Skip to content

OracleDB

Oracle Database (OracleDB) is foundational for many enterprise applications, and robust monitoring is essential for maintaining performance and reliability. KloudMate provides comprehensive visibility into OracleDB by delivering real-time insights through logs and metrics using the KloudMate Agent powered by OpenTelemetry.

OracleDB Monitoring in KloudMate enables centralized monitoring of Oracle Database instances running on AWS EC2, Azure Virtual Machines, or on-premise servers.

OracleDB Integration using KloudMate Agents

Section titled “OracleDB Integration using KloudMate Agents”

With OracleDB Monitoring enabled, KloudMate collects telemetry that provides visibility into:

  • Database session and system statistics
  • Tablespace utilization and data file metrics
  • Resource limits and consumption patterns
  • Performance bottlenecks and resource contention
  • Server logs and operational events

This visibility helps identify capacity issues, performance degradation, storage constraints, and availability problems.

  • Oracle Database must be installed and running
  • KloudMate Agent installed on the OracleDB host (see agent installation for Linux and Windows)

Monitoring database user requires:

GRANT SELECT ON V_$SESSION TO <username>;
GRANT SELECT ON V_$SYSSTAT TO <username>;
GRANT SELECT ON V_$RESOURCE_LIMIT TO <username>;
GRANT SELECT ON DBA_TABLESPACES TO <username>;
GRANT SELECT ON DBA_DATA_FILES TO <username>;
GRANT SELECT ON DBA_TABLESPACE_USAGE_METRICS TO <username>;

Two named receiver instances are used to logically separate SQL performance queries from session queries.

ReceiverPurpose
sqlquery/high_cpuSQL performance queries for top CPU, top elapsed time, top executions, and deadlock logs
sqlquery/sessionsActive session and wait event queries
Metric PrefixDescription
oracle.sql.*Top SQL by CPU time
oracle.el.*Top SQL by elapsed time
oracle.ex.*Top SQL by executions
oracle.sess.*Active session wait events

Step 1: Access Agents and OpenTelemetry Collector Configuration

Section titled “Step 1: Access Agents and OpenTelemetry Collector Configuration”
  • Log in to the KloudMate platform
  • Go to Settings → Agents
  • Select the agent running on the PostgreSQL host
  • Click Actions → Collector Configuration
  • YAML editor opens for configuration

image

receivers:
  oracledb:
    datasource: "oracle://otel:passwd@<host-ip-address>/XEPDB1"

Connection string format: oracle://username:password@host:port/service_name

Replace:

  • otel → monitoring username
  • passwd → monitoring user password
  • <host-ip-address> → OracleDB host IP
  • XEPDB1 → PDB/service name (adjust for your database)

Two named receiver instances are used to logically separate SQL performance queries from session queries.

