# Semantic conventions for Oracle Database

LLMS index: [llms.txt](/llms.txt)

---

**Status**: [Mixed][DocumentStatus]

<!-- START doctoc -->

- [Spans](#spans)
- [Context propagation](#context-propagation)
  - [V$SESSION.ACTION](#vsessionaction)
- [Metrics](#metrics)

<!-- END doctoc -->

The Semantic Conventions for *Oracle Database* extend and override the [Database Semantic Conventions](README.md).

## Spans

<!-- semconv span.db.oracledb.client -->
<!-- NOTE: THIS TEXT IS AUTOGENERATED. DO NOT EDIT BY HAND. -->
<!-- see templates/registry/markdown/snippet.md.j2 -->
<!-- prettier-ignore-start -->

**Status:** ![Release Candidate](https://img.shields.io/badge/-rc-mediumorchid)

Spans representing calls to a Oracle SQL Database adhere to the general [Semantic Conventions for Database Client Spans](database-spans.md).

`db.system.name` MUST be set to `"oracle.db"` and SHOULD be provided **at span creation time**.

**Span kind** SHOULD be `CLIENT`.

**Span status** SHOULD follow the [Recording Errors](/docs/specs/semconv/general/recording-errors.md) document.

**Attributes:**

| Key | Stability | [Requirement Level](/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values |
| --- | --- | --- | --- | --- | --- |
| [`db.namespace`](/docs/specs/semconv/registry/attributes/db.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If available without an additional network call. | string | The unique identifier of the database associated with the connection. [1] | `ORCL1`; `ORCL2`; `ORCL3` |
| [`db.response.status_code`](/docs/specs/semconv/registry/attributes/db.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If response has ended with warning or an error. | string | [Oracle Database error number](https://docs.oracle.com/en/error-help/db/) recorded as a string. [2] | `ORA-02813`; `ORA-02613` |
| [`error.type`](/docs/specs/semconv/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation failed. | string | Describes a class of error the operation ended with. [3] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` |
| [`server.port`](/docs/specs/semconv/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` [4] | int | Server port number. [5] | `80`; `8080`; `443` |
| [`db.collection.name`](/docs/specs/semconv/registry/attributes/db.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` [6] | string | The name of a collection (table, container) within the database. [7] | `public.users`; `customers` |
| [`db.operation.batch.size`](/docs/specs/semconv/registry/attributes/db.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | int | The number of database operations included in a batch operation. [8] | `2`; `3`; `4` |
| [`db.operation.name`](/docs/specs/semconv/registry/attributes/db.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` [9] | string | The name of the operation or command being executed. [10] | `EXECUTE`; `INSERT` |
| [`db.query.summary`](/docs/specs/semconv/registry/attributes/db.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` [11] | string | Low cardinality summary of a database query. [12] | `SELECT wuser_table`; `INSERT shipping_details SELECT orders`; `get user by id` |
| [`db.query.text`](/docs/specs/semconv/registry/attributes/db.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` [13] | string | The database query being executed. [14] | `SELECT * FROM wuser_table where username = ?` |
| [`db.stored_procedure.name`](/docs/specs/semconv/registry/attributes/db.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` [15] | string | The name of a stored procedure within the database. [16] | `GetCustomer` |
| [`oracle.db.domain`](/docs/specs/semconv/registry/attributes/oracledb.md) | ![Release Candidate](https://img.shields.io/badge/-rc-mediumorchid) | `Recommended` | string | The database domain associated with the connection. [17] | `example.com`; `corp.internal`; `prod.db.local` |
| [`oracle.db.instance.name`](/docs/specs/semconv/registry/attributes/oracledb.md) | ![Release Candidate](https://img.shields.io/badge/-rc-mediumorchid) | `Recommended` | string | The instance name associated with the connection in an Oracle Real Application Clusters environment. [18] | `ORCL1`; `ORCL2`; `ORCL3` |
| [`oracle.db.name`](/docs/specs/semconv/registry/attributes/oracledb.md) | ![Release Candidate](https://img.shields.io/badge/-rc-mediumorchid) | `Recommended` | string | The database name associated with the connection. [19] | `ORCL1`; `FREE` |
| [`oracle.db.pdb`](/docs/specs/semconv/registry/attributes/oracledb.md) | ![Release Candidate](https://img.shields.io/badge/-rc-mediumorchid) | `Recommended` | string | The pluggable database (PDB) name associated with the connection. [20] | `PDB1`; `FREEPDB` |
| [`oracle.db.service`](/docs/specs/semconv/registry/attributes/oracledb.md) | ![Release Candidate](https://img.shields.io/badge/-rc-mediumorchid) | `Recommended` | string | The service name currently associated with the database connection. [21] | `order-processing-service`; `db_low.adb.oraclecloud.com`; `db_high.adb.oraclecloud.com` |
| [`server.address`](/docs/specs/semconv/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | Name of the database host. [22] | `example.com`; `10.1.2.80`; `/tmp/my.sock` |
| [`db.query.parameter.<key>`](/docs/specs/semconv/registry/attributes/db.md) | ![Development](https://img.shields.io/badge/-development-blue) | `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. [23] | `someval`; `55` |
| [`db.response.returned_rows`](/docs/specs/semconv/registry/attributes/db.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | int | Number of rows returned by the operation. [24] | `10`; `30`; `1000` |

**[1] `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.

**[2] `db.response.status_code`:** Oracle Database error codes are vendor specific error codes and don't follow [SQLSTATE](https://wikipedia.org/wiki/SQLSTATE) conventions. All Oracle Database error codes SHOULD be considered errors.

**[3] `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.

**[4] `server.port`:** If using a port other than the default port for this DBMS and if `server.address` is set.

**[5] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available.

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

**[7] `db.collection.name`:** The collection name SHOULD NOT be extracted from `db.query.text`.

**[8] `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`](https://redis.io/docs/latest/commands/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`.

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

**[10] `db.operation.name`:** The operation name SHOULD NOT be extracted from `db.query.text`.

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

**[12] `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](/docs/specs/semconv/db/database-spans.md#generating-a-summary-of-the-query)
section.

For batch operations, if the individual operations are known to have the same query summary
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.

**[13] `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`](/docs/specs/semconv/db/database-spans.md#sanitization-of-dbquerytext).
Parameterized query text SHOULD be collected by default (the query parameter values themselves are opt-in, see [`db.query.parameter.<key>`](/docs/specs/semconv/registry/attributes/db.md)).

**[14] `db.query.text`:** For sanitization see [Sanitization of `db.query.text`](/docs/specs/semconv/db/database-spans.md#sanitization-of-dbquerytext).
For batch operations, if the individual operations are known to have the same query text 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.

**[15] `db.stored_procedure.name`:** If operation applies to a specific stored procedure.

**[16] `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 are known to have the same
stored procedure name then that stored procedure name SHOULD be used.

**[17] `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.

**[18] `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`.

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

**[20] `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.

**[21] `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.

**[22] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available.

**[23] `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.

`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"`.

**[24] `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.namespace`](/docs/specs/semconv/registry/attributes/db.md)
* [`db.query.summary`](/docs/specs/semconv/registry/attributes/db.md)
* [`db.query.text`](/docs/specs/semconv/registry/attributes/db.md)
* [`oracle.db.domain`](/docs/specs/semconv/registry/attributes/oracledb.md)
* [`oracle.db.instance.name`](/docs/specs/semconv/registry/attributes/oracledb.md)
* [`oracle.db.name`](/docs/specs/semconv/registry/attributes/oracledb.md)
* [`oracle.db.pdb`](/docs/specs/semconv/registry/attributes/oracledb.md)
* [`oracle.db.service`](/docs/specs/semconv/registry/attributes/oracledb.md)
* [`server.address`](/docs/specs/semconv/registry/attributes/server.md)
* [`server.port`](/docs/specs/semconv/registry/attributes/server.md)

---

`error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.

| Value | Description | Stability |
| --- | --- | --- |
| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |

<!-- prettier-ignore-end -->
<!-- END AUTOGENERATED TEXT -->
<!-- endsemconv -->

## Context propagation

**Status**: [Development][DocumentStatus]

### V$SESSION.ACTION

Instrumentations MAY propagate context with a fixed-length, 64 byte value using [V$SESSION.ACTION](https://docs.oracle.com/en/database/oracle/oracle-database/23/refrn/V-SESSION.html) 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`](https://www.w3.org/TR/trace-context/#traceparent-header) 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 physical connection as the SQL statement.

Example:

Note that Oracle database drivers in different languages may have different implementation to update `V$SESSION.ACTION`.

For a query `SELECT * FROM songs` where `traceparent` is `00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01`:

Run the following command on the same physical connection as the SQL statement:

```sql
BEGIN
    DBMS_APPLICATION_INFO.SET_ACTION('00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01');
END;
```

Then run the query:

```sql
SELECT * FROM songs;
```

## Metrics

Oracle Database driver instrumentation SHOULD collect metrics according to the general
[Semantic Conventions for Database Client Metrics](database-metrics.md).

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

[DocumentStatus]: /docs/specs/otel/document-status
