From 0e6aae3dd5366497c9f5ffa1efe5afd19c655043 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 18 Apr 2024 08:00:34 -0700 Subject: [PATCH 01/20] Replace `db.statement` with `db.query.text` in examples (#932) --- docs/database/database-spans.md | 4 ++-- docs/database/elasticsearch.md | 2 +- docs/database/mongodb.md | 2 +- docs/database/redis.md | 2 +- docs/database/sql.md | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index d43277f9d5..275ae4e5a9 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -57,7 +57,7 @@ Since SQL statements may have very high cardinality even without arguments, SQL following way, unless the statement is known to be of low cardinality: ` .`, provided that `db.operation.name` and `db.collection.name` are available. If `db.collection.name` is not available due to its semantics, the span SHOULD be named ` `. -It is not recommended to attempt any client-side parsing of `db.statement` just to get these properties, +It is not recommended to attempt any client-side parsing of `db.query.text` just to get these properties, they should only be used if the library being instrumented already provides them. When it's otherwise impossible to get any meaningful span name, `db.name` or the tech-specific database name MAY be used. @@ -178,7 +178,7 @@ This allows multiple instrumentations for the same database to be aligned and ea The value `other_sql` is intended as a fallback and MUST only be used if the DBMS is known to be SQL-compliant but the concrete product is not known to the instrumentation. If the concrete DBMS is known to the instrumentation, its specific identifier MUST be used. -Back ends could, for example, use the provided identifier to determine the appropriate SQL dialect for parsing the `db.statement`. +Back ends could, for example, use the provided identifier to determine the appropriate SQL dialect for parsing the `db.query.text`. When additional attributes are added that only apply to a specific DBMS, its identifier SHOULD be used as a namespace in the attribute key as for the attributes in the sections below. diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index 1ef894e18a..f95b4ffe80 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -100,7 +100,7 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original | `server.address` | `"elasticsearch.mydomain.com"` | | `server.port` | `9200` | | `http.request.method` | `"GET"` | -| `db.statement` | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | +| `db.query.text` | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | | `db.operation.name` | `"search"` | | `url.full` | `"https://elasticsearch.mydomain.com:9200/my-index-000001/_search?from=40&size=20"` | | `db.elasticsearch.path_parts.index` | `"my-index-000001"` | diff --git a/docs/database/mongodb.md b/docs/database/mongodb.md index 8f375ca88b..be34d3430a 100644 --- a/docs/database/mongodb.md +++ b/docs/database/mongodb.md @@ -39,7 +39,7 @@ described on this page. | `network.peer.port` | `27017` | | `network.transport` | `"tcp"` | | `db.name` | `"shopDb"` | -| `db.statement` | not set | +| `db.query.text` | not set | | `db.operation.name` | `"findAndModify"` | | `db.mongodb.collection` | `"products"` | diff --git a/docs/database/redis.md b/docs/database/redis.md index 6a8e94e057..27b9e0461d 100644 --- a/docs/database/redis.md +++ b/docs/database/redis.md @@ -41,7 +41,7 @@ Furthermore, `db.name` is not specified as there is no database name in Redis an | `network.peer.address` | `"/tmp/redis.sock"` | | `network.transport` | `"unix"` | | `db.name` | not set | -| `db.statement` | `"HMSET myhash field1 'Hello' field2 'World"` | +| `db.query.text` | `"HMSET myhash field1 'Hello' field2 'World"` | | `db.operation.name` | not set | | `db.redis.database_index` | `15` | diff --git a/docs/database/sql.md b/docs/database/sql.md index 12d24d3448..dcd4d0ba2e 100644 --- a/docs/database/sql.md +++ b/docs/database/sql.md @@ -42,7 +42,7 @@ This is an example of attributes for a MySQL database span: | `network.peer.port` | `3306` | | `network.transport` | `"tcp"` | | `db.name` | `"ShopDb"` | -| `db.statement` | `"SELECT * FROM orders WHERE order_id = 'o4711'"` | +| `db.query.text` | `"SELECT * FROM orders WHERE order_id = 'o4711'"` | | `db.operation.name` | `"SELECT"` | | `db.collection.name` | `"orders"` | From 5e822ddfe9764de99fc7937317aa1f75947a223a Mon Sep 17 00:00:00 2001 From: Alexander Wert Date: Thu, 18 Apr 2024 18:02:49 +0200 Subject: [PATCH 02/20] Fix title for the JVM docs page (#934) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- docs/runtime/jvm-metrics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/runtime/jvm-metrics.md b/docs/runtime/jvm-metrics.md index 7c658f95f8..bffa79169d 100644 --- a/docs/runtime/jvm-metrics.md +++ b/docs/runtime/jvm-metrics.md @@ -1,5 +1,5 @@ # Semantic Conventions for JVM Metrics From 54cc03eb612d9d271afd8ab9f8a6c5a9d33d407c Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 18 Apr 2024 10:56:06 -0700 Subject: [PATCH 03/20] HTTP spans restructuring: explicitly list all http client and server attributes, remove common (#931) --- .chloggen/931.yaml | 7 ++ docs/http/http-spans.md | 240 ++++++++++++++++++++++++++-------------- model/trace/http.yaml | 58 +++++----- 3 files changed, 195 insertions(+), 110 deletions(-) create mode 100644 .chloggen/931.yaml diff --git a/.chloggen/931.yaml b/.chloggen/931.yaml new file mode 100644 index 0000000000..ad215bd516 --- /dev/null +++ b/.chloggen/931.yaml @@ -0,0 +1,7 @@ +change_type: enhancement + +component: http + +note: List all HTTP client and server attributes in the corresponding table, remove common attributes from yaml and markdown. + +issues: [928] diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 6a350d5876..73a6915e58 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -16,7 +16,6 @@ and various HTTP versions like 1.1, 2 and SPDY. - [Name](#name) - [Status](#status) -- [Common Attributes](#common-attributes) - [HTTP client](#http-client) - [HTTP client span duration](#http-client-span-duration) - [HTTP request retries and redirects](#http-request-retries-and-redirects) @@ -108,25 +107,40 @@ the client or server from sending/receiving the request/response fully. When instrumentation detects such errors it MUST set span status to `Error` and MUST set the `error.type` attribute. -## Common Attributes +## HTTP client -The common attributes listed in this section apply to both HTTP clients and servers in addition to -the specific attributes listed in the [HTTP client](#http-client) and [HTTP server](#http-server) -sections below. +This span type represents an outbound HTTP request. There are two ways this can be achieved in an instrumentation: - +1. Instrumentations SHOULD create an HTTP span for each attempt to send an HTTP request over the wire. + In case the request is resent, the resend attempts MUST follow the [HTTP resend spec](#http-request-retries-and-redirects). + In this case, instrumentations SHOULD NOT (also) emit a logical encompassing HTTP client span. + +2. If for some reason it is not possible to emit a span for each send attempt (because e.g. the instrumented library does not expose hooks that would allow this), + instrumentations MAY create an HTTP span for the top-most operation of the HTTP client. + In this case, the `url.full` MUST be the absolute URL that was originally requested, before any HTTP-redirects that may happen when executing the request. + +For an HTTP client span, `SpanKind` MUST be `Client`. + + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [2] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.request.method_original`](../attributes-registry/http.md) | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | `Conditionally Required` [3] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [3] | `80`; `8080`; `443` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [4] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [5] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.method_original`](../attributes-registry/http.md) | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | `Conditionally Required` [5] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [7] | `http`; `spdy` | `Conditionally Required` [8] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.resend_count`](../attributes-registry/http.md) | int | The ordinal number of request resending attempt (for any reason, including redirects). [9] | `3` | `Recommended` if and only if request was retried. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` If `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [6] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.response.header.`](../attributes-registry/http.md) | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [7] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [8] | `tcp`; `udp` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [10] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [11] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.header.`](../attributes-registry/http.md) | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [12] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [13] | `tcp`; `udp` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`user_agent.original`](../attributes-registry/user-agent.md) | string | Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1`; `YourApp/1.0.0 grpc-java-okhttp/1.27.2` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) @@ -143,7 +157,15 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[2]:** If the request fails with an error before response status code was sent or received, +**[2]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. + +**[3]:** 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. + +**[4]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. +`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. +`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed). Sensitive content provided in `url.full` SHOULD be scrubbed when instrumentations can identify it. + +**[5]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) or a component-specific low cardinality error identifier. @@ -160,23 +182,32 @@ additional filters are applied. If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. -**[3]:** If and only if it's different than `http.request.method`. +**[6]:** If and only if it's different than `http.request.method`. + +**[7]:** The value SHOULD be normalized to lowercase. -**[4]:** The value SHOULD be normalized to lowercase. +**[8]:** If not `http` and `network.protocol.version` is set. -**[5]:** If not `http` and `network.protocol.version` is set. +**[9]:** The resend count SHOULD be updated each time an HTTP request gets resent by the client, regardless of what was the cause of the resending (e.g. redirection, authorization failure, 503 Server Unavailable, network issues, or any other). -**[6]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. +**[10]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. -**[7]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. +**[11]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. +The `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. +The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. + +**[12]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. -**[8]:** Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. Other obscure implementations are possible. +**[13]:** Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. Other obscure implementations are possible. The following attributes can be important for making sampling decisions and SHOULD be provided **at span creation time** (if provided at all): * [`http.request.method`](../attributes-registry/http.md) +* [`server.address`](../attributes-registry/server.md) +* [`server.port`](../attributes-registry/server.md) +* [`url.full`](../attributes-registry/url.md) `http.request.method` 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. @@ -209,52 +240,6 @@ The following attributes can be important for making sampling decisions and SHOU | `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -## HTTP client - -This span type represents an outbound HTTP request. There are two ways this can be achieved in an instrumentation: - -1. Instrumentations SHOULD create an HTTP span for each attempt to send an HTTP request over the wire. - In case the request is resent, the resend attempts MUST follow the [HTTP resend spec](#http-request-retries-and-redirects). - In this case, instrumentations SHOULD NOT (also) emit a logical encompassing HTTP client span. - -2. If for some reason it is not possible to emit a span for each send attempt (because e.g. the instrumented library does not expose hooks that would allow this), - instrumentations MAY create an HTTP span for the top-most operation of the HTTP client. - In this case, the `url.full` MUST be the absolute URL that was originally requested, before any HTTP-redirects that may happen when executing the request. - -For an HTTP client span, `SpanKind` MUST be `Client`. - - -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | -|---|---|---|---|---|---| -| [`server.address`](../attributes-registry/server.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [2] | `80`; `8080`; `443` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [3] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.request.resend_count`](../attributes-registry/http.md) | int | The ordinal number of request resending attempt (for any reason, including redirects). [4] | `3` | `Recommended` if and only if request was retried. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [5] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`user_agent.original`](../attributes-registry/user-agent.md) | string | Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1`; `YourApp/1.0.0 grpc-java-okhttp/1.27.2` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | - -**[1]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. - -**[2]:** 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. - -**[3]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. -`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. -`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed). Sensitive content provided in `url.full` SHOULD be scrubbed when instrumentations can identify it. - -**[4]:** The resend count SHOULD be updated each time an HTTP request gets resent by the client, regardless of what was the cause of the resending (e.g. redirection, authorization failure, 503 Server Unavailable, network issues, or any other). - -**[5]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. -The `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. -The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. - -The following attributes can be important for making sampling decisions and SHOULD be provided **at span creation time** (if provided at all): - -* [`server.address`](../attributes-registry/server.md) -* [`server.port`](../attributes-registry/server.md) -* [`url.full`](../attributes-registry/url.md) - - ### HTTP client span duration There are some minimal constraints that SHOULD be honored: @@ -335,45 +320,102 @@ This span type represents an inbound HTTP request. For an HTTP server span, `SpanKind` MUST be `Server`. - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [1] | `/search` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [2] | `http`; `https` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | `Conditionally Required` If and only if it's available | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [4] | `80`; `8080`; `443` | `Conditionally Required` If `server.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [5] | `q=OpenTelemetry` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`client.address`](../attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `83.164.160.102` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [2] | `/search` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [3] | `http`; `https` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [4] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.method_original`](../attributes-registry/http.md) | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | `Conditionally Required` [5] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [6] | `/users/:userID?`; `{controller}/{action}/{id?}` | `Conditionally Required` If and only if it's available | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [7] | `http`; `spdy` | `Conditionally Required` [8] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [9] | `80`; `8080`; `443` | `Conditionally Required` If `server.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [10] | `q=OpenTelemetry` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`client.address`](../attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [11] | `83.164.160.102` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` If `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [12] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [13] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`user_agent.original`](../attributes-registry/user-agent.md) | string | Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1`; `YourApp/1.0.0 grpc-java-okhttp/1.27.2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`client.port`](../attributes-registry/client.md) | int | The port of whichever client was captured in `client.address`. [8] | `65123` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [9] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`client.port`](../attributes-registry/client.md) | int | The port of whichever client was captured in `client.address`. [14] | `65123` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [15] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.header.`](../attributes-registry/http.md) | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [16] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.local.address`](../attributes-registry/network.md) | string | Local socket address. Useful in case of a multi-IP host. | `10.1.2.80`; `/tmp/my.sock` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.local.port`](../attributes-registry/network.md) | int | Local socket port. Useful in case of a multi-port host. | `65123` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [17] | `tcp`; `udp` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** Sensitive content provided in `url.path` SHOULD be scrubbed when instrumentations can identify it. +**[1]:** HTTP request method value SHOULD be "known" to the instrumentation. +By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) +and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). -**[2]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. + +If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override +the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named +OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods +(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). + +HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. +Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. +Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. + +**[2]:** Sensitive content provided in `url.path` SHOULD be scrubbed when instrumentations can identify it. + +**[3]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. + +**[4]:** If the request fails with an error before response status code was sent or received, +`error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) +or a component-specific low cardinality error identifier. + +If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), +`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error identifier. + +The `error.type` value SHOULD be predictable and SHOULD have low cardinality. +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low, but +telemetry consumers that aggregate data from multiple instrumentation libraries and applications +should be prepared for `error.type` to have high cardinality at query time, when no +additional filters are applied. -**[3]:** MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. +If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. + +**[5]:** If and only if it's different than `http.request.method`. + +**[6]:** MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. SHOULD include the [application root](/docs/http/http-spans.md#http-server-definitions) if there is one. -**[4]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +**[7]:** The value SHOULD be normalized to lowercase. + +**[8]:** If not `http` and `network.protocol.version` is set. -**[5]:** Sensitive content provided in `url.query` SHOULD be scrubbed when instrumentations can identify it. +**[9]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). -**[6]:** The IP address of the original client behind all proxies, if known (e.g. from [Forwarded#for](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#for), [X-Forwarded-For](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. +**[10]:** Sensitive content provided in `url.query` SHOULD be scrubbed when instrumentations can identify it. -**[7]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +**[11]:** The IP address of the original client behind all proxies, if known (e.g. from [Forwarded#for](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#for), [X-Forwarded-For](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. -**[8]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. +**[12]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. -**[9]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. +**[13]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). + +**[14]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. + +**[15]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. The `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. +**[16]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. +Users MAY explicitly configure instrumentations to capture them even though it is not recommended. +The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. + +**[17]:** Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. Other obscure implementations are possible. + The following attributes can be important for making sampling decisions and SHOULD be provided **at span creation time** (if provided at all): +* [`http.request.method`](../attributes-registry/http.md) * [`url.path`](../attributes-registry/url.md) * [`url.scheme`](../attributes-registry/url.md) * [`server.port`](../attributes-registry/server.md) @@ -382,6 +424,36 @@ The following attributes can be important for making sampling decisions and SHOU * [`server.address`](../attributes-registry/server.md) * [`user_agent.original`](../attributes-registry/user-agent.md) * [`http.request.header.`](../attributes-registry/http.md) + +`http.request.method` 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 | +|---|---|---| +| `CONNECT` | CONNECT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `DELETE` | DELETE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `GET` | GET method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `HEAD` | HEAD method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `OPTIONS` | OPTIONS method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PATCH` | PATCH method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `POST` | POST method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PUT` | PUT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `TRACE` | TRACE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`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) | + +`network.transport` 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 | +|---|---|---| +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `http.route` MUST be provided at span creation time if and only if it's already available. If it becomes available after span starts, instrumentation MUST populate it anytime before span ends. diff --git a/model/trace/http.yaml b/model/trace/http.yaml index 1e5667ad4f..b463f38497 100644 --- a/model/trace/http.yaml +++ b/model/trace/http.yaml @@ -1,41 +1,22 @@ groups: - - id: trace.http.common - extends: attributes.http.common - type: attribute_group - brief: 'This document defines semantic conventions for HTTP client and server Spans.' - note: > - These conventions can be used for http and https schemes - and various HTTP versions like 1.1, 2 and SPDY. - attributes: - - ref: http.request.method_original - requirement_level: - conditionally_required: If and only if it's different than `http.request.method`. - - ref: http.response.header - requirement_level: opt_in - - ref: http.request.method - sampling_relevant: true - requirement_level: required - - ref: network.peer.address - - ref: network.peer.port - requirement_level: - recommended: If `network.peer.address` is set. - - ref: network.transport - requirement_level: opt_in - note: > - Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. - Other obscure implementations are possible. - - id: trace.http.client type: span extends: attributes.http.client span_kind: client brief: 'Semantic Convention for HTTP Client' attributes: + - ref: http.request.method + sampling_relevant: true + - ref: http.request.method_original + requirement_level: + conditionally_required: If and only if it's different than `http.request.method`. - ref: http.request.resend_count requirement_level: recommended: if and only if request was retried. - ref: http.request.header requirement_level: opt_in + - ref: http.response.header + requirement_level: opt_in - ref: server.address sampling_relevant: true - ref: server.port @@ -46,6 +27,15 @@ groups: - ref: user_agent.original requirement_level: opt_in - ref: url.scheme + - ref: network.peer.address + - ref: network.peer.port + requirement_level: + recommended: If `network.peer.address` is set. + - ref: network.transport + requirement_level: opt_in + note: > + Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. + Other obscure implementations are possible. - id: trace.http.server type: span @@ -53,10 +43,17 @@ groups: span_kind: server brief: 'Semantic Convention for HTTP Server' attributes: + - ref: http.request.method + sampling_relevant: true + - ref: http.request.method_original + requirement_level: + conditionally_required: If and only if it's different than `http.request.method`. - ref: http.route - ref: http.request.header sampling_relevant: true requirement_level: opt_in + - ref: http.response.header + requirement_level: opt_in - ref: server.address sampling_relevant: true - ref: server.port @@ -89,3 +86,12 @@ groups: sampling_relevant: true - ref: user_agent.original sampling_relevant: true + - ref: network.peer.address + - ref: network.peer.port + requirement_level: + recommended: If `network.peer.address` is set. + - ref: network.transport + requirement_level: opt_in + note: > + Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. + Other obscure implementations are possible. From bee13d413c06f8c1ec7ea3e186e9f2fbff0fc0a5 Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Thu, 18 Apr 2024 23:26:30 +0200 Subject: [PATCH 04/20] [BREAKING] move attributes from db metrics to the registry (#909) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Co-authored-by: Trask Stalnaker Co-authored-by: Liudmila Molkova --- .chloggen/db_metrics.yaml | 22 +++++++++++ docs/attributes-registry/db.md | 25 ++++++++++++ docs/database/database-metrics.md | 22 +++++------ model/metrics/database-metrics.yaml | 59 ++++++++++------------------- model/registry/db.yaml | 24 ++++++++++++ model/registry/deprecated/db.yaml | 26 +++++++++++++ schema-next.yaml | 21 ++++++++++ 7 files changed, 149 insertions(+), 50 deletions(-) create mode 100755 .chloggen/db_metrics.yaml diff --git a/.chloggen/db_metrics.yaml b/.chloggen/db_metrics.yaml new file mode 100755 index 0000000000..0e8468e967 --- /dev/null +++ b/.chloggen/db_metrics.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: breaking + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: db + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Rename `pool.name` to `db.client.connections.pool.name` and `state` to `db.client.connections.state`. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [909] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/attributes-registry/db.md b/docs/attributes-registry/db.md index 45c73f0997..5940f91d71 100644 --- a/docs/attributes-registry/db.md +++ b/docs/attributes-registry/db.md @@ -12,6 +12,7 @@ - [MSSQL Attributes](#mssql-attributes) - [Redis Attributes](#redis-attributes) - [Deprecated DB Attributes](#deprecated-db-attributes) +- [Deprecated DB Metrics Attributes](#deprecated-db-metrics-attributes) @@ -20,6 +21,8 @@ | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| +| `db.client.connections.pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.client.connections.state` | string | The state of a connection in the pool | `idle` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.collection.name` | string | The name of a collection (table, container) within the database. [1] | `public.users`; `customers` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.instance.id` | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.name` | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [2] | `customers`; `main` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -35,6 +38,13 @@ **[3]:** Query parameters should only be captured when `db.query.text` is parameterized with placeholders. If a parameter has no name and instead is referenced only by index, then `` SHOULD be the 0-based index. +`db.client.connections.state` 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 | +|---|---|---| +| `idle` | idle | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `used` | used | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + `db.system` 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 | @@ -208,3 +218,18 @@ If a parameter has no name and instead is referenced only by index, then `` | `db.statement` | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.query.text`. | | `db.user` | string | Deprecated, no replacement at this time. | `readonly_user`; `reporting_user` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
No replacement at this time. | + +## Deprecated DB Metrics Attributes + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `pool.name` | string | Deprecated, use `db.client.connections.pool.name` instead. | `myDataSource` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.client.connections.pool.name`. | +| `state` | string | Deprecated, use `db.client.connections.state` instead. | `idle` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.client.connections.state`. | + +`state` 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 | +|---|---|---| +| `idle` | idle | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `used` | used | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + \ No newline at end of file diff --git a/docs/database/database-metrics.md b/docs/database/database-metrics.md index cff733d139..d779bc7a6d 100644 --- a/docs/database/database-metrics.md +++ b/docs/database/database-metrics.md @@ -52,10 +52,10 @@ This metric is [required][MetricRequired]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `state` | string | The state of a connection in the pool | `idle` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.state`](../attributes-registry/db.md) | string | The state of a connection in the pool | `idle` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`state` MUST be one of the following: +`db.client.connections.state` 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 | |---|---|---| @@ -75,7 +75,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.idle.min` @@ -91,7 +91,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.max` @@ -107,7 +107,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.pending_requests` @@ -123,7 +123,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.timeouts` @@ -139,7 +139,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.create_time` @@ -155,7 +155,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.wait_time` @@ -171,7 +171,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.use_time` @@ -187,7 +187,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/model/metrics/database-metrics.yaml b/model/metrics/database-metrics.yaml index d172d9e4b6..cce9257e4f 100644 --- a/model/metrics/database-metrics.yaml +++ b/model/metrics/database-metrics.yaml @@ -1,33 +1,4 @@ groups: - - id: attributes.db - type: attribute_group - brief: Describes Database attributes - attributes: - - id: state - stability: experimental - type: - allow_custom_values: false - members: - - id: idle - value: 'idle' - stability: experimental - - id: used - value: 'used' - stability: experimental - requirement_level: required - brief: "The state of a connection in the pool" - examples: ["idle"] - - id: pool.name - type: string - stability: experimental - requirement_level: required - brief: > - The name of the connection pool; unique within the instrumented application. - In case the connection pool implementation doesn't provide a name, - instrumentation should use a combination of `server.address` and `server.port` attributes - formatted as `server.address:server.port`. - examples: ["myDataSource"] - - id: metric.db.client.connections.usage type: metric metric_name: db.client.connections.usage @@ -36,8 +7,10 @@ groups: instrument: updowncounter unit: "{connection}" attributes: - - ref: state - - ref: pool.name + - ref: db.client.connections.state + requirement_level: required + - ref: db.client.connections.pool.name + requirement_level: required - id: metric.db.client.connections.idle.max type: metric @@ -47,7 +20,8 @@ groups: instrument: updowncounter unit: "{connection}" attributes: - - ref: pool.name + - ref: db.client.connections.pool.name + requirement_level: required - id: metric.db.client.connections.idle.min type: metric @@ -57,7 +31,8 @@ groups: instrument: updowncounter unit: "{connection}" attributes: - - ref: pool.name + - ref: db.client.connections.pool.name + requirement_level: required - id: metric.db.client.connections.max type: metric @@ -67,7 +42,8 @@ groups: instrument: updowncounter unit: "{connection}" attributes: - - ref: pool.name + - ref: db.client.connections.pool.name + requirement_level: required - id: metric.db.client.connections.pending_requests type: metric @@ -77,7 +53,8 @@ groups: instrument: updowncounter unit: "{request}" attributes: - - ref: pool.name + - ref: db.client.connections.pool.name + requirement_level: required - id: metric.db.client.connections.timeouts type: metric @@ -87,7 +64,8 @@ groups: instrument: counter unit: "{timeout}" attributes: - - ref: pool.name + - ref: db.client.connections.pool.name + requirement_level: required - id: metric.db.client.connections.create_time type: metric @@ -97,7 +75,8 @@ groups: instrument: histogram unit: "ms" attributes: - - ref: pool.name + - ref: db.client.connections.pool.name + requirement_level: required - id: metric.db.client.connections.wait_time type: metric @@ -107,7 +86,8 @@ groups: instrument: histogram unit: "ms" attributes: - - ref: pool.name + - ref: db.client.connections.pool.name + requirement_level: required - id: metric.db.client.connections.use_time type: metric @@ -117,4 +97,5 @@ groups: instrument: histogram unit: "ms" attributes: - - ref: pool.name + - ref: db.client.connections.pool.name + requirement_level: required diff --git a/model/registry/db.yaml b/model/registry/db.yaml index cce3c33972..25532ab6a4 100644 --- a/model/registry/db.yaml +++ b/model/registry/db.yaml @@ -487,3 +487,27 @@ groups: This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. examples: 'mysql-e26b99z.example.com' + - id: client.connections.state + tag: db-generic + stability: experimental + type: + allow_custom_values: true + members: + - id: idle + value: 'idle' + stability: experimental + - id: used + value: 'used' + stability: experimental + brief: "The state of a connection in the pool" + examples: ["idle"] + - id: client.connections.pool.name + tag: db-generic + type: string + stability: experimental + brief: > + The name of the connection pool; unique within the instrumented application. + In case the connection pool implementation doesn't provide a name, + instrumentation should use a combination of `server.address` and `server.port` attributes + formatted as `server.address:server.port`. + examples: ["myDataSource"] diff --git a/model/registry/deprecated/db.yaml b/model/registry/deprecated/db.yaml index a5a6390b1b..de58225c67 100644 --- a/model/registry/deprecated/db.yaml +++ b/model/registry/deprecated/db.yaml @@ -66,3 +66,29 @@ groups: brief: 'Deprecated, use `db.collection.name` instead.' deprecated: "Replaced by `db.collection.name`." examples: 'mytable' + + - id: registry.db.metrics.deprecated + type: attribute_group + brief: > + "Describes deprecated db metrics attributes." + attributes: + - id: state + stability: experimental + type: + allow_custom_values: true + members: + - id: idle + value: 'idle' + stability: experimental + - id: used + value: 'used' + stability: experimental + brief: "Deprecated, use `db.client.connections.state` instead." + deprecated: "Replaced by `db.client.connections.state`." + examples: ["idle"] + - id: pool.name + type: string + stability: experimental + brief: "Deprecated, use `db.client.connections.pool.name` instead." + deprecated: "Replaced by `db.client.connections.pool.name`." + examples: ["myDataSource"] diff --git a/schema-next.yaml b/schema-next.yaml index 430901253a..5fc05edea2 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -2,6 +2,27 @@ file_format: 1.1.0 schema_url: https://opentelemetry.io/schemas/next versions: next: + metrics: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/909 + - rename_attributes: + attribute_map: + state: db.client.connections.state + apply_to_metrics: + - db.client.connections.usage + - rename_attributes: + attribute_map: + pool.name: db.client.connections.pool.name + apply_to_metrics: + - db.client.connections.usage + - db.client.connections.idle.max + - db.client.connections.idle.min + - db.client.connections.max + - db.client.connections.pending_requests + - db.client.connections.timeouts + - db.client.connections.create_time + - db.client.connections.wait_time + - db.client.connections.use_time 1.25.0: spans: From 1b6bde0287f7534a13d8828370e69cb2e1415489 Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Thu, 18 Apr 2024 16:58:15 -0700 Subject: [PATCH 05/20] Move common DB attributes (#910) Co-authored-by: Liudmila Molkova --- .chloggen/910.yaml | 4 +++ model/db-common.yaml | 41 ++++++++++++++++++++++++++++++ model/trace/database.yaml | 53 +++++++-------------------------------- 3 files changed, 54 insertions(+), 44 deletions(-) create mode 100644 .chloggen/910.yaml create mode 100644 model/db-common.yaml diff --git a/.chloggen/910.yaml b/.chloggen/910.yaml new file mode 100644 index 0000000000..fbfbe2cd73 --- /dev/null +++ b/.chloggen/910.yaml @@ -0,0 +1,4 @@ +change_type: enhancement +component: db +note: Reorganize DB conventions to be shared across span and metric conventions. +issues: [ 910 ] diff --git a/model/db-common.yaml b/model/db-common.yaml new file mode 100644 index 0000000000..fdefe67883 --- /dev/null +++ b/model/db-common.yaml @@ -0,0 +1,41 @@ +groups: + - id: attributes.db.client + type: attribute_group + brief: 'Database Client attributes' + attributes: + - ref: db.name + requirement_level: + conditionally_required: If applicable. + - ref: db.collection.name + requirement_level: + conditionally_required: > + If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture + `db.collection.name`, then it SHOULD be the first collection name found in the query. + - ref: db.instance.id + requirement_level: + recommended: If different from the `server.address` + - ref: db.operation.name + requirement_level: + conditionally_required: > + If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture + `db.operation.name`, then it SHOULD be the first operation name found in the query. + - ref: db.system + requirement_level: required + - ref: network.peer.address + brief: Peer address of the database node where the operation was performed. + requirement_level: + recommended: If applicable for this database system. + note: > + Semantic conventions for individual database systems SHOULD document whether `network.peer.*` attributes are applicable. + Network peer address and port are useful when the application interacts with individual database nodes directly. + + If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. + - ref: network.peer.port + requirement_level: + recommended: if and only if `network.peer.address` is set. + - ref: server.address + brief: > + Name of the database host. + - ref: server.port + requirement_level: + conditionally_required: If using a port other than the default port for this DBMS and if `server.address` is set. diff --git a/model/trace/database.yaml b/model/trace/database.yaml index b4ed7d0da6..d42d1c6b68 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -1,55 +1,20 @@ groups: - - id: db.common.attributes + - id: trace.db.common + extends: attributes.db.client type: attribute_group brief: This group defines the attributes used to perform database client calls. attributes: - - ref: db.system - requirement_level: required - - ref: db.name - requirement_level: - conditionally_required: If applicable. - ref: db.query.text requirement_level: recommended: > Should be collected by default only if there is sanitization that excludes sensitive information. - ref: db.query.parameter requirement_level: opt_in - - ref: db.operation.name - requirement_level: - conditionally_required: > - If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture - `db.operation.name`, then it SHOULD be the first operation name found in the query. - - ref: server.address - brief: > - Name of the database host. - - ref: server.port - requirement_level: - conditionally_required: If using a port other than the default port for this DBMS and if `server.address` is set. - - ref: db.instance.id - requirement_level: - recommended: If different from the `server.address` - - ref: db.collection.name - requirement_level: - conditionally_required: > - If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture - `db.collection.name`, then it SHOULD be the first collection name found in the query. - - ref: network.peer.address - brief: Peer address of the database node where the operation was performed. - requirement_level: - recommended: If applicable for this database system. - note: > - Semantic conventions for individual database systems SHOULD document whether `network.peer.*` attributes are applicable. - Network peer address and port are useful when the application interacts with individual database nodes directly. - - If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. - - ref: network.peer.port - requirement_level: - recommended: if and only if `network.peer.address` is set. - id: db.tech_specific.network.attributes type: attribute_group brief: This group documents attributes that describe database call along with network information. - extends: db.common.attributes + extends: trace.db.common attributes: - ref: network.peer.address requirement_level: @@ -64,7 +29,7 @@ groups: type: span brief: This span defines the attributes used to perform database client calls. span_kind: client - extends: db.common.attributes + extends: trace.db.common - id: db.mssql type: span @@ -105,7 +70,7 @@ groups: - id: db.hbase type: span - extends: db.common.attributes + extends: trace.db.common brief: > Attributes for HBase attributes: @@ -118,7 +83,7 @@ groups: - id: db.couchdb type: span - extends: db.common.attributes + extends: trace.db.common brief: > Attributes for CouchDB attributes: @@ -155,7 +120,7 @@ groups: - id: db.mongodb type: span - extends: db.common.attributes + extends: trace.db.common brief: > Attributes for MongoDB attributes: @@ -219,7 +184,7 @@ groups: - id: db.sql type: span - extends: db.common.attributes + extends: trace.db.common brief: > Attributes for SQL databases attributes: @@ -236,7 +201,7 @@ groups: - id: db.cosmosdb type: span - extends: db.common.attributes + extends: trace.db.common prefix: db.cosmosdb brief: > Attributes for Cosmos DB. From b77c881ad68dca7bb7af2c97899a0ef64357c47c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerhard=20St=C3=B6bich?= Date: Fri, 19 Apr 2024 12:04:14 +0200 Subject: [PATCH 06/20] [chore] adapt lambda examples to current conventions (#938) --- docs/faas/aws-lambda.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/faas/aws-lambda.md b/docs/faas/aws-lambda.md index 273eb71eeb..0719970912 100644 --- a/docs/faas/aws-lambda.md +++ b/docs/faas/aws-lambda.md @@ -158,8 +158,8 @@ added as a link to the span. This means the span may have as many links as messa See [compatibility](../../supplementary-guidelines/compatibility/aws.md#context-propagation) for more info. - [`faas.trigger`][faas] MUST be set to `pubsub`. -- [`messaging.operation`](/docs/messaging/messaging-spans.md) MUST be set to `process`. -- [`messaging.system`](/docs/messaging/messaging-spans.md) MUST be set to `AmazonSQS`. +- [`messaging.operation.type`](/docs/messaging/messaging-spans.md) MUST be set to `process`. +- [`messaging.system`](/docs/messaging/messaging-spans.md) MUST be set to `aws_sqs`. ### SQS Message @@ -171,8 +171,8 @@ added as a link to the span. See [compatibility](../../supplementary-guidelines/compatibility/aws.md#context-propagation) for more info. - [`faas.trigger`][faas] MUST be set to `pubsub`. -- [`messaging.operation`](/docs/messaging/messaging-spans.md#messaging-attributes) MUST be set to `process`. -- [`messaging.system`](/docs/messaging/messaging-spans.md#messaging-attributes) MUST be set to `AmazonSQS`. +- [`messaging.operation.type`](/docs/messaging/messaging-spans.md#messaging-attributes) MUST be set to `process`. +- [`messaging.system`](/docs/messaging/messaging-spans.md#messaging-attributes) MUST be set to `aws_sqs`. Other [Messaging attributes](/docs/messaging/messaging-spans.md#messaging-attributes) SHOULD be set based on the available information in the SQS message event. @@ -251,9 +251,9 @@ Function F: | Span ProcBatch | | Links | | | | Span Prod1 | Span Prod2 | | SpanKind | `PRODUCER` | `PRODUCER` | `CONSUMER` | `CONSUMER` | `CONSUMER` | | Status | `Ok` | `Ok` | `Ok` | `Ok` | `Ok` | -| `messaging.system` | `AmazonSQS` | `AmazonSQS` | `AmazonSQS` | `AmazonSQS` | `AmazonSQS` | +| `messaging.system` | `aws_sqs` | `aws_sqs` | `aws_sqs` | `aws_sqs` | `aws_sqs` | | `messaging.destination.name` | `Q` | `Q` | `Q` | `Q` | `Q` | -| `messaging.operation` | | | `process` | `process` | `process` | +| `messaging.operation.type` | | | `process` | `process` | `process` | | `messaging.message.id` | | | | `"a1"` | `"a2"` | Note that if Span Prod1 and Span Prod2 were sent to different queues, Span ProcBatch would not have From c8a1337e7a45ddb01572ef6aea777174af837e96 Mon Sep 17 00:00:00 2001 From: Phillip Carter Date: Mon, 22 Apr 2024 02:14:04 -0700 Subject: [PATCH 07/20] Fix the linkTitle for Azure Messaging (#944) --- docs/messaging/azure-messaging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/messaging/azure-messaging.md b/docs/messaging/azure-messaging.md index 8028640677..3deba05a1c 100644 --- a/docs/messaging/azure-messaging.md +++ b/docs/messaging/azure-messaging.md @@ -1,5 +1,5 @@ # Semantic Conventions for Azure Messaging systems From 7f6876de7d0c5fcafaab812b00a31d56b524be77 Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Mon, 22 Apr 2024 13:40:25 +0200 Subject: [PATCH 08/20] [chore] move log to registry (#908) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 + docs/attributes-registry/README.md | 1 + docs/attributes-registry/log.md | 52 +++++++++++++++ docs/general/logs.md | 16 ++--- model/logs/general.yaml | 14 +--- model/logs/media.yaml | 47 ++------------ model/registry/log.yaml | 72 +++++++++++++++++++++ 9 files changed, 143 insertions(+), 62 deletions(-) create mode 100644 docs/attributes-registry/log.md create mode 100644 model/registry/log.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index bb5ede00e1..c78207d5fe 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -48,6 +48,7 @@ body: - area:http - area:ios - area:k8s + - area:log - area:messaging - area:network - area:oci diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index 53520602e3..355217d372 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -41,6 +41,7 @@ body: - area:http - area:ios - area:k8s + - area:log - area:messaging - area:network - area:oci diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index 0e79351f21..c4dd0faedb 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -50,6 +50,7 @@ body: - area:http - area:ios - area:k8s + - area:log - area:messaging - area:network - area:oci diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 4669206415..a0f1684213 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -55,6 +55,7 @@ Currently, the following namespaces exist: * [HTTP](http.md) * [iOS](ios.md) * [K8s](k8s.md) +* [Log](log.md) * [Network](network.md) * [OCI](oci.md) * [OpenTelemetry](otel.md) diff --git a/docs/attributes-registry/log.md b/docs/attributes-registry/log.md new file mode 100644 index 0000000000..89c5145c1b --- /dev/null +++ b/docs/attributes-registry/log.md @@ -0,0 +1,52 @@ + + +# Log + + + +- [Log Attributes](#log-attributes) + - [Generic log attributes](#generic-log-attributes) + - [File log attributes](#file-log-attributes) + - [Record log attributes](#record-log-attributes) + + + +## Log Attributes + +### Generic log attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `log.iostream` | string | The stream associated with the log. See below for a list of well-known values. | `stdout` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`log.iostream` 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 | +|---|---|---| +| `stdout` | Logs from stdout stream | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `stderr` | Events from stderr stream | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +### File log attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `log.file.name` | string | The basename of the file. | `audit.log` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `log.file.name_resolved` | string | The basename of the file, with symlinks resolved. | `uuid.log` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `log.file.path` | string | The full path to the file. | `/var/log/mysql/audit.log` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `log.file.path_resolved` | string | The full path to the file, with symlinks resolved. | `/var/lib/docker/uuid.log` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +### Record log attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `log.record.uid` | string | A unique identifier for the Log Record. [1] | `01ARZ3NDEKTSV4RRFFQ69G5FAV` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** If an id is provided, other log records with the same id will be considered duplicates and can be removed safely. This means, that two distinguishable log records MUST have different values. +The id MAY be an [Universally Unique Lexicographically Sortable Identifier (ULID)](https://github.com/ulid/spec), but other identifiers (e.g. UUID) may be used as needed. + \ No newline at end of file diff --git a/docs/general/logs.md b/docs/general/logs.md index 748c2e61fc..cd443a3b2d 100644 --- a/docs/general/logs.md +++ b/docs/general/logs.md @@ -38,7 +38,7 @@ These attributes may be used for identifying a Log Record. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `log.record.uid` | string | A unique identifier for the Log Record. [1] | `01ARZ3NDEKTSV4RRFFQ69G5FAV` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`log.record.uid`](../attributes-registry/log.md) | string | A unique identifier for the Log Record. [1] | `01ARZ3NDEKTSV4RRFFQ69G5FAV` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If an id is provided, other log records with the same id will be considered duplicates and can be removed safely. This means, that two distinguishable log records MUST have different values. The id MAY be an [Universally Unique Lexicographically Sortable Identifier (ULID)](https://github.com/ulid/spec), but other identifiers (e.g. UUID) may be used as needed. @@ -59,22 +59,22 @@ As such, these should be recorded as Log Record attributes when applicable. They | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `log.file.name` | string | The basename of the file. | `audit.log` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `log.file.name_resolved` | string | The basename of the file, with symlinks resolved. | `uuid.log` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `log.file.path` | string | The full path to the file. | `/var/log/mysql/audit.log` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `log.file.path_resolved` | string | The full path to the file, with symlinks resolved. | `/var/lib/docker/uuid.log` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`log.file.name`](../attributes-registry/log.md) | string | The basename of the file. | `audit.log` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`log.file.name_resolved`](../attributes-registry/log.md) | string | The basename of the file, with symlinks resolved. | `uuid.log` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`log.file.path`](../attributes-registry/log.md) | string | The full path to the file. | `/var/log/mysql/audit.log` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`log.file.path_resolved`](../attributes-registry/log.md) | string | The full path to the file, with symlinks resolved. | `/var/lib/docker/uuid.log` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### I/O Stream **Description:** The I/O stream to which the log was emitted. - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `log.iostream` | string | The stream associated with the log. See below for a list of well-known values. | `stdout` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`log.iostream`](../attributes-registry/log.md) | string | The stream associated with the log. See below for a list of well-known values. | `stdout` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`log.iostream` MUST be one of the following: +`log.iostream` 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 | |---|---|---| diff --git a/model/logs/general.yaml b/model/logs/general.yaml index e8f9ea5853..b4afe2c16c 100644 --- a/model/logs/general.yaml +++ b/model/logs/general.yaml @@ -1,20 +1,8 @@ groups: - id: log.record - prefix: log.record type: attribute_group brief: > The attributes described in this section are rather generic. They may be used in any Log Record they apply to. attributes: - - id: uid - type: string - stability: experimental + - ref: log.record.uid requirement_level: opt_in - brief: > - A unique identifier for the Log Record. - note: > - If an id is provided, other log records with the same id will be considered duplicates and can be removed safely. - This means, that two distinguishable log records MUST have different values. - - The id MAY be an [Universally Unique Lexicographically Sortable Identifier (ULID)](https://github.com/ulid/spec), - but other identifiers (e.g. UUID) may be used as needed. - examples: ["01ARZ3NDEKTSV4RRFFQ69G5FAV"] diff --git a/model/logs/media.yaml b/model/logs/media.yaml index b6bfea89d4..34c7631d5c 100644 --- a/model/logs/media.yaml +++ b/model/logs/media.yaml @@ -1,56 +1,21 @@ groups: - id: attributes.log - prefix: log type: attribute_group brief: "Describes Log attributes" attributes: - - id: iostream + - ref: log.iostream requirement_level: opt_in - stability: experimental - brief: > - The stream associated with the log. See below for a list of well-known values. - type: - allow_custom_values: false - members: - - id: stdout - value: 'stdout' - brief: 'Logs from stdout stream' - stability: experimental - - id: stderr - value: 'stderr' - brief: 'Events from stderr stream' - stability: experimental + - id: attributes.log.file - prefix: log.file type: attribute_group brief: > A file to which log was emitted. attributes: - - id: name - type: string - stability: experimental + - ref: log.file.name requirement_level: recommended - brief: > - The basename of the file. - examples: ["audit.log"] - - id: path - type: string - stability: experimental + - ref: log.file.path requirement_level: opt_in - brief: > - The full path to the file. - examples: [ "/var/log/mysql/audit.log" ] - - id: name_resolved - type: string - stability: experimental + - ref: log.file.name_resolved requirement_level: opt_in - brief: > - The basename of the file, with symlinks resolved. - examples: [ "uuid.log" ] - - id: path_resolved - type: string - stability: experimental + - ref: log.file.path_resolved requirement_level: opt_in - brief: > - The full path to the file, with symlinks resolved. - examples: [ "/var/lib/docker/uuid.log" ] diff --git a/model/registry/log.yaml b/model/registry/log.yaml new file mode 100644 index 0000000000..b26870a696 --- /dev/null +++ b/model/registry/log.yaml @@ -0,0 +1,72 @@ +groups: + - id: registry.log + type: attribute_group + prefix: log + brief: > + This document defines log attributes + attributes: + - id: iostream + stability: experimental + brief: > + The stream associated with the log. See below for a list of well-known values. + type: + allow_custom_values: true + members: + - id: stdout + value: 'stdout' + brief: 'Logs from stdout stream' + stability: experimental + - id: stderr + value: 'stderr' + brief: 'Events from stderr stream' + stability: experimental + + - id: registry.log.file # TODO: should we move it to the file model? + type: attribute_group + prefix: log.file + brief: > + Attributes for a file to which log was emitted. + attributes: + - id: name + type: string + stability: experimental + brief: > + The basename of the file. + examples: [ "audit.log" ] + - id: path + type: string + stability: experimental + brief: > + The full path to the file. + examples: [ "/var/log/mysql/audit.log" ] + - id: name_resolved + type: string + stability: experimental + brief: > + The basename of the file, with symlinks resolved. + examples: [ "uuid.log" ] + - id: path_resolved + type: string + stability: experimental + brief: > + The full path to the file, with symlinks resolved. + examples: [ "/var/lib/docker/uuid.log" ] + + - id: registry.log.record + type: attribute_group + prefix: log.record + brief: > + This document defines the generic attributes that may be used in any Log Record. + attributes: + - id: uid + type: string + stability: experimental + brief: > + A unique identifier for the Log Record. + note: > + If an id is provided, other log records with the same id will be considered duplicates and can be removed safely. + This means, that two distinguishable log records MUST have different values. + + The id MAY be an [Universally Unique Lexicographically Sortable Identifier (ULID)](https://github.com/ulid/spec), + but other identifiers (e.g. UUID) may be used as needed. + examples: ["01ARZ3NDEKTSV4RRFFQ69G5FAV"] From b6bc365b7689df96d97682a164318f44e0cd3bd8 Mon Sep 17 00:00:00 2001 From: Nev <54870357+MSNev@users.noreply.github.com> Date: Mon, 22 Apr 2024 09:41:54 -0700 Subject: [PATCH 09/20] Update the device.app.lifecycle event description and constraints (#794) Co-authored-by: Liudmila Molkova --- .chloggen/device_app_lifecycle.yaml | 26 +++++++ .github/ISSUE_TEMPLATE/bug_report.yaml | 1 - .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 - .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 - .gitignore | 1 + .vscode/settings.json | 2 +- docs/attributes-registry/android.md | 9 ++- docs/attributes-registry/ios.md | 8 +- docs/mobile/events.md | 57 +++++++------- model/logs/mobile-events.yaml | 85 +++++++++++++++++---- model/registry/android.yaml | 34 --------- model/registry/deprecated/android.yaml | 36 +++++++++ model/registry/{ => deprecated}/ios.yaml | 6 +- 13 files changed, 180 insertions(+), 87 deletions(-) create mode 100644 .chloggen/device_app_lifecycle.yaml create mode 100644 model/registry/deprecated/android.yaml rename model/registry/{ => deprecated}/ios.yaml (88%) diff --git a/.chloggen/device_app_lifecycle.yaml b/.chloggen/device_app_lifecycle.yaml new file mode 100644 index 0000000000..18fdf8a931 --- /dev/null +++ b/.chloggen/device_app_lifecycle.yaml @@ -0,0 +1,26 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: breaking + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: device.app.lifecycle + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: > + Reformat and update the `device.app.lifecycle` event description adds constraints for the possible values of + the `android.state` and `ios.state`. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [794] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: > + Removes the `ios.lifecycle.events` and `android.lifecycle.events` attributes from the global registry and adds + constraints for the possible values of the `android.state` and `ios.state` attributes. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index c78207d5fe..896738c60c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -46,7 +46,6 @@ body: - area:heroku - area:host - area:http - - area:ios - area:k8s - area:log - area:messaging diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index 355217d372..ca2933bc38 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -39,7 +39,6 @@ body: - area:heroku - area:host - area:http - - area:ios - area:k8s - area:log - area:messaging diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index c4dd0faedb..1c1afe1779 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -48,7 +48,6 @@ body: - area:heroku - area:host - area:http - - area:ios - area:k8s - area:log - area:messaging diff --git a/.gitignore b/.gitignore index c9508b6a86..fdb9989733 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ .project .settings bin +.vs # NetBeans /.nb-gradle diff --git a/.vscode/settings.json b/.vscode/settings.json index ec636cc19b..7741a3e1f5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,7 +11,7 @@ }, "yaml.schemas": { "https://raw.githubusercontent.com/open-telemetry/build-tools/v0.24.0/semantic-conventions/semconv.schema.json": [ - "model/**/*.yaml", + "model/**/*.yaml" ] }, "json.schemaDownload.enable": true diff --git a/docs/attributes-registry/android.md b/docs/attributes-registry/android.md index f2ca703769..971f390749 100644 --- a/docs/attributes-registry/android.md +++ b/docs/attributes-registry/android.md @@ -3,23 +3,24 @@ - [Android Attributes](#android-attributes) -- [Android Lifecycle Event Attributes](#android-lifecycle-event-attributes) +- [Deprecated Android Attributes](#deprecated-android-attributes) ## Android Attributes + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `android.os.api_level` | string | Uniquely identifies the framework API revision offered by a version (`os.version`) of the android operating system. More information can be found [here](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels). | `33`; `32` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -## Android Lifecycle Event Attributes +## Deprecated Android Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| -| `android.state` | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [1] | `created` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `android.state` | string | Deprecated use the `device.app.lifecycle` event definition including `android.state` as a payload field instead. [1] | `created` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), and from which the `OS identifiers` are derived. diff --git a/docs/attributes-registry/ios.md b/docs/attributes-registry/ios.md index e8aea69f54..b867deac8e 100644 --- a/docs/attributes-registry/ios.md +++ b/docs/attributes-registry/ios.md @@ -5,16 +5,16 @@ -- [iOS Lifecycle Event Attributes](#ios-lifecycle-event-attributes) +- [Deprecated iOS Attributes](#deprecated-ios-attributes) -## iOS Lifecycle Event Attributes +## Deprecated iOS Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| -| `ios.state` | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [1] | `active` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ios.state` | string | Deprecated use the `device.app.lifecycle` event definition including `ios.state` as a payload field instead. [1] | `active` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Moved to a payload field of `device.app.lifecycle`. | **[1]:** The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), and from which the `OS terminology` column values are derived. diff --git a/docs/mobile/events.md b/docs/mobile/events.md index b02760674b..06a6907ef4 100644 --- a/docs/mobile/events.md +++ b/docs/mobile/events.md @@ -9,8 +9,7 @@ events on mobile platforms. All mobile events MUST use a namespace of - [Lifecycle instrumentation](#lifecycle-instrumentation) - - [iOS](#ios) - - [Android](#android) + - [Event details](#event-details) @@ -21,39 +20,35 @@ application lifecycle. This event is meant to be used in conjunction with `os.name` [resource semantic convention](/docs/resource/os.md) to identify the mobile operating system (e.g. Android, iOS). -### iOS +The following table describes the payload fields that MUST +be used to describe the state of the application at the time of the event. - -The event name MUST be `device.app.lifecycle`. - -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | -|---|---|---|---|---|---| -| [`ios.state`](../attributes-registry/ios.md) | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [1] | `active` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +The `android.state` and `ios.state` fields are mutually exclusive and MUST +NOT be used together, each field MUST be used with its corresponding +`os.name` [resource semantic convention](/docs/resource/os.md) value. -**[1]:** The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), and from which the `OS terminology` column values are derived. +### Event details -`ios.state` 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. + +The event name MUST be `device.app.lifecycle`. -| Value | Description | Stability | -|---|---|---| -| `active` | The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `inactive` | The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `background` | The app is now in the background. This value is associated with UIKit notification `applicationDidEnterBackground`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `foreground` | The app is now in the foreground. This value is associated with UIKit notification `applicationWillEnterForeground`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `terminate` | The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -### Android - - -The event name MUST be `device.app.lifecycle`. - -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | + +| Body Field | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`android.state`](../attributes-registry/android.md) | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [1] | `created` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `android.state` | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [1] | `created` | `Conditionally Required`: if and only if `os.name` is `android` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ios.state` | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [2] | `active` | `Conditionally Required`: if and only if `os.name` is `ios` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), and from which the `OS identifiers` are derived. +**[2]:** The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), and from which the `OS terminology` column values are derived. + +**Additional attribute requirements:** At least one of the following sets of attributes is required: + +* `ios.state` +* `android.state` + `android.state` 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 | @@ -61,6 +56,16 @@ The event name MUST be `device.app.lifecycle`. | `created` | Any time before Activity.onResume() or, if the app has no Activity, Context.startService() has been called in the app for the first time. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `background` | Any time after Activity.onPause() or, if the app has no Activity, Context.stopService() has been called when the app was in the foreground state. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `foreground` | Any time after Activity.onResume() or, if the app has no Activity, Context.startService() has been called when the app was in either the created or background states. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - + +`ios.state` MUST be one of the following: + +| Value | Description | Stability | +|---|---|---| +| `active` | The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `inactive` | The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `background` | The app is now in the background. This value is associated with UIKit notification `applicationDidEnterBackground`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `foreground` | The app is now in the foreground. This value is associated with UIKit notification `applicationWillEnterForeground`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `terminate` | The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md diff --git a/model/logs/mobile-events.yaml b/model/logs/mobile-events.yaml index 6664bd1edb..4b1d956b21 100644 --- a/model/logs/mobile-events.yaml +++ b/model/logs/mobile-events.yaml @@ -1,17 +1,76 @@ groups: - - id: ios.lifecycle.events + - id: device.app.lifecycle + stability: experimental type: event name: device.app.lifecycle brief: > - This event represents an occurrence of a lifecycle transition on the iOS platform. - attributes: - - ref: ios.state - requirement_level: "required" - - id: android.lifecycle.events - type: event - name: device.app.lifecycle - brief: > - This event represents an occurrence of a lifecycle transition on the Android platform. - attributes: - - ref: android.state - requirement_level: required + This event represents an occurrence of a lifecycle transition on Android or iOS platform. + note: > + This event identifies the fields that are common to all lifecycle events for android and iOS using + the `android.state` and `ios.state` fields. The `android.state` and `ios.state` attributes are + mutually exclusive. + # Future Note: When the build tools support this definition please uncomment and validate the details + # included here and what has been added to the manual markdown table + # body: + # fields: + # - id: ios.state + # stability: experimental + # requirement_level: + # conditional_required: if and only if `os.name` is `ios` + # note: > + # The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), + # and from which the `OS terminology` column values are derived. + # brief: > + # This attribute represents the state the application has transitioned into at the occurrence of the event. + # type: + # allow_custom_values: false + # members: + # - id: active + # value: 'active' + # brief: > + # The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`. + # - id: inactive + # value: 'inactive' + # brief: > + # The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`. + # - id: background + # value: 'background' + # brief: > + # The app is now in the background. + # This value is associated with UIKit notification `applicationDidEnterBackground`. + # - id: foreground + # value: 'foreground' + # brief: > + # The app is now in the foreground. + # This value is associated with UIKit notification `applicationWillEnterForeground`. + # - id: terminate + # value: 'terminate' + # brief: > + # The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`. + # - id: android.state + # stability: experimental + # requirement_level: + # conditional_required: if and only if `os.name` is `android` + # brief: > + # This attribute represents the state the application has transitioned into at the occurrence of the event. + # note: > + # The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), + # and from which the `OS identifiers` are derived. + # type: + # allow_custom_values: false + # members: + # - id: created + # value: 'created' + # brief: > + # Any time before Activity.onResume() or, if the app has no Activity, Context.startService() + # has been called in the app for the first time. + # - id: background + # value: 'background' + # brief: > + # Any time after Activity.onPause() or, if the app has no Activity, + # Context.stopService() has been called when the app was in the foreground state. + # - id: foreground + # value: 'foreground' + # brief: > + # Any time after Activity.onResume() or, if the app has no Activity, + # Context.startService() has been called when the app was in either the created or background states. diff --git a/model/registry/android.yaml b/model/registry/android.yaml index bddc74a09a..cfdcac8a46 100644 --- a/model/registry/android.yaml +++ b/model/registry/android.yaml @@ -13,37 +13,3 @@ groups: (`os.version`) of the android operating system. More information can be found [here](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels). examples: ['33', '32'] - - id: registry.android.lifecycle.events - prefix: android - type: attribute_group - brief: > - This document defines attributes that represents an occurrence of a lifecycle transition on the Android platform. - attributes: - - id: state - stability: experimental - brief: > - This attribute represents the state the application has transitioned into at the occurrence of the event. - note: > - The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), - and from which the `OS identifiers` are derived. - type: - allow_custom_values: true - members: - - id: created - value: 'created' - brief: > - Any time before Activity.onResume() or, if the app has no Activity, Context.startService() - has been called in the app for the first time. - stability: experimental - - id: background - value: 'background' - brief: > - Any time after Activity.onPause() or, if the app has no Activity, - Context.stopService() has been called when the app was in the foreground state. - stability: experimental - - id: foreground - value: 'foreground' - brief: > - Any time after Activity.onResume() or, if the app has no Activity, - Context.startService() has been called when the app was in either the created or background states. - stability: experimental diff --git a/model/registry/deprecated/android.yaml b/model/registry/deprecated/android.yaml new file mode 100644 index 0000000000..97e9bd1e7a --- /dev/null +++ b/model/registry/deprecated/android.yaml @@ -0,0 +1,36 @@ +groups: + - id: registry.android.deprecated + prefix: android + type: attribute_group + brief: > + This document defines attributes that represents an occurrence of a lifecycle transition on the Android platform. + attributes: + - id: state + stability: experimental + brief: > + Deprecated use the `device.app.lifecycle` event definition including + `android.state` as a payload field instead. + note: > + The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), + and from which the `OS identifiers` are derived. + type: + allow_custom_values: true + members: + - id: created + value: 'created' + brief: > + Any time before Activity.onResume() or, if the app has no Activity, Context.startService() + has been called in the app for the first time. + stability: experimental + - id: background + value: 'background' + brief: > + Any time after Activity.onPause() or, if the app has no Activity, + Context.stopService() has been called when the app was in the foreground state. + stability: experimental + - id: foreground + value: 'foreground' + brief: > + Any time after Activity.onResume() or, if the app has no Activity, + Context.startService() has been called when the app was in either the created or background states. + stability: experimental diff --git a/model/registry/ios.yaml b/model/registry/deprecated/ios.yaml similarity index 88% rename from model/registry/ios.yaml rename to model/registry/deprecated/ios.yaml index 1bfe30f325..acc1a9f1f9 100644 --- a/model/registry/ios.yaml +++ b/model/registry/deprecated/ios.yaml @@ -1,5 +1,5 @@ groups: - - id: registry.ios.lifecycle.events + - id: registry.ios.deprecated prefix: ios type: attribute_group brief: > @@ -7,11 +7,13 @@ groups: attributes: - id: state stability: experimental + deprecated: "Moved to a payload field of `device.app.lifecycle`." note: > The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), and from which the `OS terminology` column values are derived. brief: > - This attribute represents the state the application has transitioned into at the occurrence of the event. + Deprecated use the `device.app.lifecycle` event definition including + `ios.state` as a payload field instead. type: allow_custom_values: true members: From c0e170d51e02dfd68d48a766f258895a55ee87da Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Mon, 22 Apr 2024 16:39:10 -0700 Subject: [PATCH 10/20] Add db.client.operation.duration metric (#735) Co-authored-by: Trask Stalnaker Co-authored-by: Liudmila Molkova --- .chloggen/735.yaml | 22 ++++++ docs/database/database-metrics.md | 110 ++++++++++++++++++++++++++++ model/metrics/database-metrics.yaml | 9 +++ 3 files changed, 141 insertions(+) create mode 100644 .chloggen/735.yaml diff --git a/.chloggen/735.yaml b/.chloggen/735.yaml new file mode 100644 index 0000000000..e28402e049 --- /dev/null +++ b/.chloggen/735.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: db + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add `db.client.operation.duration` metric + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [512] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/database/database-metrics.md b/docs/database/database-metrics.md index d779bc7a6d..ccf76a54b1 100644 --- a/docs/database/database-metrics.md +++ b/docs/database/database-metrics.md @@ -15,6 +15,8 @@ and attributes but more may be added in the future. +- [Database operation](#database-operation) + - [Metric: `db.client.operation.duration`](#metric-dbclientoperationduration) - [Connection pools](#connection-pools) - [Metric: `db.client.connections.usage`](#metric-dbclientconnectionsusage) - [Metric: `db.client.connections.idle.max`](#metric-dbclientconnectionsidlemax) @@ -35,6 +37,114 @@ and attributes but more may be added in the future. > until a transition plan to the (future) stable semantic conventions has been published. > Conventions include, but are not limited to, attributes, metric and span names, and unit of measure. +## Database operation + +### Metric: `db.client.operation.duration` + +**Status**: [Experimental][DocumentStatus] + +This metric is [required][MetricRequired]. + +When this metric is reported alongside a database operation span, the metric value SHOULD be the same as the database operation span duration. + +This metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/metrics/api.md#instrument-advisory-parameters) +of `[ 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10 ]`. + + +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `db.client.operation.duration` | Histogram | `s` | Duration of database client operations. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`db.system`](../attributes-registry/db.md) | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.collection.name`](../attributes-registry/db.md) | string | The name of a collection (table, container) within the database. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.name`](../attributes-registry/db.md) | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [3] | `customers`; `main` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [5] | `80`; `8080`; `443` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | `Recommended` If different from the `server.address` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [7] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this database system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +**[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. + +**[2]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.collection.name`, then it SHOULD be the first collection name found in the query. + +**[3]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). + +**[4]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. + +**[5]:** 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]:** If using a port other than the default port for this DBMS and if `server.address` is set. + +**[7]:** Semantic conventions for individual database systems SHOULD document whether `network.peer.*` attributes are applicable. Network peer address and port are useful when the application interacts with individual database nodes directly. +If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. + +**[8]:** 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. + +`db.system` 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_sql` | Some other SQL database. Fallback only. See notes. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mssql` | Microsoft SQL Server | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mssqlcompact` | Microsoft SQL Server Compact | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mysql` | MySQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `oracle` | Oracle Database | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db2` | IBM Db2 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `postgresql` | PostgreSQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `redshift` | Amazon Redshift | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hive` | Apache Hive | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudscape` | Cloudscape | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hsqldb` | HyperSQL DataBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `progress` | Progress Database | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `maxdb` | SAP MaxDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hanadb` | SAP HANA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ingres` | Ingres | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `firstsql` | FirstSQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `edb` | EnterpriseDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cache` | InterSystems Caché | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `adabas` | Adabas (Adaptable Database System) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `firebird` | Firebird | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `derby` | Apache Derby | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `filemaker` | FileMaker | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `informix` | Informix | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `instantdb` | InstantDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `interbase` | InterBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mariadb` | MariaDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `netezza` | Netezza | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pervasive` | Pervasive PSQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pointbase` | PointBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `sqlite` | SQLite | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `sybase` | Sybase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `teradata` | Teradata | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `vertica` | Vertica | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `h2` | H2 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `coldfusion` | ColdFusion IMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cassandra` | Apache Cassandra | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hbase` | Apache HBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mongodb` | MongoDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `redis` | Redis | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `couchbase` | Couchbase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `couchdb` | CouchDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cosmosdb` | Microsoft Azure Cosmos DB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dynamodb` | Amazon DynamoDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `neo4j` | Neo4j | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `geode` | Apache Geode | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `elasticsearch` | Elasticsearch | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `memcached` | Memcached | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cockroachdb` | CockroachDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `opensearch` | OpenSearch | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `clickhouse` | ClickHouse | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `spanner` | Cloud Spanner | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `trino` | Trino | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + ## Connection pools The following metric instruments describe database client connection pool operations. diff --git a/model/metrics/database-metrics.yaml b/model/metrics/database-metrics.yaml index cce9257e4f..ec8f61c55c 100644 --- a/model/metrics/database-metrics.yaml +++ b/model/metrics/database-metrics.yaml @@ -1,4 +1,13 @@ groups: + - id: metric.db.client.operation.duration + type: metric + metric_name: db.client.operation.duration + brief: "Duration of database client operations." + instrument: histogram + unit: "s" + stability: experimental + extends: attributes.db.client + - id: metric.db.client.connections.usage type: metric metric_name: db.client.connections.usage From dd73dba5ac55bd4e6adca0ac5ff217818923c241 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 23 Apr 2024 02:47:35 -0700 Subject: [PATCH 11/20] Should -> SHOULD (#946) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- docs/database/database-spans.md | 2 +- docs/database/redis.md | 2 +- model/trace/database.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 275ae4e5a9..15a6080f17 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -96,7 +96,7 @@ These attributes will usually be the same for all operations performed over the **[6]:** If using a port other than the default port for this DBMS and if `server.address` is set. -**[7]:** Should be collected by default only if there is sanitization that excludes sensitive information. +**[7]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. **[8]:** Semantic conventions for individual database systems SHOULD document whether `network.peer.*` attributes are applicable. Network peer address and port are useful when the application interacts with individual database nodes directly. If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. diff --git a/docs/database/redis.md b/docs/database/redis.md index 27b9e0461d..052c0a8048 100644 --- a/docs/database/redis.md +++ b/docs/database/redis.md @@ -24,7 +24,7 @@ described on this page. **[1]:** For **Redis**, the value provided for `db.query.text` SHOULD correspond to the syntax of the Redis CLI. If, for example, the [`HMSET` command](https://redis.io/commands/hmset) is invoked, `"HMSET myhash field1 'Hello' field2 'World'"` would be a suitable value for `db.query.text`. -**[2]:** Should be collected by default only if there is sanitization that excludes sensitive information. +**[2]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. **[3]:** If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. diff --git a/model/trace/database.yaml b/model/trace/database.yaml index d42d1c6b68..e0f6aee6c5 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -7,7 +7,7 @@ groups: - ref: db.query.text requirement_level: recommended: > - Should be collected by default only if there is sanitization that excludes sensitive information. + SHOULD be collected by default only if there is sanitization that excludes sensitive information. - ref: db.query.parameter requirement_level: opt_in From 8d6f12bd82a28f827d5efce7b70fc413659fb212 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Tue, 23 Apr 2024 17:30:22 +0200 Subject: [PATCH 12/20] Clarify fully-qualified name should be used for `error.type` (#945) Co-authored-by: Liudmila Molkova --- docs/attributes-registry/error.md | 6 +++++- docs/dotnet/dotnet-aspnetcore-metrics.md | 6 +++++- docs/messaging/messaging-metrics.md | 6 +++++- docs/messaging/messaging-spans.md | 6 +++++- model/registry/error.yaml | 6 +++++- 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/docs/attributes-registry/error.md b/docs/attributes-registry/error.md index 1b43a77600..a97583c0f4 100644 --- a/docs/attributes-registry/error.md +++ b/docs/attributes-registry/error.md @@ -10,7 +10,11 @@ |---|---|---|---|---| | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. +**[1]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. + +When `error.type` is set to a type (e.g., an exception type), its +canonical class name identifying the type within the artifact SHOULD be used. + Instrumentations SHOULD document the list of errors they report. The cardinality of `error.type` within one instrumentation library SHOULD be low. diff --git a/docs/dotnet/dotnet-aspnetcore-metrics.md b/docs/dotnet/dotnet-aspnetcore-metrics.md index d2b8491d18..edcd0615ef 100644 --- a/docs/dotnet/dotnet-aspnetcore-metrics.md +++ b/docs/dotnet/dotnet-aspnetcore-metrics.md @@ -79,7 +79,11 @@ Exceptions Metric is reported by the `Microsoft.AspNetCore.Diagnostics` meter. | [`error.type`](../attributes-registry/error.md) | string | The full name of exception type. [1] | `System.OperationCanceledException`; `Contoso.MyException` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `aspnetcore.diagnostics.handler.type` | string | Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) implementation that handled the exception. | `Contoso.MyHandler` | `Conditionally Required` [2] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. +**[1]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. + +When `error.type` is set to a type (e.g., an exception type), its +canonical class name identifying the type within the artifact SHOULD be used. + Instrumentations SHOULD document the list of errors they report. The cardinality of `error.type` within one instrumentation library SHOULD be low. diff --git a/docs/messaging/messaging-metrics.md b/docs/messaging/messaging-metrics.md index a92f357914..6d3f8da201 100644 --- a/docs/messaging/messaging-metrics.md +++ b/docs/messaging/messaging-metrics.md @@ -40,7 +40,11 @@ All messaging metrics share the same set of attributes: | [`messaging.destination.partition.id`](../attributes-registry/messaging.md) | string | The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`server.port`](../attributes-registry/server.md) | int | Server port number. [7] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. +**[1]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. + +When `error.type` is set to a type (e.g., an exception type), its +canonical class name identifying the type within the artifact SHOULD be used. + Instrumentations SHOULD document the list of errors they report. The cardinality of `error.type` within one instrumentation library SHOULD be low. diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 4b4f450e5c..1b83775077 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -308,7 +308,11 @@ as described in [Attributes specific to certain messaging systems](#attributes-s **[1]:** If a custom value is used, it MUST be of low cardinality. -**[2]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. +**[2]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. + +When `error.type` is set to a type (e.g., an exception type), its +canonical class name identifying the type within the artifact SHOULD be used. + Instrumentations SHOULD document the list of errors they report. The cardinality of `error.type` within one instrumentation library SHOULD be low. diff --git a/model/registry/error.yaml b/model/registry/error.yaml index 9864db9ce3..68bde170ba 100644 --- a/model/registry/error.yaml +++ b/model/registry/error.yaml @@ -19,7 +19,11 @@ groups: A fallback error value to be used when the instrumentation doesn't define a custom value. examples: ['timeout', 'java.net.UnknownHostException', 'server_certificate_invalid', '500'] note: | - The `error.type` SHOULD be predictable and SHOULD have low cardinality. + The `error.type` SHOULD be predictable, and SHOULD have low cardinality. + + When `error.type` is set to a type (e.g., an exception type), its + canonical class name identifying the type within the artifact SHOULD be used. + Instrumentations SHOULD document the list of errors they report. The cardinality of `error.type` within one instrumentation library SHOULD be low. From 6af1ab47a81cb4a7610b77f46901422c29f69c15 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 23 Apr 2024 18:06:15 -0700 Subject: [PATCH 13/20] Fix markdown status of exceptions (#951) --- docs/exceptions/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/exceptions/README.md b/docs/exceptions/README.md index 5791b59882..91f6c88305 100644 --- a/docs/exceptions/README.md +++ b/docs/exceptions/README.md @@ -7,7 +7,7 @@ path_base_for_github_subdir: # Semantic Conventions for Exceptions -**Status**: [Experimental][DocumentStatus] +**Status**: [Stable][DocumentStatus] This document defines semantic conventions for Exceptions. From 83369f23dd091ca205f432a310493b38402130e4 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 24 Apr 2024 06:21:16 -0700 Subject: [PATCH 14/20] [chore] Split db and messaging registry groups (#952) --- docs/attributes-registry/db.md | 12 +- docs/attributes-registry/messaging.md | 16 +- model/registry/db.yaml | 440 +++++++++++++------------- model/registry/messaging.yaml | 225 +++++++------ 4 files changed, 347 insertions(+), 346 deletions(-) diff --git a/docs/attributes-registry/db.md b/docs/attributes-registry/db.md index 5940f91d71..57f2d98a46 100644 --- a/docs/attributes-registry/db.md +++ b/docs/attributes-registry/db.md @@ -18,7 +18,7 @@ ## Generic Database Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `db.client.connections.pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -105,7 +105,7 @@ If a parameter has no name and instead is referenced only by index, then `` ## Cassandra Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `db.cassandra.consistency_level` | string | The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). | `all` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -134,7 +134,7 @@ If a parameter has no name and instead is referenced only by index, then `` ## CosmosDB Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `db.cosmosdb.client_id` | string | Unique Cosmos client instance id. | `3ba4827d-4422-483f-b59f-85b74211c11d` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -175,7 +175,7 @@ If a parameter has no name and instead is referenced only by index, then `` ## Elasticsearch Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `db.elasticsearch.cluster.name` | string | Represents the identifier of an Elasticsearch cluster. | `e9106fc68e3044f0b1475b04bf4ffd5f` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -186,7 +186,7 @@ If a parameter has no name and instead is referenced only by index, then `` ## MSSQL Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. [1] | `MSSQLSERVER` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -196,7 +196,7 @@ If a parameter has no name and instead is referenced only by index, then `` ## Redis Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `db.redis.database_index` | int | The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute. | `0`; `1`; `15` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/messaging.md b/docs/attributes-registry/messaging.md index 7e83f76a3c..b41d340165 100644 --- a/docs/attributes-registry/messaging.md +++ b/docs/attributes-registry/messaging.md @@ -18,7 +18,7 @@ ## Generic Messaging Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `messaging.batch.message_count` | int | The number of messages sent, received, or processed in the scope of the batching operation. [1] | `0`; `1`; `2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -84,7 +84,7 @@ size should be used. ## GCP Pub/Sub Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `messaging.gcp_pubsub.message.ordering_key` | string | The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. | `ordering_key` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -92,7 +92,7 @@ size should be used. ## Kafka Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `messaging.kafka.consumer.group` | string | Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. | `my-group` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -105,7 +105,7 @@ size should be used. ## RabbitMQ Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `messaging.rabbitmq.destination.routing_key` | string | RabbitMQ message routing key. | `myKey` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -114,7 +114,7 @@ size should be used. ## RocketMQ Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `messaging.rocketmq.client_group` | string | Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. | `myConsumerGroup` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -146,7 +146,7 @@ size should be used. ## Azure Event Hubs Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `messaging.eventhubs.consumer.group` | string | The name of the consumer group the event consumer is associated with. | `indexer` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -155,7 +155,7 @@ size should be used. ## Azure Service Bus Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `messaging.servicebus.destination.subscription_name` | string | The name of the subscription in the topic messages are received from. | `mySubscription` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -175,7 +175,7 @@ size should be used. ## Deprecated Messaging Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `messaging.kafka.destination.partition` | int | Deprecated, use `messaging.destination.partition.id` instead. | `2` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `messaging.destination.partition.id`. | diff --git a/model/registry/db.yaml b/model/registry/db.yaml index 25532ab6a4..293ec073fb 100644 --- a/model/registry/db.yaml +++ b/model/registry/db.yaml @@ -3,82 +3,8 @@ groups: prefix: db type: attribute_group brief: > - This document defines the attributes used to describe telemetry in the context of databases. + This group defines the attributes used to describe telemetry in the context of databases. attributes: - - id: cassandra.coordinator.dc - type: string - stability: experimental - brief: > - The data center of the coordinating node for a query. - examples: 'us-west-2' - tag: tech-specific-cassandra - - id: cassandra.coordinator.id - type: string - stability: experimental - brief: > - The ID of the coordinating node for a query. - examples: 'be13faa2-8574-4d71-926d-27f16cf8a7af' - tag: tech-specific-cassandra - - id: cassandra.consistency_level - brief: > - The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). - type: - members: - - id: all - value: 'all' - stability: experimental - - id: each_quorum - value: 'each_quorum' - stability: experimental - - id: quorum - value: 'quorum' - stability: experimental - - id: local_quorum - value: 'local_quorum' - stability: experimental - - id: one - value: 'one' - stability: experimental - - id: two - value: 'two' - stability: experimental - - id: three - value: 'three' - stability: experimental - - id: local_one - value: 'local_one' - stability: experimental - - id: any - value: 'any' - stability: experimental - - id: serial - value: 'serial' - stability: experimental - - id: local_serial - value: 'local_serial' - stability: experimental - stability: experimental - tag: tech-specific-cassandra - - id: cassandra.idempotence - type: boolean - stability: experimental - brief: > - Whether or not the query is idempotent. - tag: tech-specific-cassandra - - id: cassandra.page_size - type: int - stability: experimental - brief: > - The fetch size used for paging, i.e. how many rows will be returned at once. - examples: [5000] - tag: tech-specific-cassandra - - id: cassandra.speculative_execution_count - type: int - stability: experimental - brief: > - The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. - examples: [0, 2] - tag: tech-specific-cassandra - id: collection.name type: string stability: experimental @@ -86,134 +12,7 @@ groups: note: > If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. - tag: db-generic examples: ['public.users', 'customers'] - - id: cosmosdb.client_id - type: string - stability: experimental - brief: Unique Cosmos client instance id. - examples: '3ba4827d-4422-483f-b59f-85b74211c11d' - tag: tech-specific-cosmosdb - - id: cosmosdb.connection_mode - type: - allow_custom_values: false - members: - - id: gateway - value: 'gateway' - brief: Gateway (HTTP) connections mode - stability: experimental - - id: direct - value: 'direct' - brief: Direct connection. - stability: experimental - stability: experimental - brief: Cosmos client connection mode. - tag: tech-specific-cosmosdb - - id: cosmosdb.operation_type - type: - allow_custom_values: true - members: - - id: invalid - value: 'Invalid' - stability: experimental - - id: create - value: 'Create' - stability: experimental - - id: patch - value: 'Patch' - stability: experimental - - id: read - value: 'Read' - stability: experimental - - id: read_feed - value: 'ReadFeed' - stability: experimental - - id: delete - value: 'Delete' - stability: experimental - - id: replace - value: 'Replace' - stability: experimental - - id: execute - value: 'Execute' - stability: experimental - - id: query - value: 'Query' - stability: experimental - - id: head - value: 'Head' - stability: experimental - - id: head_feed - value: 'HeadFeed' - stability: experimental - - id: upsert - value: 'Upsert' - stability: experimental - - id: batch - value: 'Batch' - stability: experimental - - id: query_plan - value: 'QueryPlan' - stability: experimental - - id: execute_javascript - value: 'ExecuteJavaScript' - stability: experimental - stability: experimental - brief: CosmosDB Operation Type. - tag: tech-specific-cosmosdb - - id: cosmosdb.request_charge - type: double - stability: experimental - brief: RU consumed for that operation - examples: [46.18, 1.0] - tag: tech-specific-cosmosdb - - id: cosmosdb.request_content_length - type: int - stability: experimental - brief: Request payload size in bytes - tag: tech-specific-cosmosdb - - id: cosmosdb.status_code - type: int - stability: experimental - brief: Cosmos DB status code. - examples: [200, 201] - tag: tech-specific-cosmosdb - - id: cosmosdb.sub_status_code - type: int - stability: experimental - brief: Cosmos DB sub status code. - examples: [1000, 1002] - tag: tech-specific-cosmosdb - - id: elasticsearch.cluster.name - type: string - stability: experimental - brief: > - Represents the identifier of an Elasticsearch cluster. - examples: ["e9106fc68e3044f0b1475b04bf4ffd5f"] - tag: tech-specific-elasticsearch - - id: elasticsearch.path_parts - type: template[string] - stability: experimental - brief: > - A dynamic value in the url path. - note: > - Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format - `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD - reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) - in order to map the path part values to their names. - examples: ['db.elasticsearch.path_parts.index=test-index', 'db.elasticsearch.path_parts.doc_id=123'] - tag: tech-specific-elasticsearch - - id: mssql.instance_name - type: string - stability: experimental - note: > - If setting a `db.mssql.instance_name`, `server.port` is no longer - required (but still recommended if non-standard). - brief: > - The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) - connecting to. This name is used to determine the port of a named instance. - examples: 'MSSQLSERVER' - tag: tech-specific-mssql - id: name type: string stability: experimental @@ -227,29 +26,18 @@ groups: (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). examples: [ 'customers', 'main' ] - tag: db-generic - id: operation.name type: string stability: experimental brief: > The name of the operation or command being executed. examples: ['findAndModify', 'HMSET', 'SELECT'] - tag: db-generic - - id: redis.database_index - type: int - stability: experimental - brief: > - The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. - To be used instead of the generic `db.name` attribute. - examples: [0, 1, 15] - tag: tech-specific-redis - id: query.text type: string stability: experimental brief: > The database query being executed. examples: ['SELECT * FROM wuser_table where username = ?', 'SET mykey "WuValue"'] - tag: db-generic - id: query.parameter type: template[string] stability: experimental @@ -262,7 +50,6 @@ groups: If a parameter has no name and instead is referenced only by index, then `` SHOULD be the 0-based index. examples: ['someval', '55'] - tag: db-generic - id: system brief: An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. type: @@ -477,9 +264,7 @@ groups: brief: 'Trino' stability: experimental stability: experimental - tag: db-generic - id: instance.id - tag: db-generic type: string stability: experimental brief: > @@ -488,7 +273,6 @@ groups: The client may obtain this value in databases like MySQL using queries like `select @@hostname`. examples: 'mysql-e26b99z.example.com' - id: client.connections.state - tag: db-generic stability: experimental type: allow_custom_values: true @@ -502,7 +286,6 @@ groups: brief: "The state of a connection in the pool" examples: ["idle"] - id: client.connections.pool.name - tag: db-generic type: string stability: experimental brief: > @@ -511,3 +294,224 @@ groups: instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. examples: ["myDataSource"] + - id: registry.db.cassandra + prefix: db + type: attribute_group + brief: > + This group defines attributes for Cassandra. + attributes: + - id: cassandra.coordinator.dc + type: string + stability: experimental + brief: > + The data center of the coordinating node for a query. + examples: 'us-west-2' + - id: cassandra.coordinator.id + type: string + stability: experimental + brief: > + The ID of the coordinating node for a query. + examples: 'be13faa2-8574-4d71-926d-27f16cf8a7af' + - id: cassandra.consistency_level + brief: > + The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). + type: + members: + - id: all + value: 'all' + stability: experimental + - id: each_quorum + value: 'each_quorum' + stability: experimental + - id: quorum + value: 'quorum' + stability: experimental + - id: local_quorum + value: 'local_quorum' + stability: experimental + - id: one + value: 'one' + stability: experimental + - id: two + value: 'two' + stability: experimental + - id: three + value: 'three' + stability: experimental + - id: local_one + value: 'local_one' + stability: experimental + - id: any + value: 'any' + stability: experimental + - id: serial + value: 'serial' + stability: experimental + - id: local_serial + value: 'local_serial' + stability: experimental + stability: experimental + - id: cassandra.idempotence + type: boolean + stability: experimental + brief: > + Whether or not the query is idempotent. + - id: cassandra.page_size + type: int + stability: experimental + brief: > + The fetch size used for paging, i.e. how many rows will be returned at once. + examples: [5000] + - id: cassandra.speculative_execution_count + type: int + stability: experimental + brief: > + The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. + examples: [0, 2] + - id: registry.db.cosmosdb + prefix: db + type: attribute_group + brief: > + This group defines attributes for Azure Cosmos DB. + attributes: + - id: cosmosdb.client_id + type: string + stability: experimental + brief: Unique Cosmos client instance id. + examples: '3ba4827d-4422-483f-b59f-85b74211c11d' + - id: cosmosdb.connection_mode + type: + allow_custom_values: false + members: + - id: gateway + value: 'gateway' + brief: Gateway (HTTP) connections mode + stability: experimental + - id: direct + value: 'direct' + brief: Direct connection. + stability: experimental + stability: experimental + brief: Cosmos client connection mode. + - id: cosmosdb.operation_type + type: + allow_custom_values: true + members: + - id: invalid + value: 'Invalid' + stability: experimental + - id: create + value: 'Create' + stability: experimental + - id: patch + value: 'Patch' + stability: experimental + - id: read + value: 'Read' + stability: experimental + - id: read_feed + value: 'ReadFeed' + stability: experimental + - id: delete + value: 'Delete' + stability: experimental + - id: replace + value: 'Replace' + stability: experimental + - id: execute + value: 'Execute' + stability: experimental + - id: query + value: 'Query' + stability: experimental + - id: head + value: 'Head' + stability: experimental + - id: head_feed + value: 'HeadFeed' + stability: experimental + - id: upsert + value: 'Upsert' + stability: experimental + - id: batch + value: 'Batch' + stability: experimental + - id: query_plan + value: 'QueryPlan' + stability: experimental + - id: execute_javascript + value: 'ExecuteJavaScript' + stability: experimental + stability: experimental + brief: CosmosDB Operation Type. + - id: cosmosdb.request_charge + type: double + stability: experimental + brief: RU consumed for that operation + examples: [46.18, 1.0] + - id: cosmosdb.request_content_length + type: int + stability: experimental + brief: Request payload size in bytes + - id: cosmosdb.status_code + type: int + stability: experimental + brief: Cosmos DB status code. + examples: [200, 201] + - id: cosmosdb.sub_status_code + type: int + stability: experimental + brief: Cosmos DB sub status code. + examples: [1000, 1002] + - id: registry.db.elasticsearch + prefix: db + type: attribute_group + brief: > + This group defines attributes for Elasticsearch. + attributes: + - id: elasticsearch.cluster.name + type: string + stability: experimental + brief: > + Represents the identifier of an Elasticsearch cluster. + examples: ["e9106fc68e3044f0b1475b04bf4ffd5f"] + - id: elasticsearch.path_parts + type: template[string] + stability: experimental + brief: > + A dynamic value in the url path. + note: > + Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format + `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD + reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) + in order to map the path part values to their names. + examples: ['db.elasticsearch.path_parts.index=test-index', 'db.elasticsearch.path_parts.doc_id=123'] + - id: registry.db.mssql + prefix: db + type: attribute_group + brief: > + This group defines attributes for Microsoft SQL Server. + attributes: + - id: mssql.instance_name + type: string + stability: experimental + note: > + If setting a `db.mssql.instance_name`, `server.port` is no longer + required (but still recommended if non-standard). + brief: > + The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) + connecting to. This name is used to determine the port of a named instance. + examples: 'MSSQLSERVER' + - id: registry.db.redis + prefix: db + type: attribute_group + brief: > + This group defines attributes for Redis. + attributes: + - id: redis.database_index + type: int + stability: experimental + brief: > + The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. + To be used instead of the generic `db.name` attribute. + examples: [0, 1, 15] diff --git a/model/registry/messaging.yaml b/model/registry/messaging.yaml index 32e603d1dc..4a2c6a2714 100644 --- a/model/registry/messaging.yaml +++ b/model/registry/messaging.yaml @@ -13,14 +13,12 @@ groups: When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. examples: [0, 1, 2] - tag: messaging-generic - id: client_id type: string stability: experimental brief: > A unique identifier for the client that consumes or produces a message. examples: ['client-5', 'myhost@8742@s8083jm'] - tag: messaging-generic - id: destination.name type: string stability: experimental @@ -29,7 +27,6 @@ groups: Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If the broker doesn't have such notion, the destination name SHOULD uniquely identify the broker. examples: ['MyQueue', 'MyTopic'] - tag: messaging-generic - id: destination.template type: string stability: experimental @@ -41,22 +38,18 @@ groups: the underlying template is of low cardinality and can be effectively used for grouping and aggregation. examples: ['/customers/{customerId}'] - tag: messaging-generic - id: destination.anonymous type: boolean stability: experimental brief: 'A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name).' - tag: messaging-generic - id: destination.temporary type: boolean stability: experimental brief: 'A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed.' - tag: messaging-generic - id: destination_publish.anonymous type: boolean stability: experimental brief: 'A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name).' - tag: messaging-generic - id: destination_publish.name type: string stability: experimental @@ -65,46 +58,12 @@ groups: The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If the broker doesn't have such notion, the original destination name SHOULD uniquely identify the broker. examples: ['MyQueue', 'MyTopic'] - tag: messaging-generic - id: destination.partition.id type: string stability: experimental brief: > The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. examples: '1' - tag: messaging-generic - - id: kafka.consumer.group - type: string - stability: experimental - brief: > - Name of the Kafka Consumer Group that is handling the message. - Only applies to consumers, not producers. - examples: 'my-group' - tag: tech-specific-kafka - - id: kafka.message.key - type: string - stability: experimental - brief: > - Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. - They differ from `messaging.message.id` in that they're not unique. - If the key is `null`, the attribute MUST NOT be set. - note: > - If the key type is not string, it's string representation has to be supplied for the attribute. - If the key has no unambiguous, canonical string form, don't include its value. - examples: 'myKey' - tag: tech-specific-kafka - - id: kafka.message.offset - type: int - stability: experimental - brief: > - The offset of a record in the corresponding Kafka partition. - examples: 42 - tag: tech-specific-kafka - - id: kafka.message.tombstone - type: boolean - stability: experimental - brief: 'A boolean that is true if the message is a tombstone.' - tag: tech-specific-kafka - id: message.conversation_id type: string stability: experimental @@ -112,7 +71,6 @@ groups: The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". examples: 'MyConversationId' - tag: messaging-generic - id: message.envelope.size type: int stability: experimental @@ -122,13 +80,11 @@ groups: This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed size should be used. examples: 2738 - tag: messaging-generic - id: message.id type: string stability: experimental brief: 'A value used by the messaging system as an identifier for the message, represented as a string.' examples: '452a7c7c7c7048c2f887f61572b18fc2' - tag: messaging-generic - id: message.body.size type: int stability: experimental @@ -138,7 +94,6 @@ groups: This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed body size should be used. examples: 1439 - tag: messaging-generic - id: operation.type type: allow_custom_values: true @@ -175,36 +130,123 @@ groups: brief: > A string identifying the type of the messaging operation. note: If a custom value is used, it MUST be of low cardinality. - tag: messaging-generic - id: operation.name type: string stability: experimental brief: > The system-specific name of the messaging operation. examples: [ "ack", "nack", "send" ] - tag: messaging-generic + - id: system + brief: > + An identifier for the messaging system being used. See below for a list of well-known identifiers. + type: + allow_custom_values: true + members: + - id: activemq + value: 'activemq' + brief: 'Apache ActiveMQ' + stability: experimental + - id: aws_sqs + value: 'aws_sqs' + brief: 'Amazon Simple Queue Service (SQS)' + stability: experimental + - id: eventgrid + value: 'eventgrid' + brief: 'Azure Event Grid' + stability: experimental + - id: eventhubs + value: 'eventhubs' + brief: 'Azure Event Hubs' + stability: experimental + - id: servicebus + value: 'servicebus' + brief: 'Azure Service Bus' + stability: experimental + - id: gcp_pubsub + value: 'gcp_pubsub' + brief: 'Google Cloud Pub/Sub' + stability: experimental + - id: jms + value: 'jms' + brief: 'Java Message Service' + stability: experimental + - id: kafka + value: 'kafka' + brief: 'Apache Kafka' + stability: experimental + - id: rabbitmq + value: 'rabbitmq' + brief: 'RabbitMQ' + stability: experimental + - id: rocketmq + value: 'rocketmq' + brief: 'Apache RocketMQ' + stability: experimental + stability: experimental + - id: registry.messaging.kafka + prefix: messaging + type: attribute_group + brief: > + This group describes attributes specific to Apache Kafka. + attributes: + - id: kafka.consumer.group + type: string + stability: experimental + brief: > + Name of the Kafka Consumer Group that is handling the message. + Only applies to consumers, not producers. + examples: 'my-group' + - id: kafka.message.key + type: string + stability: experimental + brief: > + Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. + They differ from `messaging.message.id` in that they're not unique. + If the key is `null`, the attribute MUST NOT be set. + note: > + If the key type is not string, it's string representation has to be supplied for the attribute. + If the key has no unambiguous, canonical string form, don't include its value. + examples: 'myKey' + - id: kafka.message.offset + type: int + stability: experimental + brief: > + The offset of a record in the corresponding Kafka partition. + examples: 42 + - id: kafka.message.tombstone + type: boolean + stability: experimental + brief: 'A boolean that is true if the message is a tombstone.' + - id: registry.messaging.rabbitmq + prefix: messaging + type: attribute_group + brief: > + This group describes attributes specific to RabbitMQ. + attributes: - id: rabbitmq.destination.routing_key type: string stability: experimental brief: > RabbitMQ message routing key. examples: 'myKey' - tag: tech-specific-rabbitmq - id: rabbitmq.message.delivery_tag type: int stability: experimental brief: > RabbitMQ message delivery tag examples: 123 - tag: tech-specific-rabbitmq - + - id: registry.messaging.rocketmq + prefix: messaging + type: attribute_group + brief: > + This group describes attributes specific to RocketMQ. + attributes: - id: rocketmq.client_group type: string stability: experimental brief: > Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. examples: 'myConsumerGroup' - tag: tech-specific-rocketmq - id: rocketmq.consumption_model type: allow_custom_values: false @@ -220,42 +262,36 @@ groups: stability: experimental brief: > Model of message consumption. This only applies to consumer spans. - tag: tech-specific-rocketmq - id: rocketmq.message.delay_time_level type: int stability: experimental brief: > The delay time level for delay message, which determines the message delay time. examples: 3 - tag: tech-specific-rocketmq - id: rocketmq.message.delivery_timestamp type: int stability: experimental brief: > The timestamp in milliseconds that the delay message is expected to be delivered to consumer. examples: 1665987217045 - tag: tech-specific-rocketmq - id: rocketmq.message.group type: string stability: experimental brief: > It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. examples: 'myMessageGroup' - tag: tech-specific-rocketmq - id: rocketmq.message.keys type: string[] stability: experimental brief: > Key(s) of message, another way to mark message besides message id. examples: ['keyA', 'keyB'] - tag: tech-specific-rocketmq - id: rocketmq.message.tag type: string stability: experimental brief: > The secondary classifier of message besides topic. examples: tagA - tag: tech-specific-rocketmq - id: rocketmq.message.type type: allow_custom_values: false @@ -279,90 +315,48 @@ groups: stability: experimental brief: > Type of message. - tag: tech-specific-rocketmq - id: rocketmq.namespace type: string stability: experimental brief: > Namespace of RocketMQ resources, resources in different namespaces are individual. examples: 'myNamespace' - tag: tech-specific-rocketmq + - id: registry.messaging.gcp_pubsub + prefix: messaging + type: attribute_group + brief: > + This group describes attributes specific to GCP Pub/Sub. + attributes: - id: gcp_pubsub.message.ordering_key type: string stability: experimental brief: > The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. examples: 'ordering_key' - tag: tech-specific-gcp-pubsub - - id: system - brief: > - An identifier for the messaging system being used. See below for a list of well-known identifiers. - type: - allow_custom_values: true - members: - - id: activemq - value: 'activemq' - brief: 'Apache ActiveMQ' - stability: experimental - - id: aws_sqs - value: 'aws_sqs' - brief: 'Amazon Simple Queue Service (SQS)' - stability: experimental - - id: eventgrid - value: 'eventgrid' - brief: 'Azure Event Grid' - stability: experimental - - id: eventhubs - value: 'eventhubs' - brief: 'Azure Event Hubs' - stability: experimental - - id: servicebus - value: 'servicebus' - brief: 'Azure Service Bus' - stability: experimental - - id: gcp_pubsub - value: 'gcp_pubsub' - brief: 'Google Cloud Pub/Sub' - stability: experimental - - id: jms - value: 'jms' - brief: 'Java Message Service' - stability: experimental - - id: kafka - value: 'kafka' - brief: 'Apache Kafka' - stability: experimental - - id: rabbitmq - value: 'rabbitmq' - brief: 'RabbitMQ' - stability: experimental - - id: rocketmq - value: 'rocketmq' - brief: 'Apache RocketMQ' - stability: experimental - stability: experimental - tag: messaging-generic + - id: registry.messaging.servicebus + prefix: messaging + type: attribute_group + brief: > + This group describes attributes specific to Azure Service Bus. + attributes: - id: servicebus.message.delivery_count type: int stability: experimental brief: > Number of deliveries that have been attempted for this message. examples: 2 - tag: tech-specific-servicebus - id: servicebus.message.enqueued_time type: int stability: experimental brief: > The UTC epoch seconds at which the message has been accepted and stored in the entity. examples: 1701393730 - tag: tech-specific-servicebus - id: servicebus.destination.subscription_name type: string stability: experimental brief: > The name of the subscription in the topic messages are received from. examples: "mySubscription" - tag: tech-specific-servicebus - id: servicebus.disposition_status brief: > Describes the [settlement type](https://learn.microsoft.com/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock). @@ -386,18 +380,21 @@ groups: brief: 'Message is deferred' stability: experimental stability: experimental - tag: tech-specific-servicebus + - id: registry.messaging.eventhubs + prefix: messaging + type: attribute_group + brief: > + This group describes attributes specific to Azure Event Hubs. + attributes: - id: eventhubs.message.enqueued_time type: int stability: experimental brief: > The UTC epoch seconds at which the message has been accepted and stored in the entity. examples: 1701393730 - tag: tech-specific-eventhubs - id: eventhubs.consumer.group type: string stability: experimental brief: > The name of the consumer group the event consumer is associated with. examples: 'indexer' - tag: tech-specific-eventhubs From a28fa9e62eca17c2a470d25a13a49811fa58b29c Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Wed, 24 Apr 2024 18:32:01 +0200 Subject: [PATCH 15/20] [chore] fix type of registry groups (#957) Co-authored-by: Liudmila Molkova --- model/registry/aws.yaml | 2 +- model/registry/otel.yaml | 2 +- model/registry/peer.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/model/registry/aws.yaml b/model/registry/aws.yaml index 6214375852..90bb10b853 100644 --- a/model/registry/aws.yaml +++ b/model/registry/aws.yaml @@ -315,7 +315,7 @@ groups: examples: ["8", "26"] - id: registry.aws.eks prefix: aws.eks - type: resource + type: attribute_group brief: > This document defines attributes for AWS Elastic Kubernetes Service (EKS). attributes: diff --git a/model/registry/otel.yaml b/model/registry/otel.yaml index 7da6ece282..76286cdc9b 100644 --- a/model/registry/otel.yaml +++ b/model/registry/otel.yaml @@ -25,7 +25,7 @@ groups: stability: stable - id: registry.otel.scope prefix: otel.scope - type: resource + type: attribute_group brief: Attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. attributes: - id: name diff --git a/model/registry/peer.yaml b/model/registry/peer.yaml index 58ee700904..a6e38a129d 100644 --- a/model/registry/peer.yaml +++ b/model/registry/peer.yaml @@ -1,6 +1,6 @@ groups: - id: registry.peer - type: span + type: attribute_group prefix: peer brief: > Operations that access some remote service. From 7c09a909b5da756a0823c49da437c4b6a5508d57 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 24 Apr 2024 12:40:31 -0400 Subject: [PATCH 16/20] =?UTF-8?q?(chore)=20Remove=20common=20attributes=20?= =?UTF-8?q?from=20RPC=20documentation=20in=20favor=20of=20f=E2=80=A6=20(#9?= =?UTF-8?q?60)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/rpc/rpc-spans.md | 103 ++++++++++++++++++++++++++++-------------- 1 file changed, 68 insertions(+), 35 deletions(-) diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index 387f5b56b1..f38c76f0b7 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -15,8 +15,7 @@ This document defines how to describe remote procedure calls - [Common remote procedure call conventions](#common-remote-procedure-call-conventions) - [Span name](#span-name) - - [Common attributes](#common-attributes) - - [Service name](#service-name) + - [Service name](#service-name) - [Client attributes](#client-attributes) - [Server attributes](#server-attributes) - [Events](#events) @@ -79,14 +78,30 @@ Examples of span names: `MyServiceReference.ICalculator/Add` reported by the client for .NET WCF calls - `MyServiceWithNoPackage/theMethod` -### Common attributes +### Service name - +On the server process receiving and handling the remote procedure call, the service name provided in `rpc.service` does not necessarily have to match the [`service.name`][] resource attribute. +One process can expose multiple RPC endpoints and thus have multiple RPC service names. From a deployment perspective, as expressed by the `service.*` resource attributes, it will be treated as one deployed service with one `service.name`. +Likewise, on clients sending RPC requests to a server, the service name provided in `rpc.service` does not have to match the [`peer.service`][] span attribute. + +As an example, given a process deployed as `QuoteService`, this would be the name that goes into the `service.name` resource attribute which applies to the entire process. +This process could expose two RPC endpoints, one called `CurrencyQuotes` (= `rpc.service`) with a method called `getMeanRate` (= `rpc.method`) and the other endpoint called `StockQuotes` (= `rpc.service`) with two methods `getCurrentBid` and `getLastClose` (= `rpc.method`). +In this example, spans representing client request should have their `peer.service` attribute set to `QuoteService` as well to match the server's `service.name` resource attribute. +Generally, a user SHOULD NOT set `peer.service` to a fully qualified RPC service name. + +[`service.name`]: /docs/resource/README.md#service +[`peer.service`]: /docs/general/attributes.md#general-remote-service-attributes + +### Client attributes + + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`rpc.system`](../attributes-registry/rpc.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`server.address`](../attributes-registry/server.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`server.port`](../attributes-registry/server.md) | int | Server port number. [2] | `80`; `8080`; `443` | `Conditionally Required` [3] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` If `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [4] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [5] | `ipv4`; `ipv6` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [6] | `exampleMethod` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -137,52 +152,70 @@ different processes could be listening on TCP port 12345 and UDP port 12345. | `ipv6` | IPv6 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -#### Service name - -On the server process receiving and handling the remote procedure call, the service name provided in `rpc.service` does not necessarily have to match the [`service.name`][] resource attribute. -One process can expose multiple RPC endpoints and thus have multiple RPC service names. From a deployment perspective, as expressed by the `service.*` resource attributes, it will be treated as one deployed service with one `service.name`. -Likewise, on clients sending RPC requests to a server, the service name provided in `rpc.service` does not have to match the [`peer.service`][] span attribute. - -As an example, given a process deployed as `QuoteService`, this would be the name that goes into the `service.name` resource attribute which applies to the entire process. -This process could expose two RPC endpoints, one called `CurrencyQuotes` (= `rpc.service`) with a method called `getMeanRate` (= `rpc.method`) and the other endpoint called `StockQuotes` (= `rpc.service`) with two methods `getCurrentBid` and `getLastClose` (= `rpc.method`). -In this example, spans representing client request should have their `peer.service` attribute set to `QuoteService` as well to match the server's `service.name` resource attribute. -Generally, a user SHOULD NOT set `peer.service` to a fully qualified RPC service name. - -[`service.name`]: /docs/resource/README.md#service -[`peer.service`]: /docs/general/attributes.md#general-remote-service-attributes - -### Client attributes +### Server attributes - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| +| [`rpc.system`](../attributes-registry/rpc.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](../attributes-registry/server.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [2] | `80`; `8080`; `443` | `Conditionally Required` [3] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`client.address`](../attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`client.port`](../attributes-registry/client.md) | int | Client port number. [5] | `65123` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` If `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | - +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [6] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [7] | `ipv4`; `ipv6` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [8] | `exampleMethod` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.service`](../attributes-registry/rpc.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [9] | `myservice.EchoService` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -### Server attributes +**[1]:** May contain server IP address, DNS name, or local socket name. When host component is an IP address, instrumentations SHOULD NOT do a reverse proxy lookup to obtain DNS name and SHOULD set `server.address` to the IP address provided in the host component. - -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | -|---|---|---|---|---|---| -| [`client.address`](../attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`client.port`](../attributes-registry/client.md) | int | Client port number. [2] | `65123` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` If `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +**[2]:** 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. -**[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. +**[3]:** if the port is supported by the network transport used for communication. + +**[4]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. -**[2]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. +**[5]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. -**[3]:** The value SHOULD be normalized to lowercase. +**[6]:** The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport. For example different processes could be listening on TCP port 12345 and UDP port 12345. -**[4]:** The value SHOULD be normalized to lowercase. +**[7]:** The value SHOULD be normalized to lowercase. + +**[8]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). + +**[9]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). + +`rpc.system` 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 | +|---|---|---| +| `grpc` | gRPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `java_rmi` | Java RMI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dotnet_wcf` | .NET WCF | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `apache_dubbo` | Apache Dubbo | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `connect_rpc` | Connect RPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`network.transport` 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 | +|---|---|---| +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`network.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 | +|---|---|---| +| `ipv4` | IPv4 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `ipv6` | IPv6 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ### Events From d1a2d487c1951deecaa39552520a8d4060a59b47 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 24 Apr 2024 10:32:38 -0700 Subject: [PATCH 17/20] Move .NET-specific attributes to the registry (#943) --- .github/CODEOWNERS | 10 +- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 2 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 2 + docs/attributes-registry/aspnetcore.md | 46 ++++++++ docs/attributes-registry/signalr.md | 32 ++++++ docs/dotnet/dotnet-aspnetcore-metrics.md | 22 ++-- docs/dotnet/dotnet-signalr-metrics.md | 8 +- model/metrics/dotnet/dotnet-aspnetcore.yaml | 111 +++----------------- model/metrics/dotnet/dotnet-signalr.yaml | 43 -------- model/registry/aspnetcore.yaml | 90 ++++++++++++++++ model/registry/signalr.yaml | 43 ++++++++ 12 files changed, 251 insertions(+), 160 deletions(-) create mode 100644 docs/attributes-registry/aspnetcore.md create mode 100644 docs/attributes-registry/signalr.md create mode 100644 model/registry/aspnetcore.yaml create mode 100644 model/registry/signalr.yaml diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 185fedbfdb..0b1b2e4672 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -76,11 +76,15 @@ # .NET semantic conventions approvers /model/metrics/dotnet/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers -/docs/dotnet/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers +/model/registry/aspnetcore.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers +/model/registry/signalr.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers +/docs/dotnet/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers +/docs/attributes-registry/aspnetcore.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers +/docs/attributes-registry/signalr.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers # Gen-AI semantic conventions approvers -/model/registry/gen-ai.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers -/model/metrics/gen-ai.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers +/model/registry/gen-ai.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers +/model/metrics/gen-ai.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers /model/trace/gen-ai.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers /docs/gen-ai/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers /docs/attributes-registry/llm.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 896738c60c..32e7e1299c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -20,6 +20,7 @@ body: # DO NOT manually edit it. # Start semconv area list - area:android + - area:aspnetcore - area:aws - area:browser - area:client @@ -60,6 +61,7 @@ body: - area:server - area:service - area:session + - area:signalr - area:source - area:system - area:telemetry diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index ca2933bc38..b800c0e341 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -13,6 +13,7 @@ body: # DO NOT manually edit it. # Start semconv area list - area:android + - area:aspnetcore - area:aws - area:browser - area:client @@ -53,6 +54,7 @@ body: - area:server - area:service - area:session + - area:signalr - area:source - area:system - area:telemetry diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index 1c1afe1779..08421ab61d 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -22,6 +22,7 @@ body: # DO NOT manually edit it. # Start semconv area list - area:android + - area:aspnetcore - area:aws - area:browser - area:client @@ -62,6 +63,7 @@ body: - area:server - area:service - area:session + - area:signalr - area:source - area:system - area:telemetry diff --git a/docs/attributes-registry/aspnetcore.md b/docs/attributes-registry/aspnetcore.md new file mode 100644 index 0000000000..533eae5635 --- /dev/null +++ b/docs/attributes-registry/aspnetcore.md @@ -0,0 +1,46 @@ +# ASP.NET Core + + + +- [ASP.NET Core Attributes](#aspnet-core-attributes) + + + +## ASP.NET Core Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `aspnetcore.rate_limiting.result` | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aspnetcore.diagnostics.handler.type` | string | Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) implementation that handled the exception. | `Contoso.MyHandler` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aspnetcore.diagnostics.exception.result` | string | ASP.NET Core exception middleware handling result | `handled`; `unhandled` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aspnetcore.request.is_unhandled` | boolean | Flag indicating if request was handled by the application pipeline. | `True` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aspnetcore.routing.is_fallback` | boolean | A value that indicates whether the matched route is a fallback route. | `True` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aspnetcore.routing.match_status` | string | Match result - success or failure | `success`; `failure` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`aspnetcore.rate_limiting.result` 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 | +|---|---|---| +| `acquired` | Lease was acquired | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `endpoint_limiter` | Lease request was rejected by the endpoint limiter | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `global_limiter` | Lease request was rejected by the global limiter | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `request_canceled` | Lease request was canceled | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`aspnetcore.diagnostics.exception.result` MUST be one of the following: + +| Value | Description | Stability | +|---|---|---| +| `handled` | Exception was handled by the exception handling middleware. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unhandled` | Exception was not handled by the exception handling middleware. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `skipped` | Exception handling was skipped because the response had started. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aborted` | Exception handling didn't run because the request was aborted. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`aspnetcore.routing.match_status` 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 | +|---|---|---| +| `success` | Match succeeded | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `failure` | Match failed | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + \ No newline at end of file diff --git a/docs/attributes-registry/signalr.md b/docs/attributes-registry/signalr.md new file mode 100644 index 0000000000..ba2e9e0b7a --- /dev/null +++ b/docs/attributes-registry/signalr.md @@ -0,0 +1,32 @@ +# ASP.NET Core + + + +- [SignalR Attributes](#signalr-attributes) + + + +## SignalR Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `signalr.connection.status` | string | SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `signalr.transport` | string | [SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`signalr.connection.status` MUST be one of the following: + +| Value | Description | Stability | +|---|---|---| +| `normal_closure` | The connection was closed normally. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `timeout` | The connection was closed due to a timeout. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `app_shutdown` | The connection was closed because the app is shutting down. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`signalr.transport` 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 | +|---|---|---| +| `server_sent_events` | ServerSentEvents protocol | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `long_polling` | LongPolling protocol | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `web_sockets` | WebSockets protocol | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + \ No newline at end of file diff --git a/docs/dotnet/dotnet-aspnetcore-metrics.md b/docs/dotnet/dotnet-aspnetcore-metrics.md index edcd0615ef..772d698a1d 100644 --- a/docs/dotnet/dotnet-aspnetcore-metrics.md +++ b/docs/dotnet/dotnet-aspnetcore-metrics.md @@ -43,8 +43,8 @@ All routing metrics are reported by the `Microsoft.AspNetCore.Routing` meter. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aspnetcore.routing.match_status` | string | Match result - success or failure | `success`; `failure` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `aspnetcore.routing.is_fallback` | boolean | A value that indicates whether the matched route is a fallback route. | `True` | `Conditionally Required` if and only if a route was successfully matched. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.routing.match_status`](../attributes-registry/aspnetcore.md) | string | Match result - success or failure | `success`; `failure` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.routing.is_fallback`](../attributes-registry/aspnetcore.md) | boolean | A value that indicates whether the matched route is a fallback route. | `True` | `Conditionally Required` if and only if a route was successfully matched. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [1] | `/users/:userID?`; `{controller}/{action}/{id?}` | `Conditionally Required` if and only if a route was successfully matched. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. @@ -75,9 +75,9 @@ Exceptions Metric is reported by the `Microsoft.AspNetCore.Diagnostics` meter. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aspnetcore.diagnostics.exception.result` | string | ASP.NET Core exception middleware handling result | `handled`; `unhandled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.diagnostics.exception.result`](../attributes-registry/aspnetcore.md) | string | ASP.NET Core exception middleware handling result | `handled`; `unhandled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`error.type`](../attributes-registry/error.md) | string | The full name of exception type. [1] | `System.OperationCanceledException`; `Contoso.MyException` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `aspnetcore.diagnostics.handler.type` | string | Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) implementation that handled the exception. | `Contoso.MyHandler` | `Conditionally Required` [2] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.diagnostics.handler.type`](../attributes-registry/aspnetcore.md) | string | Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) implementation that handled the exception. | `Contoso.MyHandler` | `Conditionally Required` [2] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. @@ -134,7 +134,7 @@ All rate-limiting metrics are reported by the `Microsoft.AspNetCore.RateLimiting | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.rate_limiting.policy`](../attributes-registry/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** if the matched endpoint for the request had a rate-limiting policy. @@ -156,7 +156,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.rate_limiting.policy`](../attributes-registry/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** if the matched endpoint for the request had a rate-limiting policy. @@ -174,7 +174,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.rate_limiting.policy`](../attributes-registry/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** if the matched endpoint for the request had a rate-limiting policy. @@ -196,8 +196,8 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aspnetcore.rate_limiting.result` | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.rate_limiting.result`](../attributes-registry/aspnetcore.md) | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.rate_limiting.policy`](../attributes-registry/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** if the matched endpoint for the request had a rate-limiting policy. @@ -229,8 +229,8 @@ Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aspnetcore.rate_limiting.result` | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.rate_limiting.result`](../attributes-registry/aspnetcore.md) | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.rate_limiting.policy`](../attributes-registry/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** if the matched endpoint for the request had a rate-limiting policy. diff --git a/docs/dotnet/dotnet-signalr-metrics.md b/docs/dotnet/dotnet-signalr-metrics.md index f2c5b73257..1960b681a1 100644 --- a/docs/dotnet/dotnet-signalr-metrics.md +++ b/docs/dotnet/dotnet-signalr-metrics.md @@ -32,8 +32,8 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `signalr.connection.status` | string | SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `signalr.transport` | string | [SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`signalr.connection.status`](../attributes-registry/signalr.md) | string | SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`signalr.transport`](../attributes-registry/signalr.md) | string | [SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `signalr.connection.status` MUST be one of the following: @@ -65,8 +65,8 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `signalr.connection.status` | string | SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `signalr.transport` | string | [SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`signalr.connection.status`](../attributes-registry/signalr.md) | string | SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`signalr.transport`](../attributes-registry/signalr.md) | string | [SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `signalr.connection.status` MUST be one of the following: diff --git a/model/metrics/dotnet/dotnet-aspnetcore.yaml b/model/metrics/dotnet/dotnet-aspnetcore.yaml index da851f57fb..fd0c2c4d78 100644 --- a/model/metrics/dotnet/dotnet-aspnetcore.yaml +++ b/model/metrics/dotnet/dotnet-aspnetcore.yaml @@ -1,62 +1,11 @@ groups: - - id: aspnetcore - prefix: aspnetcore + - id: aspnetcore.common.rate_limiting.metrics.attributes type: attribute_group - brief: ASP.NET Core attributes + brief: Common ASP.NET Core rate-limiting metrics attributes attributes: - - id: rate_limiting.policy - type: string - brief: Rate limiting policy name. - stability: stable - examples: ["fixed", "sliding", "token"] + - ref: aspnetcore.rate_limiting.policy requirement_level: conditionally_required: if the matched endpoint for the request had a rate-limiting policy. - - id: rate_limiting.result - type: - allow_custom_values: true - members: - - id: acquired - value: 'acquired' - brief: "Lease was acquired" - stability: stable - - id: endpoint_limiter - value: 'endpoint_limiter' - brief: "Lease request was rejected by the endpoint limiter" - stability: stable - - id: global_limiter - value: 'global_limiter' - brief: "Lease request was rejected by the global limiter" - stability: stable - - id: request_canceled - value: 'request_canceled' - brief: "Lease request was canceled" - stability: stable - stability: stable - brief: Rate-limiting result, shows whether the lease was acquired or contains a rejection reason - examples: ["acquired", "request_canceled"] - requirement_level: required - - id: routing.is_fallback - type: boolean - stability: stable - brief: A value that indicates whether the matched route is a fallback route. - examples: [true] - requirement_level: - conditionally_required: If and only if a route was successfully matched. - - id: diagnostics.handler.type - type: string - stability: stable - brief: Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) - implementation that handled the exception. - examples: ["Contoso.MyHandler"] - requirement_level: - conditionally_required: if and only if the exception was handled by this handler. - - id: request.is_unhandled - type: boolean - stability: stable - brief: Flag indicating if request was handled by the application pipeline. - examples: [true] - requirement_level: - conditionally_required: if and only if the request was not handled. # routing - id: metric.aspnetcore.routing.match_attempts @@ -75,22 +24,8 @@ groups: - ref: aspnetcore.routing.is_fallback requirement_level: conditionally_required: if and only if a route was successfully matched. - - id: aspnetcore.routing.match_status - type: - allow_custom_values: true - members: - - id: success - value: 'success' - brief: 'Match succeeded' - stability: stable - - id: failure - value: 'failure' - brief: 'Match failed' - stability: stable - stability: stable + - ref: aspnetcore.routing.match_status requirement_level: required - brief: Match result - success or failure - examples: ["success", "failure"] # diagnostics - id: metric.aspnetcore.diagnostics.exceptions @@ -108,29 +43,8 @@ groups: examples: ['System.OperationCanceledException', 'Contoso.MyException'] requirement_level: required - ref: aspnetcore.diagnostics.handler.type - - id: aspnetcore.diagnostics.exception.result - type: - members: - - id: handled - value: 'handled' - brief: "Exception was handled by the exception handling middleware." - stability: stable - - id: unhandled - value: 'unhandled' - brief: "Exception was not handled by the exception handling middleware." - stability: stable - - id: skipped - value: 'skipped' - brief: "Exception handling was skipped because the response had started." - stability: stable - - id: aborted - value: 'aborted' - brief: "Exception handling didn't run because the request was aborted." - stability: stable - stability: stable + - ref: aspnetcore.diagnostics.exception.result requirement_level: required - brief: ASP.NET Core exception middleware handling result - examples: ["handled", "unhandled"] # rate_limiting - id: metric.aspnetcore.rate_limiting.active_request_leases @@ -142,8 +56,7 @@ groups: unit: "{request}" note: | Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 - attributes: - - ref: aspnetcore.rate_limiting.policy + extends: aspnetcore.common.rate_limiting.metrics.attributes - id: metric.aspnetcore.rate_limiting.request_lease.duration type: metric @@ -154,8 +67,7 @@ groups: unit: "s" note: | Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 - attributes: - - ref: aspnetcore.rate_limiting.policy + extends: aspnetcore.common.rate_limiting.metrics.attributes - id: metric.aspnetcore.rate_limiting.request.time_in_queue type: metric @@ -166,9 +78,10 @@ groups: unit: "s" note: | Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 + extends: aspnetcore.common.rate_limiting.metrics.attributes attributes: - - ref: aspnetcore.rate_limiting.policy - ref: aspnetcore.rate_limiting.result + requirement_level: required - id: metric.aspnetcore.rate_limiting.queued_requests type: metric @@ -179,8 +92,7 @@ groups: unit: "{request}" note: | Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 - attributes: - - ref: aspnetcore.rate_limiting.policy + extends: aspnetcore.common.rate_limiting.metrics.attributes - id: metric.aspnetcore.rate_limiting.requests type: metric @@ -196,6 +108,7 @@ groups: * Canceled while waiting for the lease. Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 + extends: aspnetcore.common.rate_limiting.metrics.attributes attributes: - - ref: aspnetcore.rate_limiting.policy - ref: aspnetcore.rate_limiting.result + requirement_level: required diff --git a/model/metrics/dotnet/dotnet-signalr.yaml b/model/metrics/dotnet/dotnet-signalr.yaml index e6233fc3cd..f91690e925 100644 --- a/model/metrics/dotnet/dotnet-signalr.yaml +++ b/model/metrics/dotnet/dotnet-signalr.yaml @@ -1,47 +1,4 @@ groups: - - id: signalr.common_attributes - prefix: signalr - type: attribute_group - brief: SignalR attributes - attributes: - - id: connection.status - type: - members: - - id: normal_closure - value: 'normal_closure' - brief: "The connection was closed normally." - stability: stable - - id: timeout - value: 'timeout' - brief: "The connection was closed due to a timeout." - stability: stable - - id: app_shutdown - value: 'app_shutdown' - brief: "The connection was closed because the app is shutting down." - stability: stable - stability: stable - brief: SignalR HTTP connection closure status. - examples: ["app_shutdown", "timeout"] - - id: transport - brief: "[SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md)" - type: - allow_custom_values: true - members: - - id: server_sent_events - value: 'server_sent_events' - brief: "ServerSentEvents protocol" - stability: stable - - id: long_polling - value: 'long_polling' - brief: "LongPolling protocol" - stability: stable - - id: web_sockets - value: 'web_sockets' - brief: "WebSockets protocol" - stability: stable - stability: stable - examples: ["web_sockets", "long_polling"] - - id: metric.signalr.server.connection.duration type: metric metric_name: signalr.server.connection.duration diff --git a/model/registry/aspnetcore.yaml b/model/registry/aspnetcore.yaml new file mode 100644 index 0000000000..0c93fc1aee --- /dev/null +++ b/model/registry/aspnetcore.yaml @@ -0,0 +1,90 @@ +groups: + - id: registry.aspnetcore + prefix: aspnetcore + type: attribute_group + brief: ASP.NET Core attributes + attributes: + - id: rate_limiting.policy + type: string + brief: Rate limiting policy name. + stability: stable + examples: ["fixed", "sliding", "token"] + - id: rate_limiting.result + type: + allow_custom_values: true + members: + - id: acquired + value: 'acquired' + brief: "Lease was acquired" + stability: stable + - id: endpoint_limiter + value: 'endpoint_limiter' + brief: "Lease request was rejected by the endpoint limiter" + stability: stable + - id: global_limiter + value: 'global_limiter' + brief: "Lease request was rejected by the global limiter" + stability: stable + - id: request_canceled + value: 'request_canceled' + brief: "Lease request was canceled" + stability: stable + stability: stable + brief: Rate-limiting result, shows whether the lease was acquired or contains a rejection reason + examples: ["acquired", "request_canceled"] + requirement_level: required + - id: routing.is_fallback + type: boolean + stability: stable + brief: A value that indicates whether the matched route is a fallback route. + examples: [true] + - id: diagnostics.handler.type + type: string + stability: stable + brief: Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) + implementation that handled the exception. + examples: ["Contoso.MyHandler"] + requirement_level: + conditionally_required: if and only if the exception was handled by this handler. + - id: request.is_unhandled + type: boolean + stability: stable + brief: Flag indicating if request was handled by the application pipeline. + examples: [true] + - id: routing.match_status + type: + allow_custom_values: true + members: + - id: success + value: 'success' + brief: 'Match succeeded' + stability: stable + - id: failure + value: 'failure' + brief: 'Match failed' + stability: stable + stability: stable + brief: Match result - success or failure + examples: ["success", "failure"] + - id: diagnostics.exception.result + type: + members: + - id: handled + value: 'handled' + brief: "Exception was handled by the exception handling middleware." + stability: stable + - id: unhandled + value: 'unhandled' + brief: "Exception was not handled by the exception handling middleware." + stability: stable + - id: skipped + value: 'skipped' + brief: "Exception handling was skipped because the response had started." + stability: stable + - id: aborted + value: 'aborted' + brief: "Exception handling didn't run because the request was aborted." + stability: stable + stability: stable + brief: ASP.NET Core exception middleware handling result + examples: ["handled", "unhandled"] diff --git a/model/registry/signalr.yaml b/model/registry/signalr.yaml new file mode 100644 index 0000000000..879034e7b3 --- /dev/null +++ b/model/registry/signalr.yaml @@ -0,0 +1,43 @@ +groups: + - id: registry.signalr + prefix: signalr + type: attribute_group + brief: SignalR attributes + attributes: + - id: connection.status + type: + members: + - id: normal_closure + value: 'normal_closure' + brief: "The connection was closed normally." + stability: stable + - id: timeout + value: 'timeout' + brief: "The connection was closed due to a timeout." + stability: stable + - id: app_shutdown + value: 'app_shutdown' + brief: "The connection was closed because the app is shutting down." + stability: stable + stability: stable + brief: SignalR HTTP connection closure status. + examples: ["app_shutdown", "timeout"] + - id: transport + brief: "[SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md)" + type: + allow_custom_values: true + members: + - id: server_sent_events + value: 'server_sent_events' + brief: "ServerSentEvents protocol" + stability: stable + - id: long_polling + value: 'long_polling' + brief: "LongPolling protocol" + stability: stable + - id: web_sockets + value: 'web_sockets' + brief: "WebSockets protocol" + stability: stable + stability: stable + examples: ["web_sockets", "long_polling"] From 3afe2871d14603e2ab107e0b82ac2f76809ccbf0 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 24 Apr 2024 11:53:24 -0700 Subject: [PATCH 18/20] Rename `db.name` to `db.namespace` and generalize it (#911) Co-authored-by: Trask Stalnaker --- .chloggen/911.yaml | 4 + docs/attributes-registry/db.md | 28 ++----- docs/database/cassandra.md | 4 +- docs/database/cosmosdb.md | 6 +- docs/database/database-metrics.md | 5 +- docs/database/database-spans.md | 12 +-- docs/database/hbase.md | 7 +- docs/database/mongodb.md | 15 ++-- docs/database/mssql.md | 15 ++-- docs/database/redis.md | 20 ++--- docs/database/sql.md | 33 ++++++-- model/db-common.yaml | 2 +- model/registry/db.yaml | 48 +++--------- model/registry/deprecated/db.yaml | 18 +++++ model/trace/database.yaml | 123 ++++++++++++++++++++++++++---- schema-next.yaml | 4 + 16 files changed, 226 insertions(+), 118 deletions(-) create mode 100644 .chloggen/911.yaml diff --git a/.chloggen/911.yaml b/.chloggen/911.yaml new file mode 100644 index 0000000000..b132291a62 --- /dev/null +++ b/.chloggen/911.yaml @@ -0,0 +1,4 @@ +change_type: breaking +component: db +note: Rename `db.name` and `db.redis.database_index` to `db.namespace`, deprecate `db.mssql.instance_name`. +issues: [ 885 ] diff --git a/docs/attributes-registry/db.md b/docs/attributes-registry/db.md index 57f2d98a46..da0022a380 100644 --- a/docs/attributes-registry/db.md +++ b/docs/attributes-registry/db.md @@ -9,8 +9,6 @@ - [Cassandra Attributes](#cassandra-attributes) - [CosmosDB Attributes](#cosmosdb-attributes) - [Elasticsearch Attributes](#elasticsearch-attributes) -- [MSSQL Attributes](#mssql-attributes) -- [Redis Attributes](#redis-attributes) - [Deprecated DB Attributes](#deprecated-db-attributes) - [Deprecated DB Metrics Attributes](#deprecated-db-metrics-attributes) @@ -25,7 +23,7 @@ | `db.client.connections.state` | string | The state of a connection in the pool | `idle` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.collection.name` | string | The name of a collection (table, container) within the database. [1] | `public.users`; `customers` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.instance.id` | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.name` | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [2] | `customers`; `main` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.namespace` | string | The name of the database, fully qualified within the server address and port. [2] | `customers`; `test.users` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.operation.name` | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.query.parameter.` | string | The query parameters used in `db.query.text`, with `` being the parameter name, and the attribute value being the parameter value. [3] | `someval`; `55` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.query.text` | string | The database query being executed. | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -33,7 +31,8 @@ **[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. -**[2]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). +**[2]:** If a database system has multiple namespace components, they SHOULD be concatenated (potentially using database system specific conventions) from most general to most specific namespace component, and more specific namespaces SHOULD NOT be captured without the more general namespaces, to ensure that "startswith" queries for the more general namespaces will be valid. +Semantic conventions for individual database systems SHOULD document what `db.namespace` means in the context of that system. **[3]:** Query parameters should only be captured when `db.query.text` is parameterized with placeholders. If a parameter has no name and instead is referenced only by index, then `` SHOULD be the 0-based index. @@ -184,24 +183,6 @@ If a parameter has no name and instead is referenced only by index, then `` **[1]:** Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names. -## MSSQL Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. [1] | `MSSQLSERVER` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -**[1]:** If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). - - -## Redis Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `db.redis.database_index` | int | The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute. | `0`; `1`; `15` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - - ## Deprecated DB Attributes @@ -213,7 +194,10 @@ If a parameter has no name and instead is referenced only by index, then `` | `db.elasticsearch.node.name` | string | Deprecated, use `db.instance.id` instead. | `instance-0000000001` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.instance.id`. | | `db.jdbc.driver_classname` | string | Removed, no replacement at this time. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed as not used. | | `db.mongodb.collection` | string | Deprecated, use `db.collection.name` instead. | `mytable` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.collection.name`. | +| `db.mssql.instance_name` | string | Deprecated, SQL Server instance is now populated as a part of `db.namespace` attribute. | `MSSQLSERVER` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, no replacement at this time. | +| `db.name` | string | Deprecated, use `db.namespace` instead. | `customers`; `main` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.namespace`. | | `db.operation` | string | Deprecated, use `db.operation.name` instead. | `findAndModify`; `HMSET`; `SELECT` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.operation.name`. | +| `db.redis.database_index` | int | Deprecated, use `db.namespace` instead. | `0`; `1`; `15` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.namespace`. | | `db.sql.table` | string | Deprecated, use `db.collection.name` instead. | `mytable` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.collection.name`. | | `db.statement` | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.query.text`. | | `db.user` | string | Deprecated, no replacement at this time. | `readonly_user`; `reporting_user` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
No replacement at this time. | diff --git a/docs/database/cassandra.md b/docs/database/cassandra.md index b726721e92..52033e0adf 100644 --- a/docs/database/cassandra.md +++ b/docs/database/cassandra.md @@ -18,7 +18,7 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`db.collection.name`](../attributes-registry/db.md) | string | The name of the Cassandra table that the operation is acting upon. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.name`](../attributes-registry/db.md) | string | The keyspace name in Cassandra. [3] | `mykeyspace` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](../attributes-registry/db.md) | string | The Cassandra keyspace name. [3] | `mykeyspace` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.cassandra.consistency_level`](../attributes-registry/db.md) | string | The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). | `all` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.cassandra.coordinator.dc`](../attributes-registry/db.md) | string | The data center of the coordinating node for a query. | `us-west-2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.cassandra.coordinator.id`](../attributes-registry/db.md) | string | The ID of the coordinating node for a query. | `be13faa2-8574-4d71-926d-27f16cf8a7af` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -32,7 +32,7 @@ described on this page. **[2]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.collection.name`, then it SHOULD be the first collection name found in the query. -**[3]:** For Cassandra the `db.name` should be set to the Cassandra keyspace name. +**[3]:** For commands that switch the keyspace, this SHOULD be set to the target keyspace (even if the command fails). **[4]:** If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. diff --git a/docs/database/cosmosdb.md b/docs/database/cosmosdb.md index f6a32606fa..4a7c63d328 100644 --- a/docs/database/cosmosdb.md +++ b/docs/database/cosmosdb.md @@ -79,14 +79,14 @@ In addition to Cosmos DB attributes, all spans include | `kind` | `"internal"` | | `az.namespace` | `"Microsoft.DocumentDB"` | | `db.system` | `"cosmosdb"` | -| `db.name` | `"database name"` | +| `db.collection.name` | `"orders"` | +| `db.namespace` | `"ShopDb"` | | `db.operation.name` | `"ReadItemsAsync"` | -| `server.address` | `"account.documents.azure.com"` | +| `server.address` | `"account.documents.azure.com"` | | `db.cosmosdb.client_id` | `3ba4827d-4422-483f-b59f-85b74211c11d` | | `db.cosmosdb.operation_type` | `Read` | | `user_agent.original` | `cosmos-netstandard-sdk/3.23.0\|3.23.1\|1\|X64\|Linux 5.4.0-1098-azure 104 18\|.NET Core 3.1.32\|S\|` | | `db.cosmosdb.connection_mode` | `"Direct"` | -| `db.cosmosdb.container` | `"container name"` | | `db.cosmosdb.request_content_length` | `20` | | `db.cosmosdb.status_code` | `201` | | `db.cosmosdb.sub_status_code` | `0` | diff --git a/docs/database/database-metrics.md b/docs/database/database-metrics.md index ccf76a54b1..e8b648820b 100644 --- a/docs/database/database-metrics.md +++ b/docs/database/database-metrics.md @@ -62,7 +62,7 @@ of `[ 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10 ]`. |---|---|---|---|---|---| | [`db.system`](../attributes-registry/db.md) | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.collection.name`](../attributes-registry/db.md) | string | The name of a collection (table, container) within the database. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.name`](../attributes-registry/db.md) | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [3] | `customers`; `main` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](../attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. [3] | `customers`; `test.users` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`server.port`](../attributes-registry/server.md) | int | Server port number. [5] | `80`; `8080`; `443` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | `Recommended` If different from the `server.address` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -74,7 +74,8 @@ of `[ 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10 ]`. **[2]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.collection.name`, then it SHOULD be the first collection name found in the query. -**[3]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). +**[3]:** If a database system has multiple namespace components, they SHOULD be concatenated (potentially using database system specific conventions) from most general to most specific namespace component, and more specific namespaces SHOULD NOT be captured without the more general namespaces, to ensure that "startswith" queries for the more general namespaces will be valid. +Semantic conventions for individual database systems SHOULD document what `db.namespace` means in the context of that system. **[4]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 15a6080f17..80492ca794 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -55,11 +55,12 @@ The **span name** SHOULD be set to a low cardinality value representing the stat It MAY be a stored procedure name (without arguments), DB statement without variable arguments, operation name, etc. Since SQL statements may have very high cardinality even without arguments, SQL spans SHOULD be named the following way, unless the statement is known to be of low cardinality: -` .`, provided that `db.operation.name` and `db.collection.name` are available. -If `db.collection.name` is not available due to its semantics, the span SHOULD be named ` `. +` .`, provided that `db.operation.name` and `db.collection.name` are available. +If `db.collection.name` is not available due to its semantics, the span SHOULD be named ` `. + It is not recommended to attempt any client-side parsing of `db.query.text` just to get these properties, they should only be used if the library being instrumented already provides them. -When it's otherwise impossible to get any meaningful span name, `db.name` or the tech-specific database name MAY be used. +When it's otherwise impossible to get any meaningful span name, `db.namespace` or the tech-specific database name MAY be used. Span that describes database call SHOULD cover the duration of the corresponding call as if it was observed by the caller (such as client application). For example, if a transient issue happened and was retried within this database call, the corresponding span should cover the duration of the logical operation @@ -74,7 +75,7 @@ These attributes will usually be the same for all operations performed over the |---|---|---|---|---|---| | [`db.system`](../attributes-registry/db.md) | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.collection.name`](../attributes-registry/db.md) | string | The name of a collection (table, container) within the database. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.name`](../attributes-registry/db.md) | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [3] | `customers`; `main` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](../attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. [3] | `customers`; `test.users` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`server.port`](../attributes-registry/server.md) | int | Server port number. [5] | `80`; `8080`; `443` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | `Recommended` If different from the `server.address` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -88,7 +89,8 @@ These attributes will usually be the same for all operations performed over the **[2]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.collection.name`, then it SHOULD be the first collection name found in the query. -**[3]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). +**[3]:** If a database system has multiple namespace components, they SHOULD be concatenated (potentially using database system specific conventions) from most general to most specific namespace component, and more specific namespaces SHOULD NOT be captured without the more general namespaces, to ensure that "startswith" queries for the more general namespaces will be valid. +Semantic conventions for individual database systems SHOULD document what `db.namespace` means in the context of that system. **[4]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. diff --git a/docs/database/hbase.md b/docs/database/hbase.md index 290525590d..5bd4955583 100644 --- a/docs/database/hbase.md +++ b/docs/database/hbase.md @@ -17,9 +17,12 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.name`](../attributes-registry/db.md) | string | The HBase namespace. [1] | `mynamespace` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.collection.name`](../attributes-registry/db.md) | string | The HBase table name. [1] | `mytable`; `ns:table` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](../attributes-registry/db.md) | string | The HBase namespace. [2] | `mynamespace` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -**[1]:** For HBase the `db.name` should be set to the HBase namespace. +**[1]:** If table name includes the namespace, the `db.collection.name` SHOULD be set to the full table name. + +**[2]:** When performing table-related operations, the instrumentations SHOULD extract the namespace from the table name according to the [HBase table naming conventions](https://hbase.apache.org/book.html#namespace_creation). If namespace is not provided, instrumentation SHOULD set `db.namespace` value to `default`. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/mongodb.md b/docs/database/mongodb.md index be34d3430a..bc4a08d7b5 100644 --- a/docs/database/mongodb.md +++ b/docs/database/mongodb.md @@ -17,14 +17,17 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.collection.name`](../attributes-registry/db.md) | string | The MongoDB collection being accessed within the database stated in `db.name`. [1] | `public.users`; `customers` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the command being executed. [2] | `findAndModify`; `getMore`; `update` | `Conditionally Required` [3] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.collection.name`](../attributes-registry/db.md) | string | The MongoDB collection being accessed within the database stated in `db.namespace`. [1] | `public.users`; `customers` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](../attributes-registry/db.md) | string | The MongoDB database name. [2] | `customers`; `test.users` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the command being executed. [3] | `findAndModify`; `getMore`; `update` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. -**[2]:** See [MongoDB database commands](https://www.mongodb.com/docs/manual/reference/command/). +**[2]:** -**[3]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. +**[3]:** See [MongoDB database commands](https://www.mongodb.com/docs/manual/reference/command/). + +**[4]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. ## Example @@ -38,9 +41,9 @@ described on this page. | `network.peer.address` | `"192.0.2.14"` | | `network.peer.port` | `27017` | | `network.transport` | `"tcp"` | -| `db.name` | `"shopDb"` | +| `db.collection.name` | `"products"` | +| `db.namespace` | `"shopDb"` | | `db.query.text` | not set | | `db.operation.name` | `"findAndModify"` | -| `db.mongodb.collection` | `"products"` | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/mssql.md b/docs/database/mssql.md index e4c0774857..6a0e7766a3 100644 --- a/docs/database/mssql.md +++ b/docs/database/mssql.md @@ -17,20 +17,21 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.collection.name`](../attributes-registry/db.md) | string | The name of the SQL table that the operation is acting upon. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. [3] | `SELECT`; `INSERT`; `UPDATE`; `DELETE`; `CREATE`; `mystoredproc` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.mssql.instance_name`](../attributes-registry/db.md) | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. [5] | `MSSQLSERVER` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.collection.name`](../attributes-registry/db.md) | string | The name of the SQL table that the operation is acting upon. [1] | `users`; `dbo.products` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](../attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. [3] | `instance1.products`; `customers` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. [4] | `SELECT`; `INSERT`; `UPDATE`; `DELETE`; `CREATE`; `mystoredproc` | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. **[2]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.collection.name`, then it SHOULD be the first collection name found in the query. -**[3]:** This SHOULD be the SQL command such as `SELECT`, `INSERT`, `UPDATE`, `CREATE`, `DROP`. -In the case of `EXEC`, this SHOULD be the stored procedure name that is being executed. +**[3]:** When connecting to a default instance, `db.namespace` SHOULD be set to the name of the database. When connecting to a [named instance](https://learn.microsoft.com/sql/connect/jdbc/building-the-connection-url#named-and-multiple-sql-server-instances), `db.namespace` SHOULD be set to the combination of instance and database name following the `{instance_name}.{database_name}` pattern. +For commands that switch the database, this SHOULD be set to the target database (even if the command fails). -**[4]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. +**[4]:** This SHOULD be the SQL command such as `SELECT`, `INSERT`, `UPDATE`, `CREATE`, `DROP`. +In the case of `EXEC`, this SHOULD be the stored procedure name that is being executed. -**[5]:** If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). +**[5]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/redis.md b/docs/database/redis.md index 052c0a8048..116be54221 100644 --- a/docs/database/redis.md +++ b/docs/database/redis.md @@ -17,22 +17,25 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.redis.database_index`](../attributes-registry/db.md) | int | The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute. | `0`; `1`; `15` | `Conditionally Required` If other than the default database (`0`). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.query.text`](../attributes-registry/db.md) | string | The full syntax of the Redis CLI command. [1] | `HMSET myhash field1 'Hello' field2 'World'` | `Recommended` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [3] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.namespace`](../attributes-registry/db.md) | string | The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select). [1] | `0`; `1`; `15` | `Conditionally Required` If and only if it can be captured reliably. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.query.text`](../attributes-registry/db.md) | string | The full syntax of the Redis CLI command. [2] | `HMSET myhash field1 'Hello' field2 'World'` | `Recommended` [3] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [4] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** For **Redis**, the value provided for `db.query.text` SHOULD correspond to the syntax of the Redis CLI. If, for example, the [`HMSET` command](https://redis.io/commands/hmset) is invoked, `"HMSET myhash field1 'Hello' field2 'World'"` would be a suitable value for `db.query.text`. +**[1]:** The database index for current connection can be changed by the application dynamically. Instrumentations MAY use the initial database index provided in the connection string and keep track of the currently selected database to capture the `db.namespace`. +Instrumentations SHOULD NOT set this attribute if capturing it would require additional network calls to Redis. +For commands that switch the database, this SHOULD be set to the target database (even if the command fails). -**[2]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. +**[2]:** For **Redis**, the value provided for `db.query.text` SHOULD correspond to the syntax of the Redis CLI. If, for example, the [`HMSET` command](https://redis.io/commands/hmset) is invoked, `"HMSET myhash field1 'Hello' field2 'World'"` would be a suitable value for `db.query.text`. -**[3]:** If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. +**[3]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. + +**[4]:** If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. ## Example In this example, Redis is connected using a unix domain socket and therefore the connection string is left out. -Furthermore, `db.name` is not specified as there is no database name in Redis and `db.redis.database_index` is set instead. | Key | Value | |:--------------------------| :-------------------------------------------- | @@ -40,9 +43,8 @@ Furthermore, `db.name` is not specified as there is no database name in Redis an | `db.system` | `"redis"` | | `network.peer.address` | `"/tmp/redis.sock"` | | `network.transport` | `"unix"` | -| `db.name` | not set | +| `db.namespace` | `"15"` | | `db.query.text` | `"HMSET myhash field1 'Hello' field2 'World"` | | `db.operation.name` | not set | -| `db.redis.database_index` | `15` | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/sql.md b/docs/database/sql.md index dcd4d0ba2e..58cfbee159 100644 --- a/docs/database/sql.md +++ b/docs/database/sql.md @@ -15,17 +15,38 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.collection.name`](../attributes-registry/db.md) | string | The name of the SQL table that the operation is acting upon. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. [3] | `SELECT`; `INSERT`; `UPDATE`; `DELETE`; `CREATE`; `mystoredproc` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.collection.name`](../attributes-registry/db.md) | string | The name of the SQL table that the operation is acting upon. [1] | `users`; `dbo.products` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](../attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. [3] | `customers`; `test.users` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. [4] | `SELECT`; `INSERT`; `UPDATE`; `DELETE`; `CREATE`; `mystoredproc` | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. **[2]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.collection.name`, then it SHOULD be the first collection name found in the query. -**[3]:** This SHOULD be the SQL command such as `SELECT`, `INSERT`, `UPDATE`, `CREATE`, `DROP`. +**[3]:** If a database system has multiple namespace components, they SHOULD be concatenated +(potentially using database system specific conventions) from most general to most +specific namespace component, and more specific namespaces SHOULD NOT be captured without +the more general namespaces, to ensure that "startswith" queries for the more general namespaces will be valid. + +Unless specified by the system-specific semantic convention, the `db.namespace` attribute matches +the name of the database being accessed. + +The database name can usually be obtained with database driver API such as +[JDBC `Connection.getCatalog()`](https://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#getCatalog--) +or [.NET `SqlConnection.Database`](https://learn.microsoft.com/dotnet/api/system.data.sqlclient.sqlconnection.database). + +Some database drivers don't detect when the current database is changed (for example, with SQL `USE database` statement). +Instrumentations that parse SQL statements MAY use the database name provided +in the connection string and keep track of the currently selected database name. + +For commands that switch the database, this SHOULD be set to the target database (even if the command fails). + +If instrumentation cannot reliably determine the current database name, it SHOULD NOT set `db.namespace`. + +**[4]:** This SHOULD be the SQL command such as `SELECT`, `INSERT`, `UPDATE`, `CREATE`, `DROP`. In the case of `EXEC`, this SHOULD be the stored procedure name that is being executed. -**[4]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. +**[5]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. ## Example @@ -35,15 +56,15 @@ This is an example of attributes for a MySQL database span: | Key | Value | |:-----------------------| :----------------------------------------------------------- | | Span name | `"SELECT ShopDb.orders"` | +| `db.collection.name` | `"orders"` | +| `db.namespace` | `"ShopDb"` | | `db.system` | `"mysql"` | | `server.address` | `"shopdb.example.com"` | | `server.port` | `3306` | | `network.peer.address` | `"192.0.2.12"` | | `network.peer.port` | `3306` | | `network.transport` | `"tcp"` | -| `db.name` | `"ShopDb"` | | `db.query.text` | `"SELECT * FROM orders WHERE order_id = 'o4711'"` | | `db.operation.name` | `"SELECT"` | -| `db.collection.name` | `"orders"` | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/model/db-common.yaml b/model/db-common.yaml index fdefe67883..faca39e25f 100644 --- a/model/db-common.yaml +++ b/model/db-common.yaml @@ -3,7 +3,7 @@ groups: type: attribute_group brief: 'Database Client attributes' attributes: - - ref: db.name + - ref: db.namespace requirement_level: conditionally_required: If applicable. - ref: db.collection.name diff --git a/model/registry/db.yaml b/model/registry/db.yaml index 293ec073fb..eef192fe1d 100644 --- a/model/registry/db.yaml +++ b/model/registry/db.yaml @@ -13,19 +13,20 @@ groups: If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. examples: ['public.users', 'customers'] - - id: name + - id: namespace type: string stability: experimental brief: > - This attribute is used to report the name of the database being accessed. - For commands that switch the database, this should be set to the target database - (even if the command fails). + The name of the database, fully qualified within the server address and port. note: > - In some SQL databases, the database name to be used is called "schema name". - In case there are multiple layers that could be considered for database name - (e.g. Oracle instance name and schema name), - the database name to be used is the more specific layer (e.g. Oracle schema name). - examples: [ 'customers', 'main' ] + If a database system has multiple namespace components, they SHOULD be concatenated + (potentially using database system specific conventions) from most general to most + specific namespace component, and more specific namespaces SHOULD NOT be captured without + the more general namespaces, to ensure that "startswith" queries for the more general namespaces will be valid. + + Semantic conventions for individual database systems SHOULD document what `db.namespace` + means in the context of that system. + examples: [ 'customers', 'test.users' ] - id: operation.name type: string stability: experimental @@ -486,32 +487,3 @@ groups: reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names. examples: ['db.elasticsearch.path_parts.index=test-index', 'db.elasticsearch.path_parts.doc_id=123'] - - id: registry.db.mssql - prefix: db - type: attribute_group - brief: > - This group defines attributes for Microsoft SQL Server. - attributes: - - id: mssql.instance_name - type: string - stability: experimental - note: > - If setting a `db.mssql.instance_name`, `server.port` is no longer - required (but still recommended if non-standard). - brief: > - The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) - connecting to. This name is used to determine the port of a named instance. - examples: 'MSSQLSERVER' - - id: registry.db.redis - prefix: db - type: attribute_group - brief: > - This group defines attributes for Redis. - attributes: - - id: redis.database_index - type: int - stability: experimental - brief: > - The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. - To be used instead of the generic `db.name` attribute. - examples: [0, 1, 15] diff --git a/model/registry/deprecated/db.yaml b/model/registry/deprecated/db.yaml index de58225c67..8734714110 100644 --- a/model/registry/deprecated/db.yaml +++ b/model/registry/deprecated/db.yaml @@ -66,6 +66,24 @@ groups: brief: 'Deprecated, use `db.collection.name` instead.' deprecated: "Replaced by `db.collection.name`." examples: 'mytable' + - id: redis.database_index + type: int + stability: experimental + brief: 'Deprecated, use `db.namespace` instead.' + deprecated: "Replaced by `db.namespace`." + examples: [0, 1, 15] + - id: name + type: string + stability: experimental + brief: 'Deprecated, use `db.namespace` instead.' + deprecated: "Replaced by `db.namespace`." + examples: [ 'customers', 'main' ] + - id: mssql.instance_name + type: string + stability: experimental + brief: 'Deprecated, SQL Server instance is now populated as a part of `db.namespace` attribute.' + deprecated: 'Deprecated, no replacement at this time.' + examples: 'MSSQLSERVER' - id: registry.db.metrics.deprecated type: attribute_group diff --git a/model/trace/database.yaml b/model/trace/database.yaml index e0f6aee6c5..f3b59d5a08 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -4,12 +4,48 @@ groups: type: attribute_group brief: This group defines the attributes used to perform database client calls. attributes: + - ref: db.system + requirement_level: required - ref: db.query.text requirement_level: recommended: > SHOULD be collected by default only if there is sanitization that excludes sensitive information. - ref: db.query.parameter requirement_level: opt_in + - ref: db.operation.name + requirement_level: + conditionally_required: > + If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture + `db.operation.name`, then it SHOULD be the first operation name found in the query. + - ref: server.address + brief: > + Name of the database host. + - ref: server.port + requirement_level: + conditionally_required: If using a port other than the default port for this DBMS and if `server.address` is set. + - ref: db.instance.id + requirement_level: + recommended: If different from the `server.address` + - ref: db.collection.name + requirement_level: + conditionally_required: > + If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture + `db.collection.name`, then it SHOULD be the first collection name found in the query. + - ref: db.namespace + requirement_level: + conditionally_required: If available. + - ref: network.peer.address + brief: Peer address of the database node where the operation was performed. + requirement_level: + recommended: If applicable for this database system. + note: > + Semantic conventions for individual database systems SHOULD document whether `network.peer.*` attributes are applicable. + Network peer address and port are useful when the application interacts with individual database nodes directly. + + If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. + - ref: network.peer.port + requirement_level: + recommended: if and only if `network.peer.address` is set. - id: db.tech_specific.network.attributes type: attribute_group @@ -37,7 +73,15 @@ groups: brief: > Attributes for Microsoft SQL Server attributes: - - ref: db.mssql.instance_name + - ref: db.namespace + brief: The name of the database, fully qualified within the server address and port. + note: + When connecting to a default instance, `db.namespace` SHOULD be set to the name of + the database. When connecting to a [named instance](https://learn.microsoft.com/sql/connect/jdbc/building-the-connection-url#named-and-multiple-sql-server-instances), + `db.namespace` SHOULD be set to the combination of instance and database name following the `{instance_name}.{database_name}` pattern. + + For commands that switch the database, this SHOULD be set to the target database (even if the command fails). + examples: ["instance1.products", "customers"] tag: tech-specific - id: db.cassandra @@ -46,12 +90,11 @@ groups: brief: > Attributes for Cassandra attributes: - - ref: db.name - tag: tech-specific - brief: > - The keyspace name in Cassandra. + - ref: db.namespace + brief: The Cassandra keyspace name. + note: For commands that switch the keyspace, this SHOULD be set to the target keyspace (even if the command fails). examples: ["mykeyspace"] - note: For Cassandra the `db.name` should be set to the Cassandra keyspace name. + tag: tech-specific - ref: db.cassandra.page_size tag: tech-specific - ref: db.cassandra.consistency_level @@ -74,12 +117,24 @@ groups: brief: > Attributes for HBase attributes: - - ref: db.name - tag: tech-specific - brief: > - The HBase namespace. + - ref: db.namespace + brief: The HBase namespace. + requirement_level: + conditionally_required: If applicable. + note: > + When performing table-related operations, the instrumentations SHOULD extract the namespace from the table name according to + the [HBase table naming conventions](https://hbase.apache.org/book.html#namespace_creation). If namespace is not provided, + instrumentation SHOULD set `db.namespace` value to `default`. examples: ['mynamespace'] - note: For HBase the `db.name` should be set to the HBase namespace. + tag: tech-specific + - ref: db.collection.name + brief: The HBase table name. + requirement_level: + conditionally_required: If applicable. + note: > + If table name includes the namespace, the `db.collection.name` SHOULD be set to the full table name. + examples: ['mytable', 'ns:table'] + tag: tech-specific - id: db.couchdb type: span @@ -105,9 +160,20 @@ groups: brief: > Attributes for Redis attributes: - - ref: db.redis.database_index + - ref: db.namespace + brief: > + The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select). requirement_level: - conditionally_required: If other than the default database (`0`). + conditionally_required: If and only if it can be captured reliably. + note: > + The database index for current connection can be changed by the application dynamically. Instrumentations MAY use + the initial database index provided in the connection string and keep track of the currently selected + database to capture the `db.namespace`. + + Instrumentations SHOULD NOT set this attribute if capturing it would require additional network calls to Redis. + + For commands that switch the database, this SHOULD be set to the target database (even if the command fails). + examples: ["0", "1", "15"] tag: tech-specific - ref: db.query.text tag: tech-specific @@ -133,9 +199,14 @@ groups: tag: tech-specific - ref: db.collection.name brief: - The MongoDB collection being accessed within the database stated in `db.name`. + The MongoDB collection being accessed within the database stated in `db.namespace`. requirement_level: required tag: tech-specific + - ref: db.namespace + brief: The MongoDB database name. + note: | + + tag: tech-specific - id: db.elasticsearch type: span @@ -197,8 +268,30 @@ groups: tag: tech-specific - ref: db.collection.name brief: The name of the SQL table that the operation is acting upon. - tag: tech-specific + examples: ['users', 'dbo.products'] + tag: tech-specific + - ref: db.namespace + note: | + If a database system has multiple namespace components, they SHOULD be concatenated + (potentially using database system specific conventions) from most general to most + specific namespace component, and more specific namespaces SHOULD NOT be captured without + the more general namespaces, to ensure that "startswith" queries for the more general namespaces will be valid. + Unless specified by the system-specific semantic convention, the `db.namespace` attribute matches + the name of the database being accessed. + + The database name can usually be obtained with database driver API such as + [JDBC `Connection.getCatalog()`](https://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#getCatalog--) + or [.NET `SqlConnection.Database`](https://learn.microsoft.com/dotnet/api/system.data.sqlclient.sqlconnection.database). + + Some database drivers don't detect when the current database is changed (for example, with SQL `USE database` statement). + Instrumentations that parse SQL statements MAY use the database name provided + in the connection string and keep track of the currently selected database name. + + For commands that switch the database, this SHOULD be set to the target database (even if the command fails). + + If instrumentation cannot reliably determine the current database name, it SHOULD NOT set `db.namespace`. + tag: tech-specific - id: db.cosmosdb type: span extends: trace.db.common diff --git a/schema-next.yaml b/schema-next.yaml index 5fc05edea2..85bfa85d72 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -27,6 +27,10 @@ versions: 1.25.0: spans: changes: + # https://github.com/open-telemetry/semantic-conventions/pull/911 + - rename_attributes: + attribute_map: + db.name: db.namespace # https://github.com/open-telemetry/semantic-conventions/pull/870 - rename_attributes: attribute_map: From 387b74f8a78c56d513063828093ef64341cafffb Mon Sep 17 00:00:00 2001 From: Anna Levenberg Date: Wed, 24 Apr 2024 15:00:50 -0400 Subject: [PATCH 19/20] docs(messaging): add gcp_pubsub unary pull example (#634) Co-authored-by: Joao Grassi Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Co-authored-by: Liudmila Molkova --- .chloggen/634.yaml | 25 +++++++++ docs/attributes-registry/messaging.md | 3 + docs/messaging/gcp-pubsub.md | 80 ++++++++++++++++++++++++++- model/registry/messaging.yaml | 22 ++++++++ model/trace/messaging.yaml | 9 ++- 5 files changed, 136 insertions(+), 3 deletions(-) create mode 100644 .chloggen/634.yaml diff --git a/.chloggen/634.yaml b/.chloggen/634.yaml new file mode 100644 index 0000000000..16b837ff88 --- /dev/null +++ b/.chloggen/634.yaml @@ -0,0 +1,25 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: messaging + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: "Add a GCP Pub/Sub unary pull example and the new GCP messaging attributes: +- `messaging.gcp_pubsub.message.ack_deadline`, +- `messaging.gcp_pubsub.message.ack_id`, +- `messaging.gcp_pubsub.message.delivery_attempt`" + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [527] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/attributes-registry/messaging.md b/docs/attributes-registry/messaging.md index b41d340165..25bad90a56 100644 --- a/docs/attributes-registry/messaging.md +++ b/docs/attributes-registry/messaging.md @@ -87,6 +87,9 @@ size should be used. | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| +| `messaging.gcp_pubsub.message.ack_deadline` | int | The ack deadline in seconds set for the modify ack deadline request. | `10` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.gcp_pubsub.message.ack_id` | string | The ack id for a given message. | `ack_id` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.gcp_pubsub.message.delivery_attempt` | int | The delivery attempt for a given message. | `2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `messaging.gcp_pubsub.message.ordering_key` | string | The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. | `ordering_key` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/messaging/gcp-pubsub.md b/docs/messaging/gcp-pubsub.md index b586668d69..3ed71fdcf1 100644 --- a/docs/messaging/gcp-pubsub.md +++ b/docs/messaging/gcp-pubsub.md @@ -14,12 +14,28 @@ The Semantic Conventions for [Google Cloud Pub/Sub](https://cloud.google.com/pub For Google Cloud Pub/Sub, the following additional attributes are defined: - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`messaging.gcp_pubsub.message.ordering_key`](../attributes-registry/messaging.md) | string | The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. | `ordering_key` | `Conditionally Required` If the message type has an ordering key set. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.gcp_pubsub.message.ack_deadline`](../attributes-registry/messaging.md) | int | The ack deadline in seconds set for the modify ack deadline request. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.gcp_pubsub.message.ack_id`](../attributes-registry/messaging.md) | string | The ack id for a given message. | `ack_id` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.gcp_pubsub.message.delivery_attempt`](../attributes-registry/messaging.md) | int | The delivery attempt for a given message. | `2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +## Span names + +The span name SHOULD follow the [general messaging span name pattern](../messaging/gcp-pubsub.md): it SHOULD start with the messaging destination name (Topic/Subscription) and contain a low-cardinality name of an operation the span describes: + +- Spans for `settle` operations SHOULD follow the ` ack` or ` nack` pattern. +- Spans names for `publish` operations SHOULD follow the ` send` pattern. +- Spans for `create`, `receive`, and `publish` operations SHOULD follow the general ` ` pattern. + +In addition there are the following operations are GCP specific: + +- Spans that represents the time from after the message was received to when the message is acknowledged, negatively acknowledged, or expire (used by streaming pull) SHOULD follow the ` subscribe` pattern. +- Spans that represent extending the lease for a single message or batch of messages SHOULD follow the` modack` pattern. + ## Examples ### Asynchronous Batch Publish Example @@ -58,4 +74,64 @@ flowchart LR; | `messaging.message.envelope.size` | `1` | `1` | | | `messaging.system` | `"gcp_pubsub"` | `"gcp_pubsub"` | `"gcp_pubsub"` | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md +### Unary Pull Example + +```mermaid +flowchart TD; + subgraph CONSUMER + direction LR + R1[Receive m1] + SM1[Ack m1] + EM1[Modack m1] + end + subgraph PRODUCER + direction LR + CM1[Create m1] + PM1[Publish] + end + %% Link 0 + CM1-. link .-PM1; + %% Link 1 + CM1-. link .-R1; + %% Link 2 + R1-. link .-SM1; + %% Link 3 + R1-. link .-EM1; + + %% Style the node and corresponding link + %% Producer links and nodes + classDef producer fill:green + class PM1,CM1 producer + linkStyle 0 color:green,stroke:green + + %% Consumer links and nodes + classDef consumer fill:#49fcdc + class R1 consumer + linkStyle 1 color:#49fcdc,stroke:#49fcdc + + classDef ack fill:#577eb5 + class SM1 ack + linkStyle 2 color:#577eb5,stroke:#577eb5 + + classDef modack fill:#0560f2 + class EM1 modack + linkStyle 3 color:#0560f2,stroke:#0560f2 +``` + +| Field or Attribute | Span Create A | Span Publish A | Span Receive A | Span Modack A | Span Ack A | +|-|-|-|-|-|-| +| Span name | `T create` | `publish` | `S receive` | `S modack` |`S ack` | +| Parent | | | | | | +| Links | | Span Create A | Span Create A | Span Receive A | Span Receive A | +| SpanKind | `PRODUCER` | `PRODUCER` | `CONSUMER` |`CLIENT` |`CLIENT` | +| Status | `Ok` | `Ok` | `Ok` |`Ok` | `Ok` | +| `messaging.destination.name` | `"T"`| `"T"`| `"S"` | `"S"` |`"S"` | +| `messaging.system` | `"gcp_pubsub"` | `"gcp_pubsub"` | `"gcp_pubsub"` | `"gcp_pubsub"` | `"gcp_pubsub"` | +| `messaging.operation` | `"create"` | `"publish"` | `"receive"` | `"extend"` | `"settle"` | +| `messaging.message.id` | `"a1"` | | `"a1"` | | | +| `messaging.message.envelope.size` | `1` | `1` | `1` | | | +| `messaging.gcp_pubsub.message.ack_id` | | | | `"ack_id1"` |`"ack_id1"` | +| `messaging.gcp_pubsub.message.delivery_attempt` | | | | `0` | | +| `messaging.gcp_pubsub.message.ack_deadline` | | | | | `0` | + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/model/registry/messaging.yaml b/model/registry/messaging.yaml index 4a2c6a2714..f22f58f155 100644 --- a/model/registry/messaging.yaml +++ b/model/registry/messaging.yaml @@ -333,6 +333,28 @@ groups: brief: > The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. examples: 'ordering_key' + tag: tech-specific-gcp-pubsub + - id: gcp_pubsub.message.ack_id + type: string + stability: experimental + brief: > + The ack id for a given message. + examples: 'ack_id' + tag: tech-specific-gcp-pubsub + - id: gcp_pubsub.message.ack_deadline + type: int + stability: experimental + brief: > + The ack deadline in seconds set for the modify ack deadline request. + examples: 10 + tag: tech-specific-gcp-pubsub + - id: gcp_pubsub.message.delivery_attempt + type: int + stability: experimental + brief: > + The delivery attempt for a given message. + examples: 2 + tag: tech-specific-gcp-pubsub - id: registry.messaging.servicebus prefix: messaging type: attribute_group diff --git a/model/trace/messaging.yaml b/model/trace/messaging.yaml index f12a96b1df..542edec127 100644 --- a/model/trace/messaging.yaml +++ b/model/trace/messaging.yaml @@ -188,14 +188,21 @@ groups: tag: tech-specific - id: messaging.gcp_pubsub type: attribute_group + stability: experimental extends: messaging brief: > Attributes for Google Cloud Pub/Sub attributes: - ref: messaging.gcp_pubsub.message.ordering_key - tag: tech-specific + tag: tech-specific-gcp-pubsub requirement_level: conditionally_required: If the message type has an ordering key set. + - ref: messaging.gcp_pubsub.message.delivery_attempt + tag: tech-specific-gcp-pubsub + - ref: messaging.gcp_pubsub.message.ack_deadline + tag: tech-specific-gcp-pubsub + - ref: messaging.gcp_pubsub.message.ack_id + tag: tech-specific-gcp-pubsub - id: messaging.servicebus type: attribute_group extends: messaging From 4d80b4ce2b17c84856f39c73cef41ae54d087d32 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 24 Apr 2024 12:17:44 -0700 Subject: [PATCH 20/20] [chore] Disable link check for semconv pulls and issues (#962) --- .markdown_link_check_config.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.markdown_link_check_config.json b/.markdown_link_check_config.json index 8ee8073745..ede6fbc5eb 100644 --- a/.markdown_link_check_config.json +++ b/.markdown_link_check_config.json @@ -2,6 +2,9 @@ "ignorePatterns": [ { "pattern": "^https://github\\.com/open-telemetry/opentelemetry-specification/(issues|pull)" + }, + { + "pattern": "^https://github\\.com/open-telemetry/semantic-conventions/(issues|pull)" } ], "replacementPatterns": [