sqlquery/high_cpu:
  driver: oracle
  host: <host-ip>
  database: <database-connection-string>
  port: 1521
  collection_interval: 10s
  username: sys
  password: password
  storage: file_storage
  queries:
    - sql: >
        SELECT * FROM (
            SELECT
                sql_id AS "sql_id",
                sql_text AS "sql_text",
                parsing_schema_name AS "parsing_schema_name",
                executions AS "executions",
                cpu_time/1000000 AS "cpu_seconds",
                elapsed_time/1000000 AS "elapsed_seconds",
                buffer_gets AS "buffer_gets",
                disk_reads AS "disk_reads",
                ROUND(cpu_time/DECODE(executions,0,1,executions)/1000000,2) AS "cpu_per_exec"
            FROM v$sql
            ORDER BY cpu_time DESC
        ) WHERE ROWNUM <= 10
      metrics:
        - metric_name: oracle.sql.cpuseconds
          value_column: cpu_seconds
          value_type: double
          data_type: sum
          aggregation: cumulative
          monotonic: true
          attribute_columns:
            - sql_text
            - parsing_schema_name
            - sql_id
        - metric_name: oracle.sql.elapseseconds
          value_column: elapsed_seconds
          value_type: double
          data_type: sum
          aggregation: cumulative
          monotonic: true
          attribute_columns:
            - sql_id
            - parsing_schema_name
            - sql_text
        - metric_name: oracle.sql.executions
          value_column: executions
          value_type: int
          data_type: sum
          aggregation: cumulative
          monotonic: true
          attribute_columns:
            - sql_id
            - parsing_schema_name
            - sql_text
        - metric_name: oracle.sql.buffergets
          value_column: buffer_gets
          value_type: int
          data_type: sum
          aggregation: cumulative
          monotonic: true
          attribute_columns:
            - sql_id
            - parsing_schema_name
            - sql_text
        - metric_name: oracle.sql.diskreads
          value_column: disk_reads
          value_type: int
          data_type: sum
          aggregation: cumulative
          monotonic: true
          attribute_columns:
            - sql_id
            - parsing_schema_name
            - sql_text
        - metric_name: oracle.sql.cpuexec
          value_column: cpu_per_exec
          value_type: double
          data_type: gauge
          attribute_columns:
            - sql_id
            - parsing_schema_name
            - sql_text
    - sql: >
        SELECT * FROM (
            SELECT
                sql_id AS "sql_id",
                sql_text AS "sql_text",
                parsing_schema_name AS "parsing_schema_name",
                executions AS "executions",
                elapsed_time/1000000 AS "elapsed_seconds",
                cpu_time/1000000 AS "cpu_seconds",
                buffer_gets AS "buffer_gets",
                disk_reads AS "disk_reads",
                ROUND(elapsed_time/DECODE(executions,0,1,executions)/1000000,2) AS "elapsed_per_exec"
            FROM v$sql
            ORDER BY elapsed_time DESC
        ) WHERE ROWNUM <= 10
      metrics:
        - metric_name: oracle.el.elapseseconds
          value_column: elapsed_seconds
          value_type: double
          data_type: sum
          aggregation: cumulative
          monotonic: true
          attribute_columns:
            - sql_id
            - sql_text
            - parsing_schema_name
        - metric_name: oracle.el.cpuseconds
          value_column: cpu_seconds
          value_type: double
          data_type: sum
          aggregation: cumulative
          monotonic: true
          attribute_columns:
            - sql_id
            - sql_text
            - parsing_schema_name
        - metric_name: oracle.el.executions
          value_column: executions
          value_type: int
          data_type: sum
          aggregation: cumulative
          monotonic: true
          attribute_columns:
            - sql_id
            - sql_text
            - parsing_schema_name
        - metric_name: oracle.el.buffergets
          value_column: buffer_gets
          value_type: int
          data_type: sum
          aggregation: cumulative
          monotonic: true
          attribute_columns:
            - sql_id
            - sql_text
            - parsing_schema_name
        - metric_name: oracle.el.diskreads
          value_column: disk_reads
          value_type: int
          data_type: sum
          aggregation: cumulative
          monotonic: true
          attribute_columns:
            - sql_id
            - sql_text
            - parsing_schema_name
        - metric_name: oracle.el.elapseexec
          value_column: elapsed_per_exec
          value_type: double
          data_type: gauge
          attribute_columns:
            - sql_id
            - sql_text
            - parsing_schema_name
    - sql: |
        SELECT * FROM (
            SELECT
                sql_id AS "sql_id",
                sql_text AS "sql_text",
                parsing_schema_name AS "parsing_schema_name",
                executions AS "executions",
                cpu_time/1000000 AS "cpu_seconds",
                elapsed_time/1000000 AS "elapsed_seconds"
            FROM v$sql
            WHERE executions > 0
            ORDER BY executions DESC
        ) WHERE ROWNUM <= 10
      metrics:
        - metric_name: oracle.ex.executions
          value_column: executions
          value_type: int
          data_type: sum
          aggregation: cumulative
          monotonic: true
          attribute_columns:
            - sql_id
            - sql_text
            - parsing_schema_name
        - metric_name: oracle.ex.cpuseconds
          value_column: cpu_seconds
          value_type: double
          data_type: sum
          aggregation: cumulative
          monotonic: true
          attribute_columns:
            - sql_id
            - sql_text
            - parsing_schema_name
        - metric_name: oracle.ex.elapseseconds
          value_column: elapsed_seconds
          value_type: double
          data_type: sum
          aggregation: cumulative
          monotonic: true
          attribute_columns:
            - sql_id
            - sql_text
            - parsing_schema_name
    - sql: >
        SELECT
            originating_timestamp AS "originating_timestamp",
            to_char(originating_timestamp, 'DD-MON-YYYY HH24:MI:SS') AS "time",
            message_text AS "message_text"
        FROM v$diag_alert_ext WHERE message_text LIKE '%deadlock%' ORDER BY
        originating_timestamp DESC
      tracking_column: originating_timestamp
      tracking_start_value: 2024-01-01T00:00:00Z
      logs:
        - body_column: message_text
          attribute_columns:
            - time
            - originating_timestamp
sqlquery/sessions:
  driver: oracle
  host: <host-ip>
  database: <database-connection-string>
  port: 1521
  collection_interval: 30s
  username: sys
  password: password
  storage: file_storage
  queries:
    - sql: |
        SELECT
            s.sid AS "sid",
            s.username AS "username",
            s.status AS "status",
            s.osuser AS "osuser",
            s.machine AS "machine",
            s.program AS "program",
            s.sql_id AS "sql_id",
            s.event AS "event",
            s.wait_class AS "wait_class",
            s.seconds_in_wait AS "seconds_in_wait",
            s.state AS "state"
        FROM v$session s
        WHERE s.status = 'ACTIVE'
        AND s.username IS NOT NULL
        ORDER BY s.seconds_in_wait DESC
      metrics:
        - metric_name: oracle.sess.secinwait
          value_column: seconds_in_wait
          value_type: int
          data_type: gauge
          attribute_columns:
            - sid
            - username
            - machine
            - program
            - sql_id
            - event
            - wait_class
            - state
            - status
exporters:
  otlphttp:
    endpoint: 'https://otel.kloudmate.com:4318'
    headers:
      Authorization: <API-Key>

This enables forwarding telemetry to KloudMate for analysis and visualization.

extensions:
  file_storage:
    create_directory: true

receivers:
  oracledb:
    datasource: "oracle://otel:passwd@<host-ip-address>/XEPDB1"

  sqlquery/high_cpu:
    driver: oracle
    host: <server_ip_address>
    database: XEPDB1
    port: 1521
    collection_interval: 10s
    username: sys
    password: <password>
    storage: file_storage
    queries:
      - sql: >
          SELECT * FROM (
              SELECT
                  sql_id AS "sql_id",
                  sql_text AS "sql_text",
                  parsing_schema_name AS "parsing_schema_name",
                  executions AS "executions",
                  cpu_time/1000000 AS "cpu_seconds",
                  elapsed_time/1000000 AS "elapsed_seconds",
                  buffer_gets AS "buffer_gets",
                  disk_reads AS "disk_reads",
                  ROUND(cpu_time/DECODE(executions,0,1,executions)/1000000,2) AS "cpu_per_exec"
              FROM v$sql
              ORDER BY cpu_time DESC
          ) WHERE ROWNUM <= 10
        metrics:
          - metric_name: oracle.sql.cpuseconds
            value_column: cpu_seconds
            value_type: double
            data_type: sum
            aggregation: cumulative
            monotonic: true
            attribute_columns:
              - sql_text
              - parsing_schema_name
              - sql_id
          - metric_name: oracle.sql.elapseseconds
            value_column: elapsed_seconds
            value_type: double
            data_type: sum
            aggregation: cumulative
            monotonic: true
            attribute_columns:
              - sql_id
              - parsing_schema_name
              - sql_text
          - metric_name: oracle.sql.executions
            value_column: executions
            value_type: int
            data_type: sum
            aggregation: cumulative
            monotonic: true
            attribute_columns:
              - sql_id
              - parsing_schema_name
              - sql_text
          - metric_name: oracle.sql.buffergets
            value_column: buffer_gets
            value_type: int
            data_type: sum
            aggregation: cumulative
            monotonic: true
            attribute_columns:
              - sql_id
              - parsing_schema_name
              - sql_text
          - metric_name: oracle.sql.diskreads
            value_column: disk_reads
            value_type: int
            data_type: sum
            aggregation: cumulative
            monotonic: true
            attribute_columns:
              - sql_id
              - parsing_schema_name
              - sql_text
          - metric_name: oracle.sql.cpuexec
            value_column: cpu_per_exec
            value_type: double
            data_type: gauge
            attribute_columns:
              - sql_id
              - parsing_schema_name
              - sql_text
      - sql: >
          SELECT * FROM (
              SELECT
                  sql_id AS "sql_id",
                  sql_text AS "sql_text",
                  parsing_schema_name AS "parsing_schema_name",
                  executions AS "executions",
                  elapsed_time/1000000 AS "elapsed_seconds",
                  cpu_time/1000000 AS "cpu_seconds",
                  buffer_gets AS "buffer_gets",
                  disk_reads AS "disk_reads",
                  ROUND(elapsed_time/DECODE(executions,0,1,executions)/1000000,2) AS "elapsed_per_exec"
              FROM v$sql
              ORDER BY elapsed_time DESC
          ) WHERE ROWNUM <= 10
        metrics:
          - metric_name: oracle.el.elapseseconds
            value_column: elapsed_seconds
            value_type: double
            data_type: sum
            aggregation: cumulative
            monotonic: true
            attribute_columns:
              - sql_id
              - sql_text
              - parsing_schema_name
          - metric_name: oracle.el.cpuseconds
            value_column: cpu_seconds
            value_type: double
            data_type: sum
            aggregation: cumulative
            monotonic: true
            attribute_columns:
              - sql_id
              - sql_text
              - parsing_schema_name
          - metric_name: oracle.el.executions
            value_column: executions
            value_type: int
            data_type: sum
            aggregation: cumulative
            monotonic: true
            attribute_columns:
              - sql_id
              - sql_text
              - parsing_schema_name
          - metric_name: oracle.el.buffergets
            value_column: buffer_gets
            value_type: int
            data_type: sum
            aggregation: cumulative
            monotonic: true
            attribute_columns:
              - sql_id
              - sql_text
              - parsing_schema_name
          - metric_name: oracle.el.diskreads
            value_column: disk_reads
            value_type: int
            data_type: sum
            aggregation: cumulative
            monotonic: true
            attribute_columns:
              - sql_id
              - sql_text
              - parsing_schema_name
          - metric_name: oracle.el.elapseexec
            value_column: elapsed_per_exec
            value_type: double
            data_type: gauge
            attribute_columns:
              - sql_id
              - sql_text
              - parsing_schema_name
      - sql: |
          SELECT * FROM (
              SELECT
                  sql_id AS "sql_id",
                  sql_text AS "sql_text",
                  parsing_schema_name AS "parsing_schema_name",
                  executions AS "executions",
                  cpu_time/1000000 AS "cpu_seconds",
                  elapsed_time/1000000 AS "elapsed_seconds"
              FROM v$sql
              WHERE executions > 0
              ORDER BY executions DESC
          ) WHERE ROWNUM <= 10
        metrics:
          - metric_name: oracle.ex.executions
            value_column: executions
            value_type: int
            data_type: sum
            aggregation: cumulative
            monotonic: true
            attribute_columns:
              - sql_id
              - sql_text
              - parsing_schema_name
          - metric_name: oracle.ex.cpuseconds
            value_column: cpu_seconds
            value_type: double
            data_type: sum
            aggregation: cumulative
            monotonic: true
            attribute_columns:
              - sql_id
              - sql_text
              - parsing_schema_name
          - metric_name: oracle.ex.elapseseconds
            value_column: elapsed_seconds
            value_type: double
            data_type: sum
            aggregation: cumulative
            monotonic: true
            attribute_columns:
              - sql_id
              - sql_text
              - parsing_schema_name
      - sql: >
          SELECT
              originating_timestamp AS "originating_timestamp",
              to_char(originating_timestamp, 'DD-MON-YYYY HH24:MI:SS') AS "time",
              message_text AS "message_text"
          FROM v$diag_alert_ext WHERE message_text LIKE '%deadlock%' ORDER BY
          originating_timestamp DESC
        tracking_column: originating_timestamp
        tracking_start_value: 2024-01-01T00:00:00Z
        logs:
          - body_column: message_text
            attribute_columns:
              - time
              - originating_timestamp
  sqlquery/sessions:
    driver: oracle
    host: <server_ip_address>
    database: XEPDB1
    port: 1521
    collection_interval: 30s
    username: sys
    password: password
    storage: file_storage
    queries:
      - sql: |
          SELECT
              s.sid AS "sid",
              s.username AS "username",
              s.status AS "status",
              s.osuser AS "osuser",
              s.machine AS "machine",
              s.program AS "program",
              s.sql_id AS "sql_id",
              s.event AS "event",
              s.wait_class AS "wait_class",
              s.seconds_in_wait AS "seconds_in_wait",
              s.state AS "state"
          FROM v$session s
          WHERE s.status = 'ACTIVE'
          AND s.username IS NOT NULL
          ORDER BY s.seconds_in_wait DESC
        metrics:
          - metric_name: oracle.sess.secinwait
            value_column: seconds_in_wait
            value_type: int
            data_type: gauge
            attribute_columns:
              - sid
              - username
              - machine
              - program
              - sql_id
              - event
              - wait_class
              - state
              - status

processors:
  memory_limiter:
    check_interval: 1s
    limit_mib: 1000
    spike_limit_mib: 800
  batch:
    send_batch_size: 1000
    timeout: 10s
  resource:
    attributes:
      - key: service.name
        action: insert
        from_attribute: host.name
  resourcedetection:
    detectors:
      - system
    system:
      resource_attributes:
        host.name:
          enabled: true
        host.id:
          enabled: true
        os.type:
          enabled: false

exporters:
  debug:
    verbosity: detailed
  otlphttp:
    endpoint: 'https://otel.kloudmate.com:4318'
    headers:
      Authorization: <API-Key>

service:
  pipelines:
    metrics:
      receivers: [oracledb, sqlquery/high_cpu, sqlquery/sessions]
      processors: [resourcedetection, resource, memory_limiter, batch]
      exporters: [debug, otlphttp]
    logs:
      receivers: [oracledb, sqlquery/high_cpu]
      processors: [resourcedetection, resource, memory_limiter, batch]
      exporters: [debug, otlphttp]
  extensions:
    - file_storage

Verify that metrics are flowing into KloudMate using the Explore view.

After the agent restarts:

  1. Log in to KloudMate
  2. Navigate to Explore
  3. Select OpenTelemetry → Metrics
  4. Choose a OracleDB metric and run the query

Seeing time-series data confirms that OracleDB telemetry is flowing successfully.

Access KloudMate and create dashboards to visualize OracleDB metrics and logs. Configure alerting rules for critical thresholds and unusual activity.

image

The following metrics are collected through the oracledb receiver:

Default Metrics
oracledb_cpu_time
oracledb_dml_locks_limit
oraclb_dml_locks_usage
oracledb_enqueue_deadlocks
oracledb_enqueue_locks_limit
oracledb_enqueue_locks_usage
oracledb_enqueue_resources_limit
oracledb_enqueue_resources_usage
oracledb_exchange_deadlocks
oracledb_executions
oracledb_hard_parses
Oracledb_logical_reads
oracledb_parse_calls
oracledb_pga_memory
oracledb_physical_reads
oracledb_processes_limit
oracledb_processes_usage
oracledb_sessions_limit
oracledb_sessions_usage
oracledb_tablespace_size_limit
Oracledb_tablespace_size_usage
oracledb_transactions_limit
oracledb_transactions_usage
oracledb_user_commits
oracledb_user_rollbacks
Optional Metrics
oracledb_consistent_gets
oracledb_db_block_gets

For the complete metrics list, refer to the metrics reference.