Semantic conventions for Oracle Database
Status: Mixed
The Semantic Conventions for Oracle Database extend and override the Database Semantic Conventions.
Spans
Status:
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:
| Key | Stability | Requirement Level | Value Type | Description | Example Values |
|---|---|---|---|---|---|
db.system.name | Required | string | The database management system (DBMS) product as identified by the client instrumentation. [1] | oracle.db | |
db.namespace | Conditionally Required If available without an additional network call. | string | The unique identifier of the database associated with the connection. [2] | ORCL1; ORCL2; ORCL3 | |
db.response.status_code | Conditionally Required If response has ended with warning or an error. | string | Oracle Database error number recorded as a string. [3] | ORA-02813; ORA-02613 | |
error.type | Conditionally Required If and only if the operation failed. | string | Describes a class of error the operation ended with. [4] | timeout; java.net.UnknownHostException; server_certificate_invalid; 500 | |
server.port | Conditionally Required [5] | int | Server port number. [6] | 80; 8080; 443 | |
db.collection.name | Recommended [7] | string | The name of a collection (table, container) within the database. [8] | public.users; customers | |
db.operation.batch.size | Recommended | int | The number of database operations included in a batch operation. [9] | 2; 3; 4 | |
db.operation.name | Recommended [10] | string | The name of the operation or command being executed. [11] | EXECUTE; INSERT | |
db.query.summary | Recommended [12] | string | Low cardinality summary of a database query. [13] | SELECT wuser_table; INSERT shipping_details SELECT orders; get user by id | |
db.query.text | Recommended [14] | string | The database query being executed. [15] | SELECT * FROM wuser_table where username = ? | |
db.stored_procedure.name | Recommended [16] | string | The name of a stored procedure within the database. [17] | GetCustomer | |
oracle.db.domain | Recommended | string | The database domain associated with the connection. [18] | example.com; corp.internal; prod.db.local | |
oracle.db.instance.name | Recommended | string | The instance name associated with the connection in an Oracle Real Application Clusters environment. [19] | ORCL1; ORCL2; ORCL3 | |
oracle.db.name | Recommended | string | The database name associated with the connection. [20] | ORCL1; FREE | |
oracle.db.pdb | Recommended | string | The pluggable database (PDB) name associated with the connection. [21] | PDB1; FREEPDB | |
oracle.db.service | Recommended | string | The service name currently associated with the database connection. [22] | order-processing-service; db_low.adb.oraclecloud.com; db_high.adb.oraclecloud.com | |
server.address | Recommended | string | The database address specified in the client configuration. [23] | example.com; 10.1.2.80; /tmp/my.sock | |
db.query.parameter.<key> | Opt-In | string | A 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_rows | Opt-In | int | Number 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:
This attribute may contain large values. Applications should configure the OpenTelemetry SDK attribute value limits. Instrumentations SHOULD additionally enforce an implementation-specific size limit before constructing or recording the value to avoid unbounded memory consumption.
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.
server.address MUST NOT contain credentials or other sensitive information.
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 = %swith the parameter"jdoe", the attributedb.query.parameter.0SHOULD be set to"jdoe".For a query
"SELECT * FROM users WHERE username = %(userName)s;with parameteruserName = "jdoe", the attributedb.query.parameter.userNameSHOULD 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):
db.namespacedb.query.summarydb.query.textdb.system.nameoracle.db.domainoracle.db.instance.nameoracle.db.nameoracle.db.pdboracle.db.serviceserver.addressserver.port
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$tracectxentry immediately following statement execution (for example, in afinallyblock).
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.ACTIONimmediately following statement execution (for example, in afinallyblock).
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.
| Mechanism | Implementation Type | Minimum Stack Requirements | Behavior |
|---|---|---|---|
| Application Context | Native 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.ACTION | Out-of-Band Query Sampling | Works on all Oracle Database versions | Exposes 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 Contextis the preferred method of correlation when driver and database support are present.Out-of-Band Diagnostic Sampling:
V$SESSION.ACTIONremains essential because it exposes the activetraceparentto external collectors (such asoracledbreceiver), 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 ContextalongsideV$SESSION.ACTIONcreates native distributed spans while allowing out-of-band query samplers to correlate the receiver-specificdb.server.query_sampleevent and its database diagnostics with the originatingtraceparent.Legacy Fallback: In environments where driver or database versions do not support
Application Context,V$SESSION.ACTIONMAY 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".
Feedback
Was this page helpful?
Thank you. Your feedback is appreciated!
Please let us know how we can improve this page. Your feedback is appreciated!