Semantic conventions for Oracle Database

Status: Mixed

The Semantic Conventions for Oracle Database extend and override the Database Semantic Conventions.

Spans

Status: Release Candidate

Spans representing calls to a Oracle SQL Database adhere to the general Semantic Conventions for Database Client Spans.

Span name SHOULD follow the general database span name convention

Span kind SHOULD be CLIENT.

Span status SHOULD follow the Recording Errors document.

Attributes:

KeyStabilityRequirement LevelValue TypeDescriptionExample Values
db.system.nameStableRequiredstringThe database management system (DBMS) product as identified by the client instrumentation. [1]oracle.db
db.namespaceStableConditionally Required If available without an additional network call.stringThe unique identifier of the database associated with the connection. [2]ORCL1; ORCL2; ORCL3
db.response.status_codeStableConditionally Required If response has ended with warning or an error.stringOracle Database error number recorded as a string. [3]ORA-02813; ORA-02613
error.typeStableConditionally Required If and only if the operation failed.stringDescribes a class of error the operation ended with. [4]timeout; java.net.UnknownHostException; server_certificate_invalid; 500
server.portStableConditionally Required [5]intServer port number. [6]80; 8080; 443
db.collection.nameStableRecommended [7]stringThe name of a collection (table, container) within the database. [8]public.users; customers
db.operation.batch.sizeStableRecommendedintThe number of database operations included in a batch operation. [9]2; 3; 4
db.operation.nameStableRecommended [10]stringThe name of the operation or command being executed. [11]EXECUTE; INSERT
db.query.summaryStableRecommended [12]stringLow cardinality summary of a database query. [13]SELECT wuser_table; INSERT shipping_details SELECT orders; get user by id
db.query.textStableRecommended [14]stringThe database query being executed. [15]SELECT * FROM wuser_table where username = ?
db.stored_procedure.nameStableRecommended [16]stringThe name of a stored procedure within the database. [17]GetCustomer
oracle.db.domainRelease CandidateRecommendedstringThe database domain associated with the connection. [18]example.com; corp.internal; prod.db.local
oracle.db.instance.nameRelease CandidateRecommendedstringThe instance name associated with the connection in an Oracle Real Application Clusters environment. [19]ORCL1; ORCL2; ORCL3
oracle.db.nameRelease CandidateRecommendedstringThe database name associated with the connection. [20]ORCL1; FREE
oracle.db.pdbRelease CandidateRecommendedstringThe pluggable database (PDB) name associated with the connection. [21]PDB1; FREEPDB
oracle.db.serviceRelease CandidateRecommendedstringThe service name currently associated with the database connection. [22]order-processing-service; db_low.adb.oraclecloud.com; db_high.adb.oraclecloud.com
server.addressStableRecommendedstringThe database address specified in the client configuration. [23]example.com; 10.1.2.80; /tmp/my.sock
db.query.parameter.<key>DevelopmentOpt-InstringA database query parameter, with <key> being the parameter name, and the attribute value being a string representation of the parameter value. [24]someval; 55
db.response.returned_rowsDevelopmentOpt-InintNumber of rows returned by the operation. [25]10; 30; 1000

[1] db.system.name: MUST be set to "oracle.db".

[2] db.namespace: Use the value of DB_UNIQUE_NAME parameter. This defines the database’s globally unique identifier and must remain unique across the enterprise.

[3] db.response.status_code: Oracle Database error codes are vendor specific error codes and don’t follow SQLSTATE conventions. All Oracle Database error codes SHOULD be considered errors.

[4] error.type: The error.type SHOULD match the db.response.status_code returned by the database or the client library, or the canonical name of exception that occurred. When using canonical exception type name, instrumentation SHOULD do the best effort to report the most relevant type. For example, if the original exception is wrapped into a generic one, the original exception SHOULD be preferred. Instrumentations SHOULD document how error.type is populated.

[5] server.port: If server.address is set and the client is configured with a single database server endpoint that uses a non-default port.

[6] server.port: server.port SHOULD reflect the database port specified in the client configuration. It SHOULD NOT be derived from the server selected for an operation.

[7] db.collection.name: If the operation is executed via a higher-level API that does not support multiple collection names.

[8] db.collection.name: The collection name SHOULD NOT be extracted from db.query.text.

[9] db.operation.batch.size: Except for empty batch requests described below, a batch operation contains two or more database operations explicitly submitted as separate operations in a single client call, protocol message, or database command.

Requests to batch APIs that contain only one operation SHOULD be modeled as single operations, not as batch operations.

A database call is not a batch operation solely because one operation accepts multiple operands, such as keys, rows, documents, points, or other data elements, including Redis MGET with multiple keys.

In batch APIs that execute the same parameterized operation with parameter sets, each parameter set represents one database operation for determining whether the request is a batch operation. Requests with only one parameter set SHOULD be modeled as single operations, not as batch operations.

db.operation.batch.size SHOULD be set to the number of operations in the batch. It SHOULD NOT be set for non-batch operations.

A request to execute a batch operation with no operations SHOULD also be treated as a batch operation, and db.operation.batch.size SHOULD be set to 0.

[10] db.operation.name: If the operation is executed via a higher-level API that does not support multiple operation names.

[11] db.operation.name: The operation name SHOULD NOT be extracted from db.query.text.

[12] db.query.summary: if available through instrumentation hooks or if the instrumentation supports generating a query summary.

[13] db.query.summary: The query summary describes a class of database queries and is useful as a grouping key, especially when analyzing telemetry for database calls involving complex queries.

Summary may be available to the instrumentation through instrumentation hooks or other means. If it is not available, instrumentations that support query parsing SHOULD generate a summary following Generating query summary section.

For batch operations, if the individual operations would all have the same db.query.summary when executed as non-batch operations, then that query summary SHOULD be used prepended by BATCH . Otherwise, db.query.summary SHOULD be BATCH or some other database system specific term if more applicable.

[14] db.query.text: Non-parameterized query text SHOULD NOT be collected by default unless there is sanitization that excludes sensitive data, e.g. by redacting all literal values present in the query text. See Sanitization of db.query.text. Parameterized query text SHOULD be collected by default (the query parameter values themselves are opt-in, see db.query.parameter.<key>).

[15] db.query.text:

For sanitization see Sanitization of db.query.text. For batch operations, if the individual operations would all have the same db.query.text when executed as non-batch operations, then that query text SHOULD be used. Otherwise, all of the individual query texts SHOULD be concatenated with separator ; or some other database system specific separator if more applicable. Parameterized query text SHOULD NOT be sanitized. Even though parameterized query text can potentially have sensitive data, by using a parameterized query the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to observability of capturing the static part of the query text by default outweighs the risk.

[16] db.stored_procedure.name: If operation applies to a specific stored procedure.

[17] db.stored_procedure.name: It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization.

For batch operations, if the individual operations would all have the same db.stored_procedure.name when executed as non-batch operations, then that stored procedure name SHOULD be used.

[18] oracle.db.domain: This attribute SHOULD be set to the value of the DB_DOMAIN initialization parameter, as exposed in v$parameter. DB_DOMAIN defines the domain portion of the global database name and SHOULD be configured when a database is, or may become, part of a distributed environment. Its value consists of one or more valid identifiers (alphanumeric ASCII characters) separated by periods.

[19] oracle.db.instance.name: There can be multiple instances associated with a single database service. It indicates the unique instance name to which the connection is currently bound. For non-RAC databases, this value defaults to the oracle.db.name.

[20] oracle.db.name: This attribute SHOULD be set to the value of the parameter DB_NAME exposed in v$parameter.

[21] oracle.db.pdb: This attribute SHOULD reflect the PDB that the session is currently connected to. If instrumentation cannot reliably obtain the active PDB name for each operation without issuing an additional query (such as SELECT SYS_CONTEXT), it is RECOMMENDED to fall back to the PDB name specified at connection establishment.

[22] oracle.db.service: The effective service name for a connection can change during its lifetime, for example after executing SQL, ALTER SESSION. If an instrumentation cannot reliably obtain the current service name for each operation without issuing an additional query (such as SELECT SYS_CONTEXT), it is RECOMMENDED to fall back to the service name originally provided at connection establishment.

[23] server.address: Instrumentation SHOULD set server.address to the database address specified in the client configuration. It SHOULD NOT derive the value from the server selected for an operation.

See Database server address for guidance and examples.

[24] db.query.parameter.<key>: If a query parameter has no name and instead is referenced only by index, then <key> SHOULD be the 0-based index.

db.query.parameter.<key> SHOULD match up with the parameterized placeholders present in db.query.text.

It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization or sanitization.

Instrumentations SHOULD NOT capture db.query.parameter.<key> by default since values may contain PII or sensitive details. Application operators are expected to enable specific keys depending on their privacy and security considerations.

db.query.parameter.<key> SHOULD NOT be captured on batch operations.

Examples:

  • For a query SELECT * FROM users where username = %s with the parameter "jdoe", the attribute db.query.parameter.0 SHOULD be set to "jdoe".

  • For a query "SELECT * FROM users WHERE username = %(userName)s; with parameter userName = "jdoe", the attribute db.query.parameter.userName SHOULD be set to "jdoe".

[25] db.response.returned_rows: The number of rows returned by the database operation as observed by the instrumentation at the time the span ends.

The following attributes can be important for making sampling decisions and SHOULD be provided at span creation time (if provided at all):

Context propagation

Status: Development

Application Context

Instrumentations MAY propagate context by using an Oracle driver mechanism that piggybacks application context to the server in the same round trip as the SQL statement. Context injection SHOULD NOT be enabled by default, but instrumentations MAY allow users to opt into it.

When using W3C Trace Context, instrumentations SHOULD inject a valid traceparent. If a valid tracestate is present, instrumentations MAY inject it together with traceparent as part of the propagated trace context value.

Instrumentations that propagate context MUST use the Oracle driver API on the same connection that executes the SQL statement. Instrumentations SHOULD use driver APIs that associate the context with statement execution without requiring an additional database call.

When the Oracle driver exposes an application context API, instrumentations SHOULD use that API to associate the trace context in the CLIENTCONTEXT namespace using the key ora$opentelem$tracectx. For example, in Java (oracle.jdbc), this is supported via JDBC Connection Tracing APIs by enabling server-side telemetry and setting clientcontext.ora$opentelem$tracectx using setClientInfo.

The value of ora$opentelem$tracectx MUST use this exact field order and syntax:

traceparent: SP traceparent-value CRLF
[tracestate: SP tracestate-value CRLF]

SP is one ASCII space byte (0x20). CRLF is the two-byte sequence carriage return (0x0D) followed by line feed (0x0A), represented as \r\n. traceparent-value is a value valid under the W3C Trace Context traceparent definition. tracestate-value is a comma-delimited list of key=value list-members valid under the W3C Trace Context tracestate definition. The bracketed tracestate line is optional as a whole. When tracestate is absent or empty, instrumentations MUST NOT emit the tracestate line. Instrumentations MUST NOT include any other fields in this value or add whitespace other than the required SP or extra line terminators.

Example payload with both fields present, shown as a quoted string so the line terminators are unambiguous:

"traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01\r\ntracestate: congo=t61rcWkgMzE\r\n"

Example payload when tracestate is absent:

"traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01\r\n"

Although Application Context is not constrained by the 64-byte limit of V$SESSION.ACTION, it is subject to a 4000-byte application-context limit (see the SYS_CONTEXT documentation). This mechanism requires support from both the database client driver and the database server version in use. If the encoded value would exceed 4000 bytes, instrumentations MUST NOT truncate it at an arbitrary byte boundary; they MAY omit the tracestate line or remove whole tracestate list-members as permitted by W3C Trace Context. End-to-end tracing works only when the database server is also explicitly configured to enable tracing.

Compared with V$SESSION.ACTION, Application Context avoids overloading a field that applications may already use.

Application Context stores trace context in the Oracle CLIENTCONTEXT namespace and does not expose the propagated values through V$SESSION.ACTION.

The values stored in CLIENTCONTEXT are session state and can persist across statement executions unless the underlying driver automatically scopes or clears their lifetime.

When the underlying driver automatically manages the lifetime of CLIENTCONTEXT, instrumentations do not need to perform additional cleanup. Otherwise, instrumentations SHOULD manage the lifecycle of ora$opentelem$tracectx to prevent stale trace context from propagating across statement executions or pooled connections—including Database Resident Connection Pooling (DRCP).

  • Post-Execution Cleanup: Instrumentations SHOULD clear or reset the ora$opentelem$tracectx entry immediately following statement execution (for example, in a finally block).

If explicit post-execution teardown is not supported by the underlying driver API, instrumentations SHOULD clear or overwrite ora$opentelem$tracectx prior to executing any subsequent statement where active context propagation is disabled or absent.

For guidance on selecting between mechanisms, legacy fallbacks, or running both concurrently, see Choice of Propagation Mechanism.

Note that Oracle database drivers in different languages expose different APIs for enabling Application Context. In .NET, users enable server-side propagation with the DatabaseOpenTelemetryTracing property on an ODP.NET connection. The following example targets ODP.NET Core, version 23.26.2 or later.

Example:

using OpenTelemetry;
using OpenTelemetry.Trace;
using Oracle.ManagedDataAccess.Client;

// 1. Setup the OpenTelemetry Tracer Provider targeting the Oracle driver source
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .AddSource("Oracle.ManagedDataAccess.Core")
    .AddOtlpExporter() // Exports this application's spans to an OTLP collector.
    .Build();

string connectString = "<your_connection_string>";

using (OracleConnection connection = new OracleConnection(connectString))
{
    using (OracleCommand command = connection.CreateCommand())
    {
        connection.Open();
        try
        {
            // 2. Opt in to client context piggybacking.
            // The driver automatically serializes the active W3C trace context
            // into CLIENTCONTEXT (ora$opentelem$tracectx) during subsequent executions.
            connection.DatabaseOpenTelemetryTracing = true;

            // 3. Execute traced queries.
            command.CommandText = "INSERT INTO MYTABLE VALUES ('val1', 100)";
            command.ExecuteNonQuery();

            command.CommandText = "SELECT COL2 FROM MYTABLE WHERE COL2 = 100";
            using (OracleDataReader reader = command.ExecuteReader())
            {
                // Consume the results
            }
        }
        finally
        {
            // 4. Disable Application Context propagation for subsequent operations.
            connection.DatabaseOpenTelemetryTracing = false;
        }

        connection.Close();
    }
}

For detailed configuration of native in-database observability capabilities, trace management, and OTLP collector endpoint setups, refer to the official Oracle Database OpenTelemetry Observability Architecture and the administrative DBMS_OBSERVABILITY Package Reference.

V$SESSION.ACTION

Instrumentations MAY propagate context with a fixed-length, 64 byte value using V$SESSION.ACTION by injecting part of span context (trace-id, span-id, trace-flags, protocol version) before executing a query. For example, when using W3C Trace Context, only a string representation of traceparent SHOULD be injected. Context injection SHOULD NOT be enabled by default, but instrumentation MAY allow users to opt into it.

Variable context parts (tracestate, baggage) SHOULD NOT be injected since V$SESSION.ACTION value length is limited to 64 bytes.

Instrumentations that propagate context MUST update V$SESSION.ACTION on the same connection that executes the SQL statement.

V$SESSION.ACTION is persistent session state and can persist across statement executions. When connection pools—including Database Resident Connection Pooling (DRCP)—reuse a database session, any leftover ACTION value may be inherited by subsequent statements.

To prevent stale trace context from propagating across statement executions or pooled connections, instrumentations SHOULD scope V$SESSION.ACTION to the execution frame of the instrumented database operation.

  • Post-Execution Cleanup: Instrumentations SHOULD restore or clear V$SESSION.ACTION immediately following statement execution (for example, in a finally block).

If explicit post-execution cleanup is not supported by the underlying driver API, instrumentations SHOULD clear or overwrite V$SESSION.ACTION before executing any subsequent statement where active context propagation is disabled or absent.

Enabling ACTION propagation gives the instrumentation ownership of the V$SESSION.ACTION value for the duration of the propagation window. Because database driver interfaces are generally write-only, instrumentations cannot inspect or preserve a pre-existing application-set ACTION value. Instrumentations SHOULD document that enabling this feature overwrites any existing ACTION metadata for the duration of propagation and that the previous value is not restored automatically.

Instrumentations MAY update V$SESSION.ACTION independently or alongside Application Context. See Choice of Propagation Mechanism for details on combining these mechanisms.

Oracle database drivers in different languages expose different APIs for updating V$SESSION.ACTION. Instrumentations SHOULD use the driver-provided API when available rather than issuing SQL or PL/SQL (for example, DBMS_APPLICATION_INFO.SET_ACTION) directly, since driver APIs can piggyback the updated ACTION value with the subsequent statement execution without requiring an additional database call.

For example, in node-oracledb, instrumentation can set the action property on the connection before executing statements:

import oracledb from "oracledb";

// The instrumentation sets the current W3C traceparent.
const traceparent =
    "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01";

const connection = await oracledb.getConnection({
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  connectString: process.env.DB_CONNECT_STRING,
});

try {
  // 1. Traceable SQL Execution (SQL 1)
  try {
    // Inject traceparent prior to executing the traced statement
    connection.action = traceparent;
    await connection.execute("SELECT * FROM songs WHERE genre = :1", ["rock"]);
  } finally {
    // Clear ACTION so subsequent statements on this connection
    // do not inherit the previous trace context.
    connection.action = null;
  }

  // 2. Untraced SQL Execution on the same connection (SQL 2)
  // E.g., internal maintenance, pool validation, or non-instrumented statement
  await connection.execute(
    "UPDATE user_sessions SET last_active = SYSDATE WHERE id = :1",
    [101]
  );
} finally {
  await connection.close();
}

Choice of Propagation Mechanism

When selecting a context propagation strategy for Oracle Database, telemetry implementations SHOULD use Application Context for native distributed tracing, and MAY combine it with V$SESSION.ACTION for out-of-band query sampling.

MechanismImplementation TypeMinimum Stack RequirementsBehavior
Application ContextNative Distributed Tracing• Client: Oracle JDBC Driver 23.26.2+ or ODP.NET (managed or core) 23.26.2+

• Server: Oracle AI Database 26ai (server version 23.26.2 or later)
Injects W3C trace context into the CLIENTCONTEXT namespace. Context piggybacks on existing database round-trips without additional network calls.
V$SESSION.ACTIONOut-of-Band Query SamplingWorks on all Oracle Database versionsExposes traceparent in V$SESSION for external polling components (e.g., oracledbreceiver) to correlate server-side execution plans, wait events, and lock graphs to client spans.

Co-existence & Recommendation Guidance

  • Native Distributed Tracing: Application Context is the preferred method of correlation when driver and database support are present.

  • Out-of-Band Diagnostic Sampling: V$SESSION.ACTION remains essential because it exposes the active traceparent to external collectors (such as oracledbreceiver), enabling them to correlate query samples, execution plans, wait events, and lock information collected from Oracle dynamic performance views with the originating client span.

  • Concurrent Usage: Instrumentations MAY enable both mechanisms simultaneously. Enabling Application Context alongside V$SESSION.ACTION creates native distributed spans while allowing out-of-band query samplers to correlate the receiver-specific db.server.query_sample event and its database diagnostics with the originating traceparent.

  • Legacy Fallback: In environments where driver or database versions do not support Application Context, V$SESSION.ACTION MAY be used independently as a passive correlation mechanism.

Metrics

Oracle Database driver instrumentation SHOULD collect metrics according to the general Semantic Conventions for Database Client Metrics.

db.system.name MUST be set to "oracle.db".