Skip to main content

Overview

OmniView provides real-time trace monitoring for Oracle databases through the OMNI_TRACER_API package. Once deployed, you can send trace messages from any PL/SQL code and view them instantly in your terminal.

Starting OmniView

If you have the source code:
make run
This will:
  1. Build the ODPI-C library
  2. Compile the Go application
  3. Start OmniView with auto-restart on code changes

Using Pre-built Binary

# Make executable
chmod +x omniview

# Run
./omniview

Startup Output

When OmniView starts successfully, you’ll see:
Initializing BoltDB!
[INFO] Loading configurations...
[INFO] Connecting to Oracle database at 127.0.0.1:1521/FREEPDB1
[INFO] Running permission checks...
[INFO] Deploying tracer package...
Registered Subscriber: SUB_A1B2C3D4
OmniView v1.0.0
[Tracer] Starting event listener for subscriber: SUB_A1B2C3D4
[INFO] Listening for trace messages...
Note your subscriber name (e.g., SUB_A1B2C3D4). This uniquely identifies your OmniView instance and determines which messages you’ll receive.

Sending Trace Messages

Basic Usage

The OMNI_TRACER_API package provides the Trace_Message procedure:
OMNI_TRACER_API.Trace_Message(
    message_   IN CLOB,
    log_level_ IN VARCHAR2 DEFAULT 'INFO'
);
message_
CLOB
required
The trace message content. Can be plain text, JSON, or any structured data up to 32KB.
log_level_
VARCHAR2
default:"INFO"
The severity level of the message. Common values: DEBUG, INFO, WARN, ERROR

Example: Simple Trace

BEGIN
    OMNI_TRACER_API.Trace_Message('Processing order #12345', 'INFO');
END;
/

Example: Debugging Variables

DECLARE
    v_order_id   NUMBER := 12345;
    v_customer   VARCHAR2(100) := 'Acme Corp';
    v_total      NUMBER := 1599.99;
BEGIN
    OMNI_TRACER_API.Trace_Message(
        message_   => 'Order Details: ID=' || v_order_id || 
                      ', Customer=' || v_customer || 
                      ', Total=$' || v_total,
        log_level_ => 'DEBUG'
    );
END;
/

Example: Tracing JSON

DECLARE
    v_json_msg JSON_OBJECT_T;
    v_payload  CLOB;
BEGIN
    v_json_msg := JSON_OBJECT_T();
    v_json_msg.PUT('event', 'order_created');
    v_json_msg.PUT('order_id', 12345);
    v_json_msg.PUT('timestamp', SYSTIMESTAMP);
    v_json_msg.PUT('status', 'pending');
    
    v_payload := v_json_msg.TO_CLOB();
    
    OMNI_TRACER_API.Trace_Message(v_payload, 'INFO');
END;
/

Example: Error Tracking

BEGIN
    -- Your code here
    UPDATE orders SET status = 'SHIPPED' WHERE order_id = 12345;
    
    IF SQL%ROWCOUNT = 0 THEN
        OMNI_TRACER_API.Trace_Message(
            message_   => 'Order 12345 not found for shipping update',
            log_level_ => 'WARN'
        );
    END IF;
EXCEPTION
    WHEN OTHERS THEN
        OMNI_TRACER_API.Trace_Message(
            message_   => 'ERROR: ' || SQLERRM || ' at line ' || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE,
            log_level_ => 'ERROR'
        );
        RAISE;
END;
/

Log Levels

OmniView supports standard log levels for filtering and categorization:
DEBUG
string
Detailed diagnostic information for troubleshooting. Use for variable dumps, state inspection, and development.
INFO
string
General informational messages about application flow. Default level for routine operations.
WARN
string
Warning messages for potentially problematic situations that don’t stop execution.
ERROR
string
Error conditions that prevent normal operation but allow the application to continue.
FATAL
string
Critical errors requiring immediate attention or causing application termination.

Viewing Trace Output

Output Format

Trace messages appear in real-time in the OmniView console:
[2026-03-03T14:23:45.123-05:00] [INFO] OMNI_TRACER_API: Processing order #12345
[2026-03-03T14:23:46.456-05:00] [DEBUG] ORDER_PKG: Order Details: ID=12345, Customer=Acme Corp, Total=$1599.99
[2026-03-03T14:23:47.789-05:00] [ERROR] PAYMENT_SERVICE: Payment gateway timeout after 30 seconds

Format Components

ComponentDescriptionExample
TimestampISO 8601 with milliseconds and timezone2026-03-03T14:23:45.123-05:00
Log LevelSeverity indicatorINFO, DEBUG, ERROR
Process NameSource of the trace (package, procedure, or context)OMNI_TRACER_API, ORDER_PKG
MessageThe actual trace contentProcessing order #12345
The Process Name is automatically detected from the calling context using SYS_CONTEXT('USERENV', 'MODULE'). You can set it explicitly with DBMS_APPLICATION_INFO.SET_MODULE().

Color Coding (Terminal Support)

When running in a terminal with color support, log levels are color-coded:
  • DEBUG: Gray/dimmed
  • INFO: White/default
  • WARN: Yellow
  • ERROR: Red
  • FATAL: Red/bold

Filtering and Searching

Using grep

# Filter by log level
./omniview | grep "\[ERROR\]"

# Filter by process name
./omniview | grep "ORDER_PKG"

# Search for specific text
./omniview | grep "order #12345"

Using tee for Log Files

# Save all traces to a file while viewing
./omniview | tee omniview-$(date +%Y%m%d).log

# Save only errors
./omniview | grep "\[ERROR\]" | tee errors.log

Using awk for Custom Formatting

# Extract only timestamps and messages
./omniview | awk '{print $1, substr($0, index($0,$4))}'

# Count messages by log level
./omniview | awk -F'[][]' '{print $2}' | sort | uniq -c

Common Patterns

Performance Timing

DECLARE
    v_start_time TIMESTAMP;
    v_end_time   TIMESTAMP;
    v_elapsed    INTERVAL DAY TO SECOND;
BEGIN
    v_start_time := SYSTIMESTAMP;
    
    -- Your code to measure
    FOR i IN 1..1000 LOOP
        UPDATE orders SET last_updated = SYSDATE WHERE order_id = i;
    END LOOP;
    
    v_end_time := SYSTIMESTAMP;
    v_elapsed := v_end_time - v_start_time;
    
    OMNI_TRACER_API.Trace_Message(
        message_   => 'Bulk update completed in ' || 
                      EXTRACT(SECOND FROM v_elapsed) || ' seconds',
        log_level_ => 'INFO'
    );
END;
/

Request/Response Logging

CREATE OR REPLACE PROCEDURE process_order(p_order_id IN NUMBER)
IS
    v_request  CLOB;
    v_response CLOB;
BEGIN
    -- Log incoming request
    v_request := 'REQUEST: process_order(order_id=' || p_order_id || ')';
    OMNI_TRACER_API.Trace_Message(v_request, 'INFO');
    
    -- Process order
    UPDATE orders SET status = 'PROCESSING' WHERE order_id = p_order_id;
    
    -- Log response
    v_response := 'RESPONSE: process_order success, rows_updated=' || SQL%ROWCOUNT;
    OMNI_TRACER_API.Trace_Message(v_response, 'INFO');
EXCEPTION
    WHEN OTHERS THEN
        v_response := 'RESPONSE: process_order failed - ' || SQLERRM;
        OMNI_TRACER_API.Trace_Message(v_response, 'ERROR');
        RAISE;
END;
/

Conditional Tracing

DECLARE
    v_debug_mode BOOLEAN := TRUE;  -- Control debug output
    v_order_id   NUMBER := 12345;
BEGIN
    IF v_debug_mode THEN
        OMNI_TRACER_API.Trace_Message(
            message_   => 'Debug mode enabled for order ' || v_order_id,
            log_level_ => 'DEBUG'
        );
    END IF;
    
    -- Your code
END;
/

Batch Processing Progress

DECLARE
    v_total_records NUMBER;
    v_processed     NUMBER := 0;
    v_batch_size    NUMBER := 1000;
BEGIN
    SELECT COUNT(*) INTO v_total_records FROM orders WHERE status = 'PENDING';
    
    FOR order_rec IN (SELECT * FROM orders WHERE status = 'PENDING') LOOP
        -- Process each order
        v_processed := v_processed + 1;
        
        -- Log progress every batch_size records
        IF MOD(v_processed, v_batch_size) = 0 THEN
            OMNI_TRACER_API.Trace_Message(
                message_   => 'Progress: ' || v_processed || '/' || v_total_records || 
                              ' (' || ROUND(v_processed/v_total_records*100, 2) || '%)',
                log_level_ => 'INFO'
            );
        END IF;
    END LOOP;
    
    OMNI_TRACER_API.Trace_Message('Batch processing complete: ' || v_processed || ' records', 'INFO');
END;
/

Performance Considerations

Trace messages are enqueued with IMMEDIATE visibility, meaning they commit independently of your transaction. This ensures traces are delivered even if your transaction rolls back, but be aware of the performance implications.

Best Practices

  1. Use appropriate log levels: Reserve DEBUG for development, use INFO sparingly in production
  2. Avoid tracing in tight loops: Trace at batch boundaries instead
    -- Bad: Tracing in loop
    FOR i IN 1..10000 LOOP
        OMNI_TRACER_API.Trace_Message('Processing ' || i, 'DEBUG');
    END LOOP;
    
    -- Good: Batch tracing
    FOR i IN 1..10000 LOOP
        IF MOD(i, 1000) = 0 THEN
            OMNI_TRACER_API.Trace_Message('Processed ' || i || ' records', 'INFO');
        END IF;
    END LOOP;
    
  3. Keep messages concise: While CLOB supports large messages, keep traces under 1KB for optimal performance
  4. Handle exceptions gracefully: Wrap trace calls in exception handlers to prevent traces from breaking your application
    BEGIN
        OMNI_TRACER_API.Trace_Message(v_message, 'INFO');
    EXCEPTION
        WHEN OTHERS THEN
            NULL;  -- Silently ignore trace failures
    END;
    

Troubleshooting

No messages appearing

1

Verify OmniView is running

Check that the console shows [Tracer] Starting event listener
2

Check subscriber registration

Note the subscriber name on startup (e.g., SUB_A1B2C3D4)
3

Verify database connection

Ensure your PL/SQL session connects to the same database as OmniView
4

Check queue status

Query the queue:
SELECT queue_name, enqueue_enabled, dequeue_enabled 
FROM user_queues 
WHERE queue_name = 'OMNI_TRACER_QUEUE';

Messages delayed or batched

Trace messages are delivered in near real-time with blocking dequeue. If you experience delays:
  • Check network latency between OmniView and the database
  • Verify no other process is consuming from the same subscriber
  • Check database queue configuration with DBMS_AQADM procedures

Package invalid errors

If you get ORA-04068: existing state of packages has been discarded:
  1. Restart your database session
  2. Restart OmniView (it will auto-reconnect)
  3. Recompile the package:
    ALTER PACKAGE OMNI_TRACER_API COMPILE;
    ALTER PACKAGE OMNI_TRACER_API COMPILE BODY;
    

Next Steps

Multi-Subscriber Setup

Run multiple OmniView instances for team collaboration

API Reference

Complete OMNI_TRACER_API documentation

Build docs developers (and LLMs) love