From 3b6ffe3e810e965d122c19fdcc07212a2ec854b7 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 20 Jun 2024 18:41:59 +0100 Subject: [PATCH 01/11] Define sampling relevant attributes for messaging client spans (#1169) Co-authored-by: Trask Stalnaker --- .chloggen/1169.yaml | 4 ++++ docs/messaging/azure-messaging.md | 25 +++++++++++++++++++++++-- docs/messaging/gcp-pubsub.md | 12 +++++++++++- docs/messaging/kafka.md | 13 ++++++++++++- docs/messaging/messaging-spans.md | 19 +++++++++++++++++++ docs/messaging/rabbitmq.md | 11 ++++++++++- docs/messaging/rocketmq.md | 12 +++++++++++- model/trace/messaging.yaml | 23 +++++++++++++++++++++++ 8 files changed, 113 insertions(+), 6 deletions(-) create mode 100644 .chloggen/1169.yaml diff --git a/.chloggen/1169.yaml b/.chloggen/1169.yaml new file mode 100644 index 0000000000..33c7de4a91 --- /dev/null +++ b/.chloggen/1169.yaml @@ -0,0 +1,4 @@ +change_type: enhancement +component: messaging +note: Define sampling relevant attributes for messaging client spans +issues: [ 432, 1169 ] diff --git a/docs/messaging/azure-messaging.md b/docs/messaging/azure-messaging.md index 5ea74c75f1..0d2d6e4e7d 100644 --- a/docs/messaging/azure-messaging.md +++ b/docs/messaging/azure-messaging.md @@ -10,7 +10,7 @@ The Semantic Conventions for [Azure Service Bus](https://learn.microsoft.com/azu ## Azure Service Bus -`messaging.system` MUST be set to `"servicebus"`. +`messaging.system` MUST be set to `"servicebus"` and SHOULD be provided **at span creation time**. ### Span attributes @@ -88,6 +88,16 @@ the broker doesn't have such notion, the destination name SHOULD uniquely identi +The following attributes can be important for making sampling decisions +and SHOULD be provided **at span creation time** (if provided at all): + +* [`messaging.destination.name`](/docs/attributes-registry/messaging.md) +* [`messaging.destination.subscription.name`](/docs/attributes-registry/messaging.md) +* [`messaging.operation.name`](/docs/attributes-registry/messaging.md) +* [`messaging.operation.type`](/docs/attributes-registry/messaging.md) +* [`server.address`](/docs/attributes-registry/server.md) +* [`server.port`](/docs/attributes-registry/server.md) + `error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. | Value | Description | Stability | @@ -124,7 +134,7 @@ the broker doesn't have such notion, the destination name SHOULD uniquely identi ## Azure Event Hubs -`messaging.system` MUST be set to `"eventhubs"`. +`messaging.system` MUST be set to `"eventhubs"` and SHOULD be provided **at span creation time**. ### Span attributes @@ -199,6 +209,17 @@ the broker doesn't have such notion, the destination name SHOULD uniquely identi +The following attributes can be important for making sampling decisions +and SHOULD be provided **at span creation time** (if provided at all): + +* [`messaging.consumer.group.name`](/docs/attributes-registry/messaging.md) +* [`messaging.destination.name`](/docs/attributes-registry/messaging.md) +* [`messaging.destination.partition.id`](/docs/attributes-registry/messaging.md) +* [`messaging.operation.name`](/docs/attributes-registry/messaging.md) +* [`messaging.operation.type`](/docs/attributes-registry/messaging.md) +* [`server.address`](/docs/attributes-registry/server.md) +* [`server.port`](/docs/attributes-registry/server.md) + `error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. | Value | Description | Stability | diff --git a/docs/messaging/gcp-pubsub.md b/docs/messaging/gcp-pubsub.md index 30135a2db6..1957e3dbbc 100644 --- a/docs/messaging/gcp-pubsub.md +++ b/docs/messaging/gcp-pubsub.md @@ -8,7 +8,7 @@ linkTitle: Google Cloud Pub/Sub The Semantic Conventions for [Google Cloud Pub/Sub](https://cloud.google.com/pubsub) extend and override the [Messaging Semantic Conventions](README.md) that describe common messaging operations attributes in addition to the Semantic Conventions described on this page. -`messaging.system` MUST be set to `"gcp_pubsub"`. +`messaging.system` MUST be set to `"gcp_pubsub"` and SHOULD be provided **at span creation time**. ## Span attributes @@ -83,6 +83,16 @@ the broker doesn't have such notion, the destination name SHOULD uniquely identi +The following attributes can be important for making sampling decisions +and SHOULD be provided **at span creation time** (if provided at all): + +* [`messaging.destination.name`](/docs/attributes-registry/messaging.md) +* [`messaging.destination.subscription.name`](/docs/attributes-registry/messaging.md) +* [`messaging.operation.name`](/docs/attributes-registry/messaging.md) +* [`messaging.operation.type`](/docs/attributes-registry/messaging.md) +* [`server.address`](/docs/attributes-registry/server.md) +* [`server.port`](/docs/attributes-registry/server.md) + `error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. | Value | Description | Stability | diff --git a/docs/messaging/kafka.md b/docs/messaging/kafka.md index 15b5b1258a..cb477b56d2 100644 --- a/docs/messaging/kafka.md +++ b/docs/messaging/kafka.md @@ -18,7 +18,7 @@ The Semantic Conventions for [Apache Kafka](https://kafka.apache.org/) extend an that describe common messaging operations attributes in addition to the Semantic Conventions described on this page. -`messaging.system` MUST be set to `"kafka"`. +`messaging.system` MUST be set to `"kafka"` and SHOULD be provided **at span creation time**. ## Span attributes @@ -93,6 +93,17 @@ body size should be used. +The following attributes can be important for making sampling decisions +and SHOULD be provided **at span creation time** (if provided at all): + +* [`messaging.consumer.group.name`](/docs/attributes-registry/messaging.md) +* [`messaging.destination.name`](/docs/attributes-registry/messaging.md) +* [`messaging.destination.partition.id`](/docs/attributes-registry/messaging.md) +* [`messaging.operation.name`](/docs/attributes-registry/messaging.md) +* [`messaging.operation.type`](/docs/attributes-registry/messaging.md) +* [`server.address`](/docs/attributes-registry/server.md) +* [`server.port`](/docs/attributes-registry/server.md) + `error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. | Value | Description | Stability | diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index eed5ee7b7b..0855774bcf 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -386,6 +386,20 @@ If a messaging operation involved multiple network calls (for example retries), +The following attributes can be important for making sampling decisions +and SHOULD be provided **at span creation time** (if provided at all): + +* [`messaging.consumer.group.name`](/docs/attributes-registry/messaging.md) +* [`messaging.destination.name`](/docs/attributes-registry/messaging.md) +* [`messaging.destination.partition.id`](/docs/attributes-registry/messaging.md) +* [`messaging.destination.subscription.name`](/docs/attributes-registry/messaging.md) +* [`messaging.destination.template`](/docs/attributes-registry/messaging.md) +* [`messaging.operation.name`](/docs/attributes-registry/messaging.md) +* [`messaging.operation.type`](/docs/attributes-registry/messaging.md) +* [`messaging.system`](/docs/attributes-registry/messaging.md) +* [`server.address`](/docs/attributes-registry/server.md) +* [`server.port`](/docs/attributes-registry/server.md) + `error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. | Value | Description | Stability | @@ -455,6 +469,11 @@ the broker doesn't have such notion, the original destination name SHOULD unique +The following attributes can be important for making sampling decisions +and SHOULD be provided **at span creation time** (if provided at all): + +* [`messaging.destination_publish.name`](/docs/attributes-registry/messaging.md) + diff --git a/docs/messaging/rabbitmq.md b/docs/messaging/rabbitmq.md index 4f15afa67d..bd4a1ed73d 100644 --- a/docs/messaging/rabbitmq.md +++ b/docs/messaging/rabbitmq.md @@ -10,7 +10,7 @@ The Semantic Conventions for [RabbitMQ](https://www.rabbitmq.com/) extend and ov that describe common messaging operations attributes in addition to the Semantic Conventions described on this page. -`messaging.system` MUST be set to `"rabbitmq"`. +`messaging.system` MUST be set to `"rabbitmq"` and SHOULD be provided **at span creation time**. ## RabbitMQ attributes @@ -78,6 +78,15 @@ body size should be used. +The following attributes can be important for making sampling decisions +and SHOULD be provided **at span creation time** (if provided at all): + +* [`messaging.destination.name`](/docs/attributes-registry/messaging.md) +* [`messaging.operation.name`](/docs/attributes-registry/messaging.md) +* [`messaging.operation.type`](/docs/attributes-registry/messaging.md) +* [`server.address`](/docs/attributes-registry/server.md) +* [`server.port`](/docs/attributes-registry/server.md) + `error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. | Value | Description | Stability | diff --git a/docs/messaging/rocketmq.md b/docs/messaging/rocketmq.md index 3c7d30f73c..a602244433 100644 --- a/docs/messaging/rocketmq.md +++ b/docs/messaging/rocketmq.md @@ -10,7 +10,7 @@ The Semantic Conventions for [Apache RocketMQ](https://rocketmq.apache.org/) ext that describe common messaging operations attributes in addition to the Semantic Conventions described on this page. -`messaging.system` MUST be set to `"rocketmq"`. +`messaging.system` MUST be set to `"rocketmq"` and SHOULD be provided **at span creation time**. ## Apache RocketMQ attributes @@ -89,6 +89,16 @@ body size should be used. +The following attributes can be important for making sampling decisions +and SHOULD be provided **at span creation time** (if provided at all): + +* [`messaging.consumer.group.name`](/docs/attributes-registry/messaging.md) +* [`messaging.destination.name`](/docs/attributes-registry/messaging.md) +* [`messaging.operation.name`](/docs/attributes-registry/messaging.md) +* [`messaging.operation.type`](/docs/attributes-registry/messaging.md) +* [`server.address`](/docs/attributes-registry/server.md) +* [`server.port`](/docs/attributes-registry/server.md) + `error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. | Value | Description | Stability | diff --git a/model/trace/messaging.yaml b/model/trace/messaging.yaml index 8baed61156..257955f34e 100644 --- a/model/trace/messaging.yaml +++ b/model/trace/messaging.yaml @@ -17,6 +17,7 @@ groups: In other cases, destination attributes may be set on links. attributes: - ref: messaging.destination_publish.name + sampling_relevant: true - ref: messaging.destination_publish.anonymous - id: attributes.messaging.trace.minimal @@ -27,15 +28,25 @@ groups: attributes: - ref: messaging.operation.name requirement_level: required + sampling_relevant: true - ref: messaging.operation.type requirement_level: conditionally_required: If applicable. + sampling_relevant: true - ref: messaging.destination.name requirement_level: conditionally_required: If span describes operation on a single message or if the value applies to all messages in the batch. + sampling_relevant: true - ref: messaging.message.id requirement_level: recommended: If span describes operation on a single message. + - ref: server.address + sampling_relevant: true + - ref: server.port + sampling_relevant: true + # TODO: add messaging.system once https://github.com/open-telemetry/build-tools/issues/192 is implemented + # - ref: messaging.system + # sampling_relevant: true - id: messaging type: span @@ -45,16 +56,19 @@ groups: attributes: - ref: messaging.system requirement_level: required + sampling_relevant: true - ref: messaging.client.id requirement_level: recommended - ref: messaging.destination.partition.id requirement_level: recommended: When applicable. + sampling_relevant: true - ref: messaging.destination.template requirement_level: conditionally_required: > If available. Instrumentations MUST NOT use `messaging.destination.name` as template unless low-cardinality of destination name is guaranteed. + sampling_relevant: true - ref: messaging.destination.temporary requirement_level: conditionally_required: If value is `true`. When missing, the value is assumed to be `false`. @@ -64,9 +78,11 @@ groups: - ref: messaging.consumer.group.name requirement_level: conditionally_required: If applicable. + sampling_relevant: true - ref: messaging.destination.subscription.name requirement_level: conditionally_required: If applicable. + sampling_relevant: true - ref: messaging.message.conversation_id - ref: messaging.message.envelope.size - ref: messaging.message.body.size @@ -126,10 +142,12 @@ groups: - ref: messaging.consumer.group.name brief: "Kafka [consumer group id](https://docs.confluent.io/platform/current/clients/consumer.html)." note: "" + sampling_relevant: true - ref: messaging.destination.partition.id brief: > String representation of the partition id the message (or batch) is sent to or received from. requirement_level: recommended + sampling_relevant: true - ref: messaging.kafka.message.key requirement_level: recommended: If span describes operation on a single message. @@ -156,6 +174,7 @@ groups: - ref: messaging.consumer.group.name brief: "RocketMQ [consumer group name](https://rocketmq.apache.org/docs/domainModel/07consumergroup)." note: "" + sampling_relevant: true requirement_level: required - ref: messaging.rocketmq.namespace requirement_level: required @@ -188,6 +207,7 @@ groups: - ref: messaging.destination.subscription.name brief: "Google Pub/Sub [subscription name](https://cloud.google.com/pubsub/docs/subscription-overview)." note: "" + sampling_relevant: true - ref: messaging.gcp_pubsub.message.ordering_key requirement_level: conditionally_required: If the message type has an ordering key set. @@ -216,6 +236,7 @@ groups: - ref: messaging.destination.subscription.name brief: "Azure Service Bus [subscription name](https://learn.microsoft.com/azure/service-bus-messaging/service-bus-queues-topics-subscriptions#topics-and-subscriptions)." note: "" + sampling_relevant: true requirement_level: conditionally_required: If messages are received from the subscription. - ref: messaging.servicebus.message.delivery_count @@ -257,11 +278,13 @@ groups: note: "" requirement_level: conditionally_required: On consumer spans. + sampling_relevant: true - ref: messaging.destination.partition.id brief: > String representation of the partition id messages are sent to or received from, unique within the Event Hub. requirement_level: conditionally_required: If available. + sampling_relevant: true - ref: messaging.eventhubs.message.enqueued_time - ref: messaging.batch.message_count requirement_level: From ab03b681d48f55d3686c607cef5dc8c33477b553 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Mon, 24 Jun 2024 12:26:30 +0200 Subject: [PATCH 02/11] [chore] Fix GH yaml check warning (#1176) --- model/trace/messaging.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/model/trace/messaging.yaml b/model/trace/messaging.yaml index 257955f34e..52bf65c542 100644 --- a/model/trace/messaging.yaml +++ b/model/trace/messaging.yaml @@ -44,9 +44,9 @@ groups: sampling_relevant: true - ref: server.port sampling_relevant: true - # TODO: add messaging.system once https://github.com/open-telemetry/build-tools/issues/192 is implemented - # - ref: messaging.system - # sampling_relevant: true + # TODO: add messaging.system once https://github.com/open-telemetry/build-tools/issues/192 is implemented + # - ref: messaging.system + # sampling_relevant: true - id: messaging type: span From eeed399850993eddd29ede784137c9ea35efeba3 Mon Sep 17 00:00:00 2001 From: Gergely Kalapos Date: Mon, 24 Jun 2024 16:23:59 +0200 Subject: [PATCH 03/11] Define sanitization for db.query.text (#1100) Co-authored-by: Trask Stalnaker Co-authored-by: Liudmila Molkova --- .chloggen/db_sanitization.yaml | 22 ++++++++++++++++++++++ docs/attributes-registry/db.md | 4 +++- docs/database/cassandra.md | 6 ++++-- docs/database/cosmosdb.md | 6 ++++-- docs/database/database-spans.md | 18 ++++++++++++++++-- docs/database/elasticsearch.md | 4 +++- docs/database/mssql.md | 6 ++++-- docs/database/sql.md | 6 ++++-- model/registry/db.yaml | 6 ++++++ model/trace/database.yaml | 5 +---- 10 files changed, 67 insertions(+), 16 deletions(-) create mode 100755 .chloggen/db_sanitization.yaml diff --git a/.chloggen/db_sanitization.yaml b/.chloggen/db_sanitization.yaml new file mode 100755 index 0000000000..a6d255ec26 --- /dev/null +++ b/.chloggen/db_sanitization.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: Specify sanitization for `db.query.text`. + +# 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: [717] + +# (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 82bafcf1df..a3a6cb7e41 100644 --- a/docs/attributes-registry/db.md +++ b/docs/attributes-registry/db.md @@ -46,7 +46,9 @@ For batch operations, if the individual operations are known to have the same op **[5]:** 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. -**[6]:** For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. +**[6]:** For sanitization see [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). +For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. +Even though parameterized query text can potentially have sensitive data, by using a parameterized query the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to observability of capturing the static part of the query text by default outweighs the risk. **[7]:** The actual DBMS may differ from the one identified by the client. For example, when using PostgreSQL client libraries to connect to a CockroachDB, the `db.system` is set to `postgresql` based on the instrumentation's best knowledge. diff --git a/docs/database/cassandra.md b/docs/database/cassandra.md index abfb3d4f1f..cf9eae8aca 100644 --- a/docs/database/cassandra.md +++ b/docs/database/cassandra.md @@ -60,9 +60,11 @@ For batch operations, if the individual operations are known to have the same op **[8]:** If using a port other than the default port for this DBMS and if `server.address` is set. -**[9]:** For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. +**[9]:** For sanitization see [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). +For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. +Even though parameterized query text can potentially have sensitive data, by using a parameterized query the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to observability of capturing the static part of the query text by default outweighs the risk. -**[10]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. +**[10]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. See [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). **[11]:** 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 f4313b0bcd..5256694f2c 100644 --- a/docs/database/cosmosdb.md +++ b/docs/database/cosmosdb.md @@ -59,9 +59,11 @@ For batch operations, if the individual operations are known to have the same op **[6]:** If using a port other than the default port for this DBMS and if `server.address` is set. -**[7]:** For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. +**[7]:** For sanitization see [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). +For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. +Even though parameterized query text can potentially have sensitive data, by using a parameterized query the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to observability of capturing the static part of the query text by default outweighs the risk. -**[8]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. +**[8]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. See [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). **[9]:** 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. diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 33152ab141..23e0742623 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -13,6 +13,7 @@ linkTitle: Client Calls - [Name](#name) - [Common attributes](#common-attributes) - [Notes and well-known identifiers for `db.system`](#notes-and-well-known-identifiers-for-dbsystem) +- [Sanitization of `db.query.text`](#sanitization-of-dbquerytext) - [Semantic Conventions for specific database technologies](#semantic-conventions-for-specific-database-technologies) @@ -125,9 +126,11 @@ For batch operations, if the individual operations are known to have the same op **[9]:** If using a port other than the default port for this DBMS and if `server.address` is set. -**[10]:** For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. +**[10]:** For sanitization see [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). +For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. +Even though parameterized query text can potentially have sensitive data, by using a parameterized query the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to observability of capturing the static part of the query text by default outweighs the risk. -**[11]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. +**[11]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. See [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). **[12]:** 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. @@ -225,6 +228,17 @@ Back ends could, for example, use the provided identifier to determine the appro 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. +## Sanitization of `db.query.text` + +The `db.query.text` SHOULD be collected by default only if there is sanitization that excludes sensitive information. +Sanitization SHOULD replace all literals with a placeholder value. +Such literals include, but are not limited to, String, Numeric, Date and Time, +Boolean, Interval, Binary, and Hexadecimal literals. +The placeholder value SHOULD be `?`, unless it already has a defined meaning in the given database system, +in which case the instrumentation MAY choose a different placeholder. + +Placeholders in a parameterized query SHOULD not be sanitized. E.g. `where id = $1` can be captured as is. + ## Semantic Conventions for specific database technologies More specific Semantic Conventions are defined for the following database technologies: diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index 12dbd1e5ad..d881f79ace 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -74,7 +74,9 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original **[10]:** When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Cluster" HTTP response header. -**[11]:** For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. +**[11]:** For sanitization see [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). +For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. +Even though parameterized query text can potentially have sensitive data, by using a parameterized query the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to observability of capturing the static part of the query text by default outweighs the risk. **[12]:** Should be collected by default for search-type queries and only if there is sanitization that excludes sensitive information. diff --git a/docs/database/mssql.md b/docs/database/mssql.md index c345b60833..6d03232088 100644 --- a/docs/database/mssql.md +++ b/docs/database/mssql.md @@ -52,9 +52,11 @@ In the case of `EXEC`, this SHOULD be the stored procedure name that is being ex **[8]:** If using a port other than the default port for this DBMS and if `server.address` is set. -**[9]:** For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. +**[9]:** For sanitization see [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). +For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. +Even though parameterized query text can potentially have sensitive data, by using a parameterized query the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to observability of capturing the static part of the query text by default outweighs the risk. -**[10]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. +**[10]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. See [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). **[11]:** 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. diff --git a/docs/database/sql.md b/docs/database/sql.md index 46d4ba036a..115ec29eaa 100644 --- a/docs/database/sql.md +++ b/docs/database/sql.md @@ -91,9 +91,11 @@ In the case of `EXEC`, this SHOULD be the stored procedure name that is being ex **[8]:** If using a port other than the default port for this DBMS and if `server.address` is set. -**[9]:** For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. +**[9]:** For sanitization see [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). +For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. +Even though parameterized query text can potentially have sensitive data, by using a parameterized query the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to observability of capturing the static part of the query text by default outweighs the risk. -**[10]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. +**[10]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. See [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). **[11]:** 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. diff --git a/model/registry/db.yaml b/model/registry/db.yaml index c6af1415db..f1efd77a5f 100644 --- a/model/registry/db.yaml +++ b/model/registry/db.yaml @@ -54,9 +54,15 @@ groups: brief: > The database query being executed. note: > + For sanitization see [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). + For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. + + Even though parameterized query text can potentially have sensitive data, by using a parameterized query + the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit + to observability of capturing the static part of the query text by default outweighs the risk. examples: ['SELECT * FROM wuser_table where username = ?', 'SET mykey "WuValue"'] - id: query.parameter type: template[string] diff --git a/model/trace/database.yaml b/model/trace/database.yaml index 83208f686c..24d92636dd 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -13,10 +13,6 @@ groups: Parameterized query text SHOULD be collected by default (the query parameter values themselves are opt-in, see [`db.query.parameter.`](../../docs/attributes-registry/db.md)). - note: - Even though parameterized query text can potentially have sensitive data, by using a parameterized query - the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit - to observability of capturing the static part of the query text by default outweighs the risk. - ref: db.query.parameter requirement_level: opt_in @@ -29,6 +25,7 @@ groups: requirement_level: recommended: > SHOULD be collected by default only if there is sanitization that excludes sensitive information. + See [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). - ref: db.query.parameter requirement_level: opt_in - ref: db.collection.name From ad05f1d8d319471e23f9bc2d8afbf3e0f046b873 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 25 Jun 2024 04:40:10 -0700 Subject: [PATCH 04/11] Clarify db.query.parameter is string representation (#1165) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .chloggen/1165.yaml | 22 ++++++++++++++++++++++ docs/attributes-registry/db.md | 2 +- docs/database/cassandra.md | 2 +- docs/database/cosmosdb.md | 2 +- docs/database/database-spans.md | 2 +- docs/database/mssql.md | 2 +- docs/database/redis.md | 2 +- docs/database/sql.md | 2 +- model/registry/db.yaml | 4 ++-- 9 files changed, 31 insertions(+), 9 deletions(-) create mode 100644 .chloggen/1165.yaml diff --git a/.chloggen/1165.yaml b/.chloggen/1165.yaml new file mode 100644 index 0000000000..76e5ed376f --- /dev/null +++ b/.chloggen/1165.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: Clarify that `db.query.parameter.` is string representation of the parameter value + +# 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: [ 1165 ] + +# (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 a3a6cb7e41..db78b93f6b 100644 --- a/docs/attributes-registry/db.md +++ b/docs/attributes-registry/db.md @@ -25,7 +25,7 @@ This group defines the attributes used to describe telemetry in the context of d | `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.batch.size` | int | The number of queries included in a [batch operation](/docs/database/database-spans.md#batch-operations). [3] | `2`; `3`; `4` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.operation.name` | string | The name of the operation or command being executed. [4] | `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. [5] | `someval`; `55` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.query.parameter.` | string | A query parameter used in `db.query.text`, with `` being the parameter name, and the attribute value being a string representation of the parameter value. [5] | `someval`; `55` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.query.text` | string | The database query being executed. [6] | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.system` | string | The database management system (DBMS) product as identified by the client instrumentation. [7] | `other_sql`; `adabas`; `cache` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/database/cassandra.md b/docs/database/cassandra.md index cf9eae8aca..fec15f7cf0 100644 --- a/docs/database/cassandra.md +++ b/docs/database/cassandra.md @@ -38,7 +38,7 @@ described on this page. | [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [11] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](/docs/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`](/docs/attributes-registry/server.md) | string | Name of the database host. [12] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`db.query.parameter.`](/docs/attributes-registry/db.md) | string | The query parameters used in `db.query.text`, with `` being the parameter name, and the attribute value being the parameter value. [13] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.query.parameter.`](/docs/attributes-registry/db.md) | string | A query parameter used in `db.query.text`, with `` being the parameter name, and the attribute value being a string representation of the parameter value. [13] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. If the collection name is parsed from the query text, it SHOULD be the first collection name found in the query and it SHOULD match the value provided in the query text including any schema and database name prefix. diff --git a/docs/database/cosmosdb.md b/docs/database/cosmosdb.md index 5256694f2c..6fa48db887 100644 --- a/docs/database/cosmosdb.md +++ b/docs/database/cosmosdb.md @@ -41,7 +41,7 @@ Cosmos DB instrumentation includes call-level (public API) surface spans and net | [`db.query.text`](/docs/attributes-registry/db.md) | string | The database query being executed. [7] | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | `Recommended` [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`server.address`](/docs/attributes-registry/server.md) | string | Name of the database host. [9] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`user_agent.original`](/docs/attributes-registry/user-agent.md) | string | Full user-agent string is generated by Cosmos DB SDK [10] | `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\|` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`db.query.parameter.`](/docs/attributes-registry/db.md) | string | The query parameters used in `db.query.text`, with `` being the parameter name, and the attribute value being the parameter value. [11] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.query.parameter.`](/docs/attributes-registry/db.md) | string | A query parameter used in `db.query.text`, with `` being the parameter name, and the attribute value being a string representation of the parameter value. [11] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. If the collection name is parsed from the query text, it SHOULD be the first collection name found in the query and it SHOULD match the value provided in the query text including any schema and database name prefix. diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 23e0742623..88093233d8 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -100,7 +100,7 @@ These attributes will usually be the same for all operations performed over the | [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [12] | `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`](/docs/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`](/docs/attributes-registry/server.md) | string | Name of the database host. [13] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`db.query.parameter.`](/docs/attributes-registry/db.md) | string | The query parameters used in `db.query.text`, with `` being the parameter name, and the attribute value being the parameter value. [14] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.query.parameter.`](/docs/attributes-registry/db.md) | string | A query parameter used in `db.query.text`, with `` being the parameter name, and the attribute value being a string representation of the parameter value. [14] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The actual DBMS may differ from the one identified by the client. For example, when using PostgreSQL client libraries to connect to a CockroachDB, the `db.system` is set to `postgresql` based on the instrumentation's best knowledge. diff --git a/docs/database/mssql.md b/docs/database/mssql.md index 6d03232088..6962223af7 100644 --- a/docs/database/mssql.md +++ b/docs/database/mssql.md @@ -30,7 +30,7 @@ described on this page. | [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [7] | `80`; `8080`; `443` | `Conditionally Required` [8] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`db.query.text`](/docs/attributes-registry/db.md) | string | The database query being executed. [9] | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | `Recommended` [10] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`server.address`](/docs/attributes-registry/server.md) | string | Name of the database host. [11] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`db.query.parameter.`](/docs/attributes-registry/db.md) | string | The query parameters used in `db.query.text`, with `` being the parameter name, and the attribute value being the parameter value. [12] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.query.parameter.`](/docs/attributes-registry/db.md) | string | A query parameter used in `db.query.text`, with `` being the parameter name, and the attribute value being a string representation of the parameter value. [12] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. If the collection name is parsed from the query text, it SHOULD be the first collection name found in the query and it SHOULD match the value provided in the query text including any schema and database name prefix. diff --git a/docs/database/redis.md b/docs/database/redis.md index 9d1b5ef057..bbe41a21c2 100644 --- a/docs/database/redis.md +++ b/docs/database/redis.md @@ -31,7 +31,7 @@ described on this page. | [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [9] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](/docs/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`](/docs/attributes-registry/server.md) | string | Name of the database host. [10] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`db.query.parameter.`](/docs/attributes-registry/db.md) | string | The query parameters used in `db.query.text`, with `` being the parameter name, and the attribute value being the parameter value. [11] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.query.parameter.`](/docs/attributes-registry/db.md) | string | A query parameter used in `db.query.text`, with `` being the parameter name, and the attribute value being a string representation of the parameter value. [11] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[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. diff --git a/docs/database/sql.md b/docs/database/sql.md index 115ec29eaa..524c5878bd 100644 --- a/docs/database/sql.md +++ b/docs/database/sql.md @@ -52,7 +52,7 @@ Instrumentations applied to generic SQL drivers SHOULD adhere to SQL semantic co | [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [7] | `80`; `8080`; `443` | `Conditionally Required` [8] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`db.query.text`](/docs/attributes-registry/db.md) | string | The database query being executed. [9] | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | `Recommended` [10] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`server.address`](/docs/attributes-registry/server.md) | string | Name of the database host. [11] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`db.query.parameter.`](/docs/attributes-registry/db.md) | string | The query parameters used in `db.query.text`, with `` being the parameter name, and the attribute value being the parameter value. [12] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.query.parameter.`](/docs/attributes-registry/db.md) | string | A query parameter used in `db.query.text`, with `` being the parameter name, and the attribute value being a string representation of the parameter value. [12] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. If the collection name is parsed from the query text, it SHOULD be the first collection name found in the query and it SHOULD match the value provided in the query text including any schema and database name prefix. diff --git a/model/registry/db.yaml b/model/registry/db.yaml index f1efd77a5f..c94ac32e0f 100644 --- a/model/registry/db.yaml +++ b/model/registry/db.yaml @@ -68,8 +68,8 @@ groups: type: template[string] stability: experimental brief: > - The query parameters used in `db.query.text`, with `` being the parameter name, - and the attribute value being the parameter value. + A query parameter used in `db.query.text`, with `` being the parameter name, + and the attribute value being a string representation of the parameter value. note: > Query parameters should only be captured when `db.query.text` is parameterized with placeholders. From db1b84d45d09d0c3de67aa4006d2415a994dca07 Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Wed, 26 Jun 2024 10:46:38 +0300 Subject: [PATCH 05/11] Merge *.cpu.state attributes to a common cpu.mode attribute (#1026) Signed-off-by: ChrsMark Co-authored-by: Alexandra Konrad Co-authored-by: Liudmila Molkova Co-authored-by: Braydon Kains <93549768+braydonk@users.noreply.github.com> Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .chloggen/merge_cpu_states.yaml | 22 ++++++++++++ .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/container.md | 18 +++++----- docs/attributes-registry/cpu.md | 28 +++++++++++++++ docs/attributes-registry/process.md | 12 +++---- docs/attributes-registry/system.md | 26 +++++++------- docs/system/container-metrics.md | 19 ++++++++--- docs/system/process-metrics.md | 30 ++++++++++++---- docs/system/system-metrics.md | 18 +++++++--- model/metrics/container.yaml | 5 +-- model/metrics/process-metrics.yaml | 14 ++++---- model/metrics/system-metrics.yaml | 10 +++--- model/registry/container.yaml | 19 ----------- model/registry/cpu.yaml | 38 +++++++++++++++++++++ model/registry/deprecated/container.yaml | 20 +++++++++++ model/registry/deprecated/process.yaml | 21 ++++++++++++ model/registry/deprecated/system.yaml | 29 ++++++++++++++++ model/registry/process.yaml | 23 ------------- model/registry/system.yaml | 28 --------------- schema-next.yaml | 13 ++++++- templates/registry/markdown/weaver.yaml | 1 + 24 files changed, 272 insertions(+), 126 deletions(-) create mode 100755 .chloggen/merge_cpu_states.yaml create mode 100644 docs/attributes-registry/cpu.md create mode 100644 model/registry/cpu.yaml create mode 100644 model/registry/deprecated/process.yaml diff --git a/.chloggen/merge_cpu_states.yaml b/.chloggen/merge_cpu_states.yaml new file mode 100755 index 0000000000..54ea54c032 --- /dev/null +++ b/.chloggen/merge_cpu_states.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: system + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Rename `process.cpu.state`, `container.cpu.state`, and `system.cpu.state` attributes into a common `cpu.mode` attribute + +# 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: [840] + +# (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/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 33cf248bb7..f4add087f9 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -28,6 +28,7 @@ body: - area:cloudevents - area:code - area:container + - area:cpu - area:db - area:deployment - area:destination diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index 4429b696e6..e5c7532f76 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -21,6 +21,7 @@ body: - area:cloudevents - area:code - area:container + - area:cpu - area:db - area:deployment - area:destination diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index 1a504ea5ce..b4099a42cb 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -30,6 +30,7 @@ body: - area:cloudevents - area:code - area:container + - area:cpu - area:db - area:deployment - area:destination diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 2aa1b98447..97eab1087b 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -40,6 +40,7 @@ Currently, the following namespaces exist: - [CloudEvents](cloudevents.md) - [Code](code.md) - [Container](container.md) +- [CPU](cpu.md) - [Db](db.md) - [Deployment](deployment.md) - [Destination](destination.md) diff --git a/docs/attributes-registry/container.md b/docs/attributes-registry/container.md index 12ae8414bf..fdca43d789 100644 --- a/docs/attributes-registry/container.md +++ b/docs/attributes-registry/container.md @@ -18,7 +18,6 @@ A container instance. | `container.command` | string | The command used to run the container (i.e. the command name). [1] | `otelcontribcol` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `container.command_args` | string[] | All the command arguments (including the command/executable itself) run by the container. [2] | `["otelcontribcol, --config, config.yaml"]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `container.command_line` | string | The full command run by the container as a single string representing the full command. [2] | `otelcontribcol --config config.yaml` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `container.cpu.state` | string | The CPU state for this data point. | `user`; `kernel` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `container.id` | string | Container ID. Usually a UUID, as for example used to [identify Docker containers](https://docs.docker.com/engine/reference/run/#container-identification). The UUID might be abbreviated. | `a3bf90e006b2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `container.image.id` | string | Runtime specific image identifier. Usually a hash algorithm followed by a UUID. [2] | `sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `container.image.name` | string | Name of the image the container was built on. | `gcr.io/opentelemetry/operator` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -36,18 +35,19 @@ The ID is assigned by the container runtime and can vary in different environmen **[3]:** [Docker](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect) and [CRI](https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238) report those under the `RepoDigests` field. -`container.cpu.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 | -| -------- | --------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | -| `kernel` | When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system` | When CPU is used by the system (host OS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `user` | When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - ## Container Deprecated Attributes Describes deprecated container attributes. | Attribute | Type | Description | Examples | Stability | | ------------------------ | ------ | ------------------------------------------ | --------------------------- | --------------------------------------------------------------------------------------------- | +| `container.cpu.state` | string | Deprecated, use `cpu.mode` instead. | `user`; `kernel` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `cpu.mode` | | `container.labels.` | string | Deprecated, use `container.label` instead. | `container.label.app=nginx` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `container.label`. | + +`container.cpu.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 | +| -------- | --------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `kernel` | When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system` | When CPU is used by the system (host OS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `user` | When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/cpu.md b/docs/attributes-registry/cpu.md new file mode 100644 index 0000000000..2e405a8a83 --- /dev/null +++ b/docs/attributes-registry/cpu.md @@ -0,0 +1,28 @@ + + + + + +# CPU + +## CPU Attributes + +Attributes specific to a cpu instance. + +| Attribute | Type | Description | Examples | Stability | +| ---------- | ------ | ------------------- | ---------------- | ---------------------------------------------------------------- | +| `cpu.mode` | string | The mode of the CPU | `user`; `system` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`cpu.mode` 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) | +| `interrupt` | interrupt | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `iowait` | iowait | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `kernel` | kernel | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `nice` | nice | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `steal` | steal | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system` | system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `user` | user | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/process.md b/docs/attributes-registry/process.md index 2e525794c2..6522b0ace3 100644 --- a/docs/attributes-registry/process.md +++ b/docs/attributes-registry/process.md @@ -7,7 +7,7 @@ # Process - [Process](#process-attributes) -- [Process Cpu](#process-cpu-attributes) +- [Process Deprecated](#process-deprecated-attributes) ## Process Attributes @@ -58,13 +58,13 @@ An operating system process. | `major` | major | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `minor` | minor | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -## Process Cpu Attributes +## Process Deprecated Attributes -Attributes for process CPU +Deprecated process attributes. -| Attribute | Type | Description | Examples | Stability | -| ------------------- | ------ | ----------------------------- | ------------------------ | ---------------------------------------------------------------- | -| `process.cpu.state` | string | The CPU state of the process. | `system`; `user`; `wait` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Attribute | Type | Description | Examples | Stability | +| ------------------- | ------ | ----------------------------------- | ------------------------ | ------------------------------------------------------------------------------------- | +| `process.cpu.state` | string | Deprecated, use `cpu.mode` instead. | `system`; `user`; `wait` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `cpu.mode` | `process.cpu.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. diff --git a/docs/attributes-registry/system.md b/docs/attributes-registry/system.md index de49928773..c504f989f9 100644 --- a/docs/attributes-registry/system.md +++ b/docs/attributes-registry/system.md @@ -23,14 +23,22 @@ Describes System attributes | --------------- | ------ | --------------------- | -------------- | ---------------------------------------------------------------- | | `system.device` | string | The device identifier | `(identifier)` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -## System Cpu Attributes +## System CPU Attributes Describes System CPU attributes -| Attribute | Type | Description | Examples | Stability | -| --------------------------- | ------ | ------------------------------- | ------------------- | ---------------------------------------------------------------- | -| `system.cpu.logical_number` | int | The logical CPU number [0..n-1] | `1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.cpu.state` | string | The state of the CPU | `idle`; `interrupt` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Attribute | Type | Description | Examples | Stability | +| --------------------------- | ---- | ------------------------------- | -------- | ---------------------------------------------------------------- | +| `system.cpu.logical_number` | int | The logical CPU number [0..n-1] | `1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +## System Deprecated Attributes + +Deprecated system attributes. + +| Attribute | Type | Description | Examples | Stability | +| ------------------------- | ------ | ------------------------------------------------ | ------------------- | --------------------------------------------------------------------------------------------------- | +| `system.cpu.state` | string | Deprecated, use `cpu.mode` instead. | `idle`; `interrupt` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `cpu.mode` | +| `system.processes.status` | string | Deprecated, use `system.process.status` instead. | `running` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `system.process.status`. | `system.cpu.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. @@ -44,14 +52,6 @@ Describes System CPU attributes | `system` | system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `user` | user | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -## System Deprecated Attributes - -Deprecated system attributes. - -| Attribute | Type | Description | Examples | Stability | -| ------------------------- | ------ | ------------------------------------------------ | --------- | --------------------------------------------------------------------------------------------------- | -| `system.processes.status` | string | Deprecated, use `system.process.status` instead. | `running` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `system.process.status`. | - `system.processes.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 | diff --git a/docs/system/container-metrics.md b/docs/system/container-metrics.md index 5449a117d0..b0fb198f21 100644 --- a/docs/system/container-metrics.md +++ b/docs/system/container-metrics.md @@ -42,15 +42,24 @@ This metric is [opt-in][MetricOptIn]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`container.cpu.state`](/docs/attributes-registry/container.md) | string | The CPU state for this data point. A container SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels. | `user`; `kernel` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cpu.mode`](/docs/attributes-registry/cpu.md) | string | The CPU mode for this data point. A container's CPU metric SHOULD be characterized _either_ by data points with no `mode` labels, _or only_ data points with `mode` labels. [1] | `user`; `system` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`container.cpu.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. +**[1]:** Following states SHOULD be used: `user`, `system`, `kernel` + + + +`cpu.mode` 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 | |---|---|---| -| `kernel` | When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system` | When CPU is used by the system (host OS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `user` | When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `idle` | idle | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `interrupt` | interrupt | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `iowait` | iowait | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `kernel` | kernel | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `nice` | nice | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `steal` | steal | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system` | system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `user` | user | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/system/process-metrics.md b/docs/system/process-metrics.md index 5b40717462..892382e40f 100644 --- a/docs/system/process-metrics.md +++ b/docs/system/process-metrics.md @@ -75,15 +75,24 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`process.cpu.state`](/docs/attributes-registry/process.md) | string | A process SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels. | `system`; `user`; `wait` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cpu.mode`](/docs/attributes-registry/cpu.md) | string | A process SHOULD be characterized _either_ by data points with no `mode` labels, _or only_ data points with `mode` labels. [1] | `user`; `system` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`process.cpu.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. +**[1]:** Following states SHOULD be used: `user`, `system`, `wait` + + + +`cpu.mode` 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) | +| `interrupt` | interrupt | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `iowait` | iowait | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `kernel` | kernel | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `nice` | nice | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `steal` | steal | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `system` | system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `user` | user | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `wait` | wait | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -122,15 +131,24 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`process.cpu.state`](/docs/attributes-registry/process.md) | string | A process SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels. | `system`; `user`; `wait` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cpu.mode`](/docs/attributes-registry/cpu.md) | string | A process SHOULD be characterized _either_ by data points with no `mode` labels, _or only_ data points with `mode` labels. [1] | `user`; `system` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** Following states SHOULD be used: `user`, `system`, `wait` + + -`process.cpu.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. +`cpu.mode` 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) | +| `interrupt` | interrupt | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `iowait` | iowait | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `kernel` | kernel | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `nice` | nice | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `steal` | steal | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `system` | system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `user` | user | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `wait` | wait | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/system/system-metrics.md b/docs/system/system-metrics.md index 70a9c543af..cd01009e28 100644 --- a/docs/system/system-metrics.md +++ b/docs/system/system-metrics.md @@ -104,16 +104,21 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| +| [`cpu.mode`](/docs/attributes-registry/cpu.md) | string | The CPU mode for this data point. A system's CPU SHOULD be characterized *either* by data points with no `mode` labels, *or only* data points with `mode` labels. [1] | `user`; `system` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`system.cpu.logical_number`](/docs/attributes-registry/system.md) | int | The logical CPU number [0..n-1] | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.cpu.state`](/docs/attributes-registry/system.md) | string | The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels. | `idle`; `interrupt` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`system.cpu.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. +**[1]:** Following states SHOULD be used: `user`, `system`, `nice`, `idle`, `iowait`, `interrupt`, `steal` + + + +`cpu.mode` 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) | | `interrupt` | interrupt | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `iowait` | iowait | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `kernel` | kernel | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `nice` | nice | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `steal` | steal | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `system` | system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -156,16 +161,21 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| +| [`cpu.mode`](/docs/attributes-registry/cpu.md) | string | The CPU mode for this data point. A system's CPU SHOULD be characterized *either* by data points with no `mode` labels, *or only* data points with `mode` labels. [1] | `user`; `system` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`system.cpu.logical_number`](/docs/attributes-registry/system.md) | int | The logical CPU number [0..n-1] | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.cpu.state`](/docs/attributes-registry/system.md) | string | The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels. | `idle`; `interrupt` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`system.cpu.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. +**[1]:** Following modes SHOULD be used: `user`, `system`, `nice`, `idle`, `iowait`, `interrupt`, `steal` + + + +`cpu.mode` 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) | | `interrupt` | interrupt | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `iowait` | iowait | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `kernel` | kernel | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `nice` | nice | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `steal` | steal | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `system` | system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/model/metrics/container.yaml b/model/metrics/container.yaml index f0e15ed596..94adad2921 100644 --- a/model/metrics/container.yaml +++ b/model/metrics/container.yaml @@ -10,8 +10,9 @@ groups: instrument: counter unit: "s" attributes: - - ref: container.cpu.state - brief: "The CPU state for this data point. A container SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels." + - ref: cpu.mode + brief: "The CPU mode for this data point. A container's CPU metric SHOULD be characterized _either_ by data points with no `mode` labels, _or only_ data points with `mode` labels." + note: "Following states SHOULD be used: `user`, `system`, `kernel`" requirement_level: opt_in # container.memory.* metrics and attribute group diff --git a/model/metrics/process-metrics.yaml b/model/metrics/process-metrics.yaml index 3941cdc56d..86d224d543 100644 --- a/model/metrics/process-metrics.yaml +++ b/model/metrics/process-metrics.yaml @@ -7,10 +7,11 @@ groups: instrument: counter unit: "s" attributes: - - ref: process.cpu.state + - ref: cpu.mode brief: > - A process SHOULD be characterized _either_ by data points with no `state` - labels, _or only_ data points with `state` labels. + A process SHOULD be characterized _either_ by data points with no `mode` + labels, _or only_ data points with `mode` labels. + note: "Following states SHOULD be used: `user`, `system`, `wait`" - id: metric.process.cpu.utilization type: metric @@ -22,10 +23,11 @@ groups: instrument: gauge unit: "1" attributes: - - ref: process.cpu.state + - ref: cpu.mode brief: > - A process SHOULD be characterized _either_ by data points with no `state` - labels, _or only_ data points with `state` labels. + A process SHOULD be characterized _either_ by data points with no `mode` + labels, _or only_ data points with `mode` labels. + note: "Following states SHOULD be used: `user`, `system`, `wait`" - id: metric.process.memory.usage type: metric diff --git a/model/metrics/system-metrics.yaml b/model/metrics/system-metrics.yaml index 1b7a2cf28e..25e2d06665 100644 --- a/model/metrics/system-metrics.yaml +++ b/model/metrics/system-metrics.yaml @@ -8,8 +8,9 @@ groups: instrument: counter unit: "s" attributes: - - ref: system.cpu.state - brief: "The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels." + - ref: cpu.mode + brief: "The CPU mode for this data point. A system's CPU SHOULD be characterized *either* by data points with no `mode` labels, *or only* data points with `mode` labels." + note: "Following states SHOULD be used: `user`, `system`, `nice`, `idle`, `iowait`, `interrupt`, `steal`" - ref: system.cpu.logical_number - id: metric.system.cpu.utilization @@ -20,8 +21,9 @@ groups: instrument: gauge unit: "1" attributes: - - ref: system.cpu.state - brief: "The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels." + - ref: cpu.mode + brief: "The CPU mode for this data point. A system's CPU SHOULD be characterized *either* by data points with no `mode` labels, *or only* data points with `mode` labels." + note: "Following modes SHOULD be used: `user`, `system`, `nice`, `idle`, `iowait`, `interrupt`, `steal`" - ref: system.cpu.logical_number - id: metric.system.cpu.frequency diff --git a/model/registry/container.yaml b/model/registry/container.yaml index b2ff38239f..60348628b4 100644 --- a/model/registry/container.yaml +++ b/model/registry/container.yaml @@ -95,22 +95,3 @@ groups: brief: > Container labels, `` being the label name, the value being the label value. examples: [ 'container.label.app=nginx' ] - - id: cpu.state - brief: "The CPU state for this data point." - type: - allow_custom_values: true - members: - - id: user - value: 'user' - brief: "When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows)." - stability: experimental - - id: system - value: 'system' - brief: "When CPU is used by the system (host OS)" - stability: experimental - - id: kernel - value: 'kernel' - brief: "When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows)." - stability: experimental - stability: experimental - examples: ["user", "kernel"] diff --git a/model/registry/cpu.yaml b/model/registry/cpu.yaml new file mode 100644 index 0000000000..43fb145a38 --- /dev/null +++ b/model/registry/cpu.yaml @@ -0,0 +1,38 @@ +groups: + - id: registry.cpu + prefix: cpu + type: attribute_group + brief: Attributes specific to a cpu instance. + attributes: + - id: mode + brief: "The mode of the CPU" + type: + allow_custom_values: true + # TODO: Fix how enum members are used in semantic conventions after https://github.com/open-telemetry/build-tools/issues/192 is merged + members: + - id: user + value: 'user' + stability: experimental + - id: system + value: 'system' + stability: experimental + - id: nice + value: 'nice' + stability: experimental + - id: idle + value: 'idle' + stability: experimental + - id: iowait + value: 'iowait' + stability: experimental + - id: interrupt + value: 'interrupt' + stability: experimental + - id: steal + value: 'steal' + stability: experimental + - id: kernel + value: 'kernel' + stability: experimental + stability: experimental + examples: [ "user", "system" ] diff --git a/model/registry/deprecated/container.yaml b/model/registry/deprecated/container.yaml index 77f3466f02..63e69621dd 100644 --- a/model/registry/deprecated/container.yaml +++ b/model/registry/deprecated/container.yaml @@ -9,3 +9,23 @@ groups: brief: "Deprecated, use `container.label` instead." stability: experimental deprecated: "Replaced by `container.label`." + - id: container.cpu.state + brief: "Deprecated, use `cpu.mode` instead." + type: + allow_custom_values: true + members: + - id: user + value: 'user' + brief: "When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows)." + stability: experimental + - id: system + value: 'system' + brief: "When CPU is used by the system (host OS)" + stability: experimental + - id: kernel + value: 'kernel' + brief: "When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows)." + stability: experimental + stability: experimental + deprecated: 'Replaced by `cpu.mode`' + examples: [ "user", "kernel" ] diff --git a/model/registry/deprecated/process.yaml b/model/registry/deprecated/process.yaml new file mode 100644 index 0000000000..33c5adb0cb --- /dev/null +++ b/model/registry/deprecated/process.yaml @@ -0,0 +1,21 @@ +groups: + - id: registry.process.deprecated + type: attribute_group + brief: "Deprecated process attributes." + attributes: + - id: process.cpu.state + brief: "Deprecated, use `cpu.mode` instead." + deprecated: 'Replaced by `cpu.mode`' + type: + allow_custom_values: true + members: + - id: system + value: 'system' + stability: experimental + - id: user + value: 'user' + stability: experimental + - id: wait + value: 'wait' + stability: experimental + stability: experimental diff --git a/model/registry/deprecated/system.yaml b/model/registry/deprecated/system.yaml index 700023ab57..d220a501b7 100644 --- a/model/registry/deprecated/system.yaml +++ b/model/registry/deprecated/system.yaml @@ -23,3 +23,32 @@ groups: deprecated: "Replaced by `system.process.status`." stability: experimental examples: ["running"] + - id: system.cpu.state + type: + allow_custom_values: true + members: + - id: user + value: 'user' + stability: experimental + - id: system + value: 'system' + stability: experimental + - id: nice + value: 'nice' + stability: experimental + - id: idle + value: 'idle' + stability: experimental + - id: iowait + value: 'iowait' + stability: experimental + - id: interrupt + value: 'interrupt' + stability: experimental + - id: steal + value: 'steal' + stability: experimental + brief: "Deprecated, use `cpu.mode` instead." + stability: experimental + deprecated: 'Replaced by `cpu.mode`' + examples: [ "idle", "interrupt" ] diff --git a/model/registry/process.yaml b/model/registry/process.yaml index 54c9a6fb40..7cb7451e66 100644 --- a/model/registry/process.yaml +++ b/model/registry/process.yaml @@ -196,26 +196,3 @@ groups: value: 'minor' stability: experimental stability: experimental - - - id: registry.process.cpu - prefix: process.cpu - type: attribute_group - brief: > - Attributes for process CPU - attributes: - - id: state - brief: > - The CPU state of the process. - type: - allow_custom_values: true - members: - - id: system - value: 'system' - stability: experimental - - id: user - value: 'user' - stability: experimental - - id: wait - value: 'wait' - stability: experimental - stability: experimental diff --git a/model/registry/system.yaml b/model/registry/system.yaml index d407f96d56..790a1374af 100644 --- a/model/registry/system.yaml +++ b/model/registry/system.yaml @@ -16,34 +16,6 @@ groups: type: attribute_group brief: "Describes System CPU attributes" attributes: - - id: state - type: - allow_custom_values: true - members: - - id: user - value: 'user' - stability: experimental - - id: system - value: 'system' - stability: experimental - - id: nice - value: 'nice' - stability: experimental - - id: idle - value: 'idle' - stability: experimental - - id: iowait - value: 'iowait' - stability: experimental - - id: interrupt - value: 'interrupt' - stability: experimental - - id: steal - value: 'steal' - stability: experimental - brief: "The state of the CPU" - stability: experimental - examples: ["idle", "interrupt"] - id: logical_number type: int stability: experimental diff --git a/schema-next.yaml b/schema-next.yaml index 9469bc54eb..f87f1059d9 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -41,7 +41,18 @@ versions: # https://github.com/open-telemetry/semantic-conventions/pull/1006 - rename_metrics: messaging.publish.messages: messaging.client.published.messages - + # https://github.com/open-telemetry/semantic-conventions/pull/1026 + - rename_attributes: + attribute_map: + system.cpu.state: cpu.mode + process.cpu.state: cpu.mode + container.cpu.state: cpu.mode + apply_to_metrics: + - system.cpu.time + - system.cpu.utilization + - process.cpu.time + - process.cpu.utilization + - container.cpu.time 1.26.0: metrics: changes: diff --git a/templates/registry/markdown/weaver.yaml b/templates/registry/markdown/weaver.yaml index 19cbd089a6..64e16bead2 100644 --- a/templates/registry/markdown/weaver.yaml +++ b/templates/registry/markdown/weaver.yaml @@ -10,6 +10,7 @@ acronyms: - iOS - AWS - CloudEvents + - CPU - CosmosDB - DynamoDB - ECS From 5a2836bbea0b6e105b98370f331a7661bcf19540 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 26 Jun 2024 10:19:45 +0100 Subject: [PATCH 06/11] Update kafka spring example to align with the spec (#1155) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .chloggen/1155.yaml | 4 +++ docs/messaging/kafka.md | 77 +++++++++++++++++++++++------------------ 2 files changed, 47 insertions(+), 34 deletions(-) create mode 100644 .chloggen/1155.yaml diff --git a/.chloggen/1155.yaml b/.chloggen/1155.yaml new file mode 100644 index 0000000000..4b71d69ec3 --- /dev/null +++ b/.chloggen/1155.yaml @@ -0,0 +1,4 @@ +change_type: bug_fix +component: messaging +note: Update Kafka Spring example to align with the messaging spec +issues: [ 1155 ] diff --git a/docs/messaging/kafka.md b/docs/messaging/kafka.md index cb477b56d2..14b01a072d 100644 --- a/docs/messaging/kafka.md +++ b/docs/messaging/kafka.md @@ -138,41 +138,50 @@ If an intermediary broker is present, `service.name` and `peer.service` will not ### Apache Kafka with Quarkus or Spring Boot Example -Given is a process P, that publishes a message to a topic T1 on Apache Kafka. -One process, CA, receives the message and publishes a new message to a topic T2 that is then received and processed by CB. - -Frameworks such as Quarkus and Spring Boot separate processing of a received message from producing subsequent messages out. -For this reason, receiving (Span Rcv1) is the parent of both processing (Span Proc1) and producing a new message (Span Prod2). -The span representing message receiving (Span Rcv1) should set `messaging.operation.type` to `process`, -as it does not only receive the message but also converts the input message to something suitable for the processing operation to consume and creates the output message from the result of processing. - -``` -Process P: | Span Prod1 | --- -Process CA: | Span Rcv1 | - | Span Proc1 | - | Span Prod2 | --- -Process CB: | Span Rcv2 | +In this example, the producer publishes a message to a topic T on Apache Kafka. +Consumer receives the message, processes it and commits the offset. + +Frameworks such as Quarkus and Spring Boot provide integrations with Kafka allowing to +configure and instrument processing callbacks, so corresponding instrumentations should create "Process" +spans in addition to "Receive" spans created by Kafka instrumentations for polling calls. + +```mermaid +flowchart LR; + subgraph PRODUCER + P[Span Send] + end + subgraph CONSUMER + direction TB + R1[Span Poll] + R2[Span Process] + R3[Span Commit] + end + + P-. link .-R1; + P-. link .-R2; + R2-- parent ---R3; + + classDef normal fill:green + class P,R1,R2,R3 normal + linkStyle 0 color:green,stroke:green + linkStyle 1 color:green,stroke:green ``` -| Field or Attribute | Span Prod1 | Span Rcv1 | Span Proc1 | Span Prod2 | Span Rcv2 | -|-|-|-|-|-|-| -| Span name | `"send T1"` | `"send T1"` | `"process T1"` | `"send T2"` | `"poll T2`" | -| Parent | | Span Prod1 | Span Rcv1 | Span Rcv1 | Span Prod2 | -| Links | | | | | | -| SpanKind | `PRODUCER` | `CONSUMER` | `CONSUMER` | `PRODUCER` | `CONSUMER` | -| Status | `Ok` | `Ok` | `Ok` | `Ok` | `Ok` | -| `peer.service` | `"myKafka"` | | | `"myKafka"` | | -| `service.name` | | `"myConsumer1"` | `"myConsumer1"` | | `"myConsumer2"` | -| `messaging.system` | `"kafka"` | `"kafka"` | `"kafka"` | `"kafka"` | `"kafka"` | -| `messaging.destination.name` | `"T1"` | `"T1"` | `"T1"` | `"T2"` | `"T2"` | -| `messaging.operation.name` | `send` | `send` | `"process"` | `send` | `"poll"` | -| `messaging.operation.type` | `publish` | `publish` | `"process"` | `publish` | `"receive"` | -| `messaging.client.id` | | `"5"` | `"5"` | `"5"` | `"8"` | -| `messaging.kafka.message.key` | `"myKey"` | `"myKey"` | `"myKey"` | `"anotherKey"` | `"anotherKey"` | -| `messaging.kafka.consumer.group` | | `"my-group"` | `"my-group"` | | `"another-group"` | -| `messaging.kafka.destination.partition` | `"1"` | `"1"` | `"1"` | `"3"` | `"3"` | -| `messaging.kafka.message.offset` | `"12"` | `"12"` | `"12"` | `"32"` | `"32"` | +| Field or Attribute | Span Send | Span Poll | Span Process | Span Commit T | +|-|-|-|-|-| +| Span name | `"send T"` | `"poll T"` | `"process T"` | `"commit T"` | +| Parent | | | (optional) Span Send | Span Process | +| Links | | Span Send | Span Send | | +| SpanKind | `PRODUCER` | `CONSUMER` | `SERVER` | `CLIENT` | +| Status | `UNSET` | `UNSET` | `UNSET` | `UNSET` | +| `messaging.system` | `"kafka"` | `"kafka"` | `"kafka"` | `"kafka"` | +| `messaging.destination.name` | `"T"` | `"T"` | `"T"` | `"T"` | +| `messaging.destination.consumer.group` | | `"my-group"` | `"my-group"` | `"my-group"` | +| `messaging.destination.partition.id` | `"1"` | `"1"` | `"1"` | `"1"` | +| `messaging.operation.name` | `"send"` | `"poll"` | `"process"` | `"commit"` | +| `messaging.operation.type` | `"publish"` | `"receive"` | `"process"` | `"settle"` | +| `messaging.client.id` | `"5"` | `"8"` | `"8"` | `"8"` | +| `messaging.kafka.message.key` | `"myKey"` | `"myKey"` | `"myKey"` | | +| `messaging.kafka.message.offset` | | `"12"` | `"12"` | `"12"` | [DocumentStatus]: https://opentelemetry.io/docs/specs/otel/document-status From a328d73b5b2bd8e22735dd2f0222a14daf9a8902 Mon Sep 17 00:00:00 2001 From: Ashok Chandrasekar Date: Thu, 27 Jun 2024 11:05:12 +0000 Subject: [PATCH 07/11] Add LLM model server metrics (#1103) Co-authored-by: Liudmila Molkova Co-authored-by: Drew Robbins Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .chloggen/1102.yaml | 22 +++ docs/attributes-registry/gen-ai.md | 2 +- docs/gen-ai/gen-ai-metrics.md | 246 +++++++++++++++++++++++++++-- docs/gen-ai/gen-ai-spans.md | 2 +- model/metrics/gen-ai.yaml | 36 +++++ model/registry/gen-ai.yaml | 2 +- 6 files changed, 298 insertions(+), 12 deletions(-) create mode 100755 .chloggen/1102.yaml diff --git a/.chloggen/1102.yaml b/.chloggen/1102.yaml new file mode 100755 index 0000000000..b80789491d --- /dev/null +++ b/.chloggen/1102.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: gen-ai + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add GenAI model server metrics for measuring LLM serving latency + +# 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: [1102] + +# (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/gen-ai.md b/docs/attributes-registry/gen-ai.md index 36a69ad7dc..7030cb3bd3 100644 --- a/docs/attributes-registry/gen-ai.md +++ b/docs/attributes-registry/gen-ai.md @@ -26,7 +26,7 @@ This document defines the attributes used to describe telemetry in the context o | `gen_ai.response.finish_reasons` | string[] | Array of reasons the model stopped generating tokens, corresponding to each generation received. | `["stop"]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `gen_ai.response.id` | string | The unique identifier for the completion. | `chatcmpl-123` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `gen_ai.response.model` | string | The name of the model that generated the response. | `gpt-4-0613` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.system` | string | The Generative AI product as identified by the client instrumentation. [3] | `openai` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.system` | string | The Generative AI product as identified by the client or server instrumentation. [3] | `openai` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `gen_ai.token.type` | string | The type of token being counted. | `input`; `output` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `gen_ai.usage.completion_tokens` | int | The number of tokens used in the GenAI response (completion). | `180` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `gen_ai.usage.prompt_tokens` | int | The number of tokens used in the GenAI input or prompt. | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/gen-ai/gen-ai-metrics.md b/docs/gen-ai/gen-ai-metrics.md index 8e381c00db..9f8e165cff 100644 --- a/docs/gen-ai/gen-ai-metrics.md +++ b/docs/gen-ai/gen-ai-metrics.md @@ -2,16 +2,10 @@ linkTitle: Generative AI metrics ---> -# Semantic Conventions for Generative AI Client Metrics +# Semantic Conventions for Generative AI Metrics **Status**: [Experimental][DocumentStatus] -The conventions described in this section are specific to Generative AI client -applications. - -**Disclaimer:** These are initial Generative AI client metric instruments -and attributes but more may be added in the future. - @@ -19,11 +13,21 @@ and attributes but more may be added in the future. - [Generative AI Client Metrics](#generative-ai-client-metrics) - [Metric: `gen_ai.client.token.usage`](#metric-gen_aiclienttokenusage) - [Metric: `gen_ai.client.operation.duration`](#metric-gen_aiclientoperationduration) +- [Generative AI Model Server Metrics](#generative-ai-model-server-metrics) + - [Metric: `gen_ai.server.request.duration`](#metric-gen_aiserverrequestduration) + - [Metric: `gen_ai.server.time_per_output_token`](#metric-gen_aiservertime_per_output_token) + - [Metric: `gen_ai.server.time_to_first_token`](#metric-gen_aiservertime_to_first_token) ## Generative AI Client Metrics +The conventions described in this section are specific to Generative AI client +applications. + +**Disclaimer:** These are initial Generative AI client metric instruments +and attributes but more may be added in the future. + The following metric instruments describe Generative AI operations. An operation may be a request to an LLM, a function call, or some other distinct action within a larger Generative AI workflow. @@ -69,7 +73,7 @@ This metric SHOULD be specified with [ExplicitBucketBoundaries] of [1, 4, 16, 64 |---|---|---|---|---|---| | [`gen_ai.operation.name`](/docs/attributes-registry/gen-ai.md) | string | The name of the operation being performed. | `chat`; `completion` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`gen_ai.request.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the GenAI model a request is being made to. | `gpt-4` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client instrumentation. [1] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client or server instrumentation. [1] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`gen_ai.token.type`](/docs/attributes-registry/gen-ai.md) | string | The type of token being counted. | `input`; `output` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [2] | `80`; `8080`; `443` | `Conditionally Required` If `sever.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`gen_ai.response.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the model that generated the response. | `gpt-4-0613` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -142,7 +146,7 @@ This metric SHOULD be specified with [ExplicitBucketBoundaries] of [ 0.01, 0.02, |---|---|---|---|---|---| | [`gen_ai.operation.name`](/docs/attributes-registry/gen-ai.md) | string | The name of the operation being performed. | `chat`; `completion` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`gen_ai.request.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the GenAI model a request is being made to. | `gpt-4` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client instrumentation. [1] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client or server instrumentation. [1] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`error.type`](/docs/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 the operation ended in an error | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [3] | `80`; `8080`; `443` | `Conditionally Required` If `sever.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`gen_ai.response.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the model that generated the response. | `gpt-4-0613` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -179,6 +183,230 @@ Instrumentations SHOULD document the list of errors they report. + + + + + +## Generative AI Model Server Metrics + +The following metric instruments describe Generative AI model servers' +operational metrics. It includes both functional and performance metrics. + +### Metric: `gen_ai.server.request.duration` + +This metric is [recommended][MetricRecommended] to report the model server +latency in terms of time spent per request. + +This metric SHOULD be specified with [ExplicitBucketBoundaries] of +[0.01, 0.02, 0.04, 0.08, 0.16, 0.32, 0.64, 1.28, 2.56, 5.12,10.24, 20.48, 40.96, 81.92]. + + + + + + + + +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `gen_ai.server.request.duration` | Histogram | `s` | Generative AI server request duration such as time-to-last byte or last output token | ![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 | +|---|---|---|---|---|---| +| [`gen_ai.operation.name`](/docs/attributes-registry/gen-ai.md) | string | The name of the operation being performed. | `chat`; `completion` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.request.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the GenAI model a request is being made to. | `gpt-4` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client or server instrumentation. [1] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`error.type`](/docs/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 the operation ended in an error | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [3] | `80`; `8080`; `443` | `Conditionally Required` If `sever.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`gen_ai.response.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the model that generated the response. | `gpt-4-0613` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +**[1]:** The actual GenAI product may differ from the one identified by the client. For example, when using OpenAI client libraries to communicate with Mistral, the `gen_ai.system` is set to `openai` based on the instrumentation's best knowledge. +For custom model, a custom friendly name SHOULD be used. If none of these options apply, the `gen_ai.system` SHOULD be set to `_OTHER`. + +**[2]:** The `error.type` SHOULD match the error code returned by the Generative AI service, +the canonical name of exception that occurred, or another low-cardinality error identifier. +Instrumentations SHOULD document the list of errors they report. + +**[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]:** 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. + + + +`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) | + + +`gen_ai.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 | +|---|---|---| +| `anthropic` | Anthropic | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cohere` | Cohere | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `openai` | OpenAI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `vertex_ai` | Vertex AI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + + + + + + + +### Metric: `gen_ai.server.time_per_output_token` + +This metric is [recommended][MetricRecommended] to report the model server +latency in terms of time per token generated after the first token for any model +servers which support serving LLMs. It is measured by subtracting the time taken +to generate the first output token from the request duration and dividing the +rest of the duration by the number of output tokens generated after the first +token. This is important in measuring the performance of the decode phase of LLM +inference. + +This metric SHOULD be specified with [ExplicitBucketBoundaries] of +[0.01, 0.025, 0.05, 0.075, 0.1, 0.15, 0.2, 0.3, 0.4, 0.5, 0.75, 1.0, 2.5]. + + + + + + + + +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `gen_ai.server.time_per_output_token` | Histogram | `s` | Time per output token generated after the first token for successful responses | ![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 | +|---|---|---|---|---|---| +| [`gen_ai.operation.name`](/docs/attributes-registry/gen-ai.md) | string | The name of the operation being performed. | `chat`; `completion` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.request.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the GenAI model a request is being made to. | `gpt-4` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client or server instrumentation. [1] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [2] | `80`; `8080`; `443` | `Conditionally Required` If `sever.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`gen_ai.response.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the model that generated the response. | `gpt-4-0613` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +**[1]:** The actual GenAI product may differ from the one identified by the client. For example, when using OpenAI client libraries to communicate with Mistral, the `gen_ai.system` is set to `openai` based on the instrumentation's best knowledge. +For custom model, a custom friendly name SHOULD be used. If none of these options apply, the `gen_ai.system` SHOULD be set to `_OTHER`. + +**[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]:** 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. + + + +`gen_ai.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 | +|---|---|---| +| `anthropic` | Anthropic | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cohere` | Cohere | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `openai` | OpenAI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `vertex_ai` | Vertex AI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + + + + + + + +### Metric: `gen_ai.server.time_to_first_token` + +This metric is [recommended][MetricRecommended] to report the model server +latency in terms of time spent to generate the first token of the response for +any model servers which support serving LLMs. It helps measure the time spent in +the queue and the prefill phase. It is important especially for streaming +requests. It is calculated at a request level and is reported as a histogram +using the buckets mentioned below. + +This metric SHOULD be specified with [ExplicitBucketBoundaries] of +[0.001, 0.005, 0.01, 0.02, 0.04, 0.06, 0.08, 0.1, 0.25, 0.5, 0.75, 1.0, 2.5, 5.0, 7.5, 10.0]. + + + + + + + + +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `gen_ai.server.time_to_first_token` | Histogram | `s` | Time to generate first token for successful responses | ![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 | +|---|---|---|---|---|---| +| [`gen_ai.operation.name`](/docs/attributes-registry/gen-ai.md) | string | The name of the operation being performed. | `chat`; `completion` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.request.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the GenAI model a request is being made to. | `gpt-4` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client or server instrumentation. [1] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [2] | `80`; `8080`; `443` | `Conditionally Required` If `sever.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`gen_ai.response.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the model that generated the response. | `gpt-4-0613` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +**[1]:** The actual GenAI product may differ from the one identified by the client. For example, when using OpenAI client libraries to communicate with Mistral, the `gen_ai.system` is set to `openai` based on the instrumentation's best knowledge. +For custom model, a custom friendly name SHOULD be used. If none of these options apply, the `gen_ai.system` SHOULD be set to `_OTHER`. + +**[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]:** 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. + + + +`gen_ai.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 | +|---|---|---| +| `anthropic` | Anthropic | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cohere` | Cohere | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `openai` | OpenAI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `vertex_ai` | Vertex AI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + + diff --git a/docs/gen-ai/gen-ai-spans.md b/docs/gen-ai/gen-ai-spans.md index d6837106df..d2fb54b987 100644 --- a/docs/gen-ai/gen-ai-spans.md +++ b/docs/gen-ai/gen-ai-spans.md @@ -46,7 +46,7 @@ These attributes track input data and metadata for a request to an GenAI model. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`gen_ai.request.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the GenAI model a request is being made to. [1] | `gpt-4` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client instrumentation. [2] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client or server instrumentation. [2] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`gen_ai.request.frequency_penalty`](/docs/attributes-registry/gen-ai.md) | double | The frequency penalty setting for the GenAI request. | `0.1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`gen_ai.request.max_tokens`](/docs/attributes-registry/gen-ai.md) | int | The maximum number of tokens the model generates for a request. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`gen_ai.request.presence_penalty`](/docs/attributes-registry/gen-ai.md) | double | The presence penalty setting for the GenAI request. | `0.1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/model/metrics/gen-ai.yaml b/model/metrics/gen-ai.yaml index 8398e8f0c6..7c9979cf21 100644 --- a/model/metrics/gen-ai.yaml +++ b/model/metrics/gen-ai.yaml @@ -16,6 +16,18 @@ groups: requirement_level: required - ref: gen_ai.operation.name requirement_level: required + - id: metric_attributes.gen_ai.server + type: attribute_group + brief: 'This group describes GenAI server metrics attributes' + extends: metric_attributes.gen_ai + attributes: + - ref: error.type + requirement_level: + conditionally_required: "if the operation ended in an error" + note: | + The `error.type` SHOULD match the error code returned by the Generative AI service, + the canonical name of exception that occurred, or another low-cardinality error identifier. + Instrumentations SHOULD document the list of errors they report. - id: metric.gen_ai.client.token.usage type: metric metric_name: gen_ai.client.token.usage @@ -43,3 +55,27 @@ groups: The `error.type` SHOULD match the error code returned by the Generative AI provider or the client library, the canonical name of exception that occurred, or another low-cardinality error identifier. Instrumentations SHOULD document the list of errors they report. + - id: metric.gen_ai.server.request.duration + type: metric + metric_name: gen_ai.server.request.duration + brief: 'Generative AI server request duration such as time-to-last byte or last output token' + instrument: histogram + unit: "s" + stability: experimental + extends: metric_attributes.gen_ai.server + - id: metric.gen_ai.server.time_per_output_token + type: metric + metric_name: gen_ai.server.time_per_output_token + brief: 'Time per output token generated after the first token for successful responses' + instrument: histogram + unit: "s" + stability: experimental + extends: metric_attributes.gen_ai + - id: metric.gen_ai.server.time_to_first_token + type: metric + metric_name: gen_ai.server.time_to_first_token + brief: 'Time to generate first token for successful responses' + instrument: histogram + unit: "s" + stability: experimental + extends: metric_attributes.gen_ai diff --git a/model/registry/gen-ai.yaml b/model/registry/gen-ai.yaml index 394f053a21..2bbf16e7c4 100644 --- a/model/registry/gen-ai.yaml +++ b/model/registry/gen-ai.yaml @@ -25,7 +25,7 @@ groups: stability: experimental value: "cohere" brief: 'Cohere' - brief: The Generative AI product as identified by the client instrumentation. + brief: The Generative AI product as identified by the client or server instrumentation. note: > The actual GenAI product may differ from the one identified by the client. For example, when using OpenAI client libraries to communicate with Mistral, the `gen_ai.system` From ba4c418ff7736a5878f9782211a02f207aadbfe3 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 27 Jun 2024 09:48:09 -0700 Subject: [PATCH 08/11] Remove unreleased section from the middle of the changelog (#1189) --- CHANGELOG.md | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a4f606d30..dd3b88f886 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,7 @@ - `device.app.lifecycle`: Reformat and update the `device.app.lifecycle` event description adds constraints for the possible values of the `android.state` and `ios.state`. (#794) 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. - + - `messaging`: Rename `messaging.client_id` to `messaging.client.id` (#935) - `rpc`: Rename`message.*` attributes under `rpc` to `rpc.message.*`. Deprecate old `message.*` attributes. (#854) @@ -51,7 +51,7 @@ The entirety of the registry now is generated using weaver with templates under the `templates/` directory. Snippets still require a hardcoded command. - + - `http`: List all HTTP client and server attributes in the corresponding table, remove common attributes from yaml and markdown. (#928) - `other`: Document patterns and suggestions for semconv code generation. (#551, #953) - `db`: Show applicable common attributes in individual database semantic conventions. (#973) @@ -72,14 +72,6 @@ - `net`: Add previously deprecated net attributes to registry (#1029) These attributes were deprecated in 1.13 -## Unreleased - -### Breaking - -### Features - -### Fixes - ## v1.25.0 ### 🛑 Breaking changes 🛑 From 5077fd5ccf64e3ad0821866cc80d77bb24098ba2 Mon Sep 17 00:00:00 2001 From: Marylia Gutierrez Date: Fri, 28 Jun 2024 15:10:11 -0400 Subject: [PATCH 09/11] Add node.js runtime metrics semantic conventions (#991) Signed-off-by: maryliag Co-authored-by: Liudmila Molkova --- .chloggen/nodejs-metrics.yaml | 17 ++ docs/runtime/README.md | 3 +- docs/runtime/nodejs-metrics.md | 343 ++++++++++++++++++++++++ model/metrics/nodejs-metrics.yaml | 81 ++++++ templates/registry/markdown/weaver.yaml | 1 + 5 files changed, 444 insertions(+), 1 deletion(-) create mode 100755 .chloggen/nodejs-metrics.yaml create mode 100644 docs/runtime/nodejs-metrics.md create mode 100644 model/metrics/nodejs-metrics.yaml diff --git a/.chloggen/nodejs-metrics.yaml b/.chloggen/nodejs-metrics.yaml new file mode 100755 index 0000000000..51b11a961e --- /dev/null +++ b/.chloggen/nodejs-metrics.yaml @@ -0,0 +1,17 @@ +# 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: new_component + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: nodejs + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Introducing semantic conventions for Node.js runtime metrics. + +# 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: [990] diff --git a/docs/runtime/README.md b/docs/runtime/README.md index bcabd1d7b6..0d0dd6033f 100644 --- a/docs/runtime/README.md +++ b/docs/runtime/README.md @@ -47,8 +47,9 @@ Also consider the [OS process metrics](/docs/system/process-metrics.md) semantic conventions when instrumenting runtime environments. -- [JVM](jvm-metrics.md) - [Go](go-metrics.md) +- [JVM](jvm-metrics.md) +- [Node.js](nodejs-metrics.md) ### Attributes diff --git a/docs/runtime/nodejs-metrics.md b/docs/runtime/nodejs-metrics.md new file mode 100644 index 0000000000..60fcd283af --- /dev/null +++ b/docs/runtime/nodejs-metrics.md @@ -0,0 +1,343 @@ + + +# Semantic Conventions for Node.js Runtime Metrics + +**Status**: [Experimental][DocumentStatus] + +This document describes semantic conventions for Node.js Runtime metrics in OpenTelemetry. + + + + + +- [Experimental](#experimental) + - [Metric: `nodejs.eventloop.delay.min`](#metric-nodejseventloopdelaymin) + - [Metric: `nodejs.eventloop.delay.max`](#metric-nodejseventloopdelaymax) + - [Metric: `nodejs.eventloop.delay.mean`](#metric-nodejseventloopdelaymean) + - [Metric: `nodejs.eventloop.delay.stddev`](#metric-nodejseventloopdelaystddev) + - [Metric: `nodejs.eventloop.delay.p50`](#metric-nodejseventloopdelayp50) + - [Metric: `nodejs.eventloop.delay.p90`](#metric-nodejseventloopdelayp90) + - [Metric: `nodejs.eventloop.delay.p99`](#metric-nodejseventloopdelayp99) + - [Metric: `nodejs.eventloop.utilization`](#metric-nodejseventlooputilization) + + + +## Experimental + +**Status**: [Experimental][DocumentStatus] + +**Description:** Experimental Node.js Runtime metrics captured under `nodejs`. + +Note: The metrics for eventloop delay are split into separated values instead of a single histogram, because node runtime +only returns single values through [`perf_hooks.monitorEventLoopDelay([options])`][Eventloop] and not the entire +histogram, so it's not possible to convert it to an OpenTelemetry histogram. + +### Metric: `nodejs.eventloop.delay.min` + +This metric is [recommended][MetricRecommended]. + + + + + + + + +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `nodejs.eventloop.delay.min` | Gauge | `s` | Event loop minimum delay. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +**[1]:** Value can be retrieved from value `histogram.min` of [`perf_hooks.monitorEventLoopDelay([options])`](https://nodejs.org/api/perf_hooks.html#perf_hooksmonitoreventloopdelayoptions) + + + + + + + + + + + + + + + + + + + + + +### Metric: `nodejs.eventloop.delay.max` + +This metric is [recommended][MetricRecommended]. + + + + + + + + +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `nodejs.eventloop.delay.max` | Gauge | `s` | Event loop maximum delay. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +**[1]:** Value can be retrieved from value `histogram.max` of [`perf_hooks.monitorEventLoopDelay([options])`](https://nodejs.org/api/perf_hooks.html#perf_hooksmonitoreventloopdelayoptions) + + + + + + + + + + + + + + + + + + + + + +### Metric: `nodejs.eventloop.delay.mean` + +This metric is [recommended][MetricRecommended]. + + + + + + + + +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `nodejs.eventloop.delay.mean` | Gauge | `s` | Event loop mean delay. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +**[1]:** Value can be retrieved from value `histogram.mean` of [`perf_hooks.monitorEventLoopDelay([options])`](https://nodejs.org/api/perf_hooks.html#perf_hooksmonitoreventloopdelayoptions) + + + + + + + + + + + + + + + + + + + + + +### Metric: `nodejs.eventloop.delay.stddev` + +This metric is [recommended][MetricRecommended]. + + + + + + + + +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `nodejs.eventloop.delay.stddev` | Gauge | `s` | Event loop standard deviation delay. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +**[1]:** Value can be retrieved from value `histogram.stddev` of [`perf_hooks.monitorEventLoopDelay([options])`](https://nodejs.org/api/perf_hooks.html#perf_hooksmonitoreventloopdelayoptions) + + + + + + + + + + + + + + + + + + + + + +### Metric: `nodejs.eventloop.delay.p50` + +This metric is [recommended][MetricRecommended]. + + + + + + + + +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `nodejs.eventloop.delay.p50` | Gauge | `s` | Event loop 50 percentile delay. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +**[1]:** Value can be retrieved from value `histogram.percentile(50)` of [`perf_hooks.monitorEventLoopDelay([options])`](https://nodejs.org/api/perf_hooks.html#perf_hooksmonitoreventloopdelayoptions) + + + + + + + + + + + + + + + + + + + + + +### Metric: `nodejs.eventloop.delay.p90` + +This metric is [recommended][MetricRecommended]. + + + + + + + + +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `nodejs.eventloop.delay.p90` | Gauge | `s` | Event loop 90 percentile delay. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +**[1]:** Value can be retrieved from value `histogram.percentile(90)` of [`perf_hooks.monitorEventLoopDelay([options])`](https://nodejs.org/api/perf_hooks.html#perf_hooksmonitoreventloopdelayoptions) + + + + + + + + + + + + + + + + + + + + + +### Metric: `nodejs.eventloop.delay.p99` + +This metric is [recommended][MetricRecommended]. + + + + + + + + +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `nodejs.eventloop.delay.p99` | Gauge | `s` | Event loop 99 percentile delay. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +**[1]:** Value can be retrieved from value `histogram.percentile(99)` of [`perf_hooks.monitorEventLoopDelay([options])`](https://nodejs.org/api/perf_hooks.html#perf_hooksmonitoreventloopdelayoptions) + + + + + + + + + + + + + + + + + + + + + +### Metric: `nodejs.eventloop.utilization` + +This metric is [recommended][MetricRecommended]. + + + + + + + + +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `nodejs.eventloop.utilization` | Gauge | `1` | Event loop utilization. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +**[1]:** The value range is [0.0,1.0] and can be retrieved from value [`performance.eventLoopUtilization([utilization1[, utilization2]])`](https://nodejs.org/api/perf_hooks.html#performanceeventlooputilizationutilization1-utilization2) + + + + + + + + + + + + + + + + + + + + + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md +[MetricRecommended]: /docs/general/metric-requirement-level.md#recommended +[Eventloop]: https://nodejs.org/api/perf_hooks.html#perf_hooksmonitoreventloopdelayoptions diff --git a/model/metrics/nodejs-metrics.yaml b/model/metrics/nodejs-metrics.yaml new file mode 100644 index 0000000000..9def4fa143 --- /dev/null +++ b/model/metrics/nodejs-metrics.yaml @@ -0,0 +1,81 @@ +groups: + - id: metric.nodejs.eventloop.delay.min + type: metric + metric_name: nodejs.eventloop.delay.min + brief: "Event loop minimum delay." + instrument: gauge + unit: "s" + stability: experimental + note: > + Value can be retrieved from value `histogram.min` of [`perf_hooks.monitorEventLoopDelay([options])`](https://nodejs.org/api/perf_hooks.html#perf_hooksmonitoreventloopdelayoptions) + + - id: metric.nodejs.eventloop.delay.max + type: metric + metric_name: nodejs.eventloop.delay.max + brief: "Event loop maximum delay." + instrument: gauge + unit: "s" + stability: experimental + note: > + Value can be retrieved from value `histogram.max` of [`perf_hooks.monitorEventLoopDelay([options])`](https://nodejs.org/api/perf_hooks.html#perf_hooksmonitoreventloopdelayoptions) + + - id: metric.nodejs.eventloop.delay.mean + type: metric + metric_name: nodejs.eventloop.delay.mean + brief: "Event loop mean delay." + instrument: gauge + unit: "s" + stability: experimental + note: > + Value can be retrieved from value `histogram.mean` of [`perf_hooks.monitorEventLoopDelay([options])`](https://nodejs.org/api/perf_hooks.html#perf_hooksmonitoreventloopdelayoptions) + + - id: metric.nodejs.eventloop.delay.stddev + type: metric + metric_name: nodejs.eventloop.delay.stddev + brief: "Event loop standard deviation delay." + instrument: gauge + unit: "s" + stability: experimental + note: > + Value can be retrieved from value `histogram.stddev` of [`perf_hooks.monitorEventLoopDelay([options])`](https://nodejs.org/api/perf_hooks.html#perf_hooksmonitoreventloopdelayoptions) + + - id: metric.nodejs.eventloop.delay.pfifty + type: metric + metric_name: nodejs.eventloop.delay.p50 + brief: "Event loop 50 percentile delay." + instrument: gauge + unit: "s" + stability: experimental + note: > + Value can be retrieved from value `histogram.percentile(50)` of [`perf_hooks.monitorEventLoopDelay([options])`](https://nodejs.org/api/perf_hooks.html#perf_hooksmonitoreventloopdelayoptions) + + - id: metric.nodejs.eventloop.delay.pninety + type: metric + metric_name: nodejs.eventloop.delay.p90 + brief: "Event loop 90 percentile delay." + instrument: gauge + unit: "s" + stability: experimental + note: > + Value can be retrieved from value `histogram.percentile(90)` of [`perf_hooks.monitorEventLoopDelay([options])`](https://nodejs.org/api/perf_hooks.html#perf_hooksmonitoreventloopdelayoptions) + + - id: metric.nodejs.eventloop.delay.pninety_nine + type: metric + metric_name: nodejs.eventloop.delay.p99 + brief: "Event loop 99 percentile delay." + instrument: gauge + unit: "s" + stability: experimental + note: > + Value can be retrieved from value `histogram.percentile(99)` of [`perf_hooks.monitorEventLoopDelay([options])`](https://nodejs.org/api/perf_hooks.html#perf_hooksmonitoreventloopdelayoptions) + + - id: metric.nodejs.eventloop.utilization + type: metric + metric_name: nodejs.eventloop.utilization + brief: "Event loop utilization." + instrument: gauge + unit: "1" + stability: experimental + note: > + The value range is [0.0,1.0] and can be retrieved from value + [`performance.eventLoopUtilization([utilization1[, utilization2]])`](https://nodejs.org/api/perf_hooks.html#performanceeventlooputilizationutilization1-utilization2) diff --git a/templates/registry/markdown/weaver.yaml b/templates/registry/markdown/weaver.yaml index 64e16bead2..f698ae6754 100644 --- a/templates/registry/markdown/weaver.yaml +++ b/templates/registry/markdown/weaver.yaml @@ -20,6 +20,7 @@ acronyms: - GCE - HTTP - JVM + - NodeJS - OCI - OTel - OpenTracing From 0f067bb98f9e5a008f837a02edc43a1fdc4339ed Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 3 Jul 2024 12:25:43 -0400 Subject: [PATCH 10/11] Bump weaver to latest version. (#1207) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1b6b4f499d..b2af508988 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ CHLOGGEN_CONFIG := .chloggen/config.yaml # see https://github.com/open-telemetry/build-tools/releases for semconvgen updates # Keep links in model/README.md and .vscode/settings.json in sync! SEMCONVGEN_VERSION=0.24.0 -WEAVER_VERSION=0.2.0 +WEAVER_VERSION=0.5.0 # From where to resolve the containers (e.g. "otel/weaver"). CONTAINER_REPOSITORY=docker.io From 5971366ae2fcaf2d01b1a52da92e872b7df5491d Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 4 Jul 2024 08:41:54 -0700 Subject: [PATCH 11/11] GenAI: Rename prompt and completion tokens attributes to input and output (#1200) --- .chloggen/1200.yaml | 6 ++++++ docs/attributes-registry/gen-ai.md | 16 ++++++++++++++-- docs/gen-ai/gen-ai-spans.md | 4 ++-- model/registry/deprecated/gen-ai.yaml | 17 +++++++++++++++++ model/registry/gen-ai.yaml | 6 +++--- model/trace/gen-ai.yaml | 4 ++-- schema-next.yaml | 5 +++++ 7 files changed, 49 insertions(+), 9 deletions(-) create mode 100644 .chloggen/1200.yaml create mode 100644 model/registry/deprecated/gen-ai.yaml diff --git a/.chloggen/1200.yaml b/.chloggen/1200.yaml new file mode 100644 index 0000000000..9d40d16961 --- /dev/null +++ b/.chloggen/1200.yaml @@ -0,0 +1,6 @@ +change_type: enhancement +component: gen_ai +note: > + Rename `gen_ai.usage.prompt_tokens` to `gen_ai.usage.input_tokens` and `gen_ai.usage.completion_tokens` to `gen_ai.usage.output_tokens` + to align terminology between spans and metrics. +issues: [ 1200 ] diff --git a/docs/attributes-registry/gen-ai.md b/docs/attributes-registry/gen-ai.md index 7030cb3bd3..753b0c35e1 100644 --- a/docs/attributes-registry/gen-ai.md +++ b/docs/attributes-registry/gen-ai.md @@ -6,6 +6,9 @@ # Gen AI +- [Gen Ai](#gen-ai-attributes) +- [Gen Ai Deprecated](#gen-ai-deprecated-attributes) + ## Gen AI Attributes This document defines the attributes used to describe telemetry in the context of Generative Artificial Intelligence (GenAI) Models requests and responses. @@ -28,8 +31,8 @@ This document defines the attributes used to describe telemetry in the context o | `gen_ai.response.model` | string | The name of the model that generated the response. | `gpt-4-0613` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `gen_ai.system` | string | The Generative AI product as identified by the client or server instrumentation. [3] | `openai` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `gen_ai.token.type` | string | The type of token being counted. | `input`; `output` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.usage.completion_tokens` | int | The number of tokens used in the GenAI response (completion). | `180` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.usage.prompt_tokens` | int | The number of tokens used in the GenAI input or prompt. | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.usage.input_tokens` | int | The number of tokens used in the GenAI input (prompt). | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.usage.output_tokens` | int | The number of tokens used in the GenAI response (completion). | `180` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** It's RECOMMENDED to format completions as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation) @@ -53,3 +56,12 @@ For custom model, a custom friendly name SHOULD be used. If none of these option | -------- | ------------------------------------------ | ---------------------------------------------------------------- | | `input` | Input tokens (prompt, input, etc.) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `output` | Output tokens (completion, response, etc.) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +## Gen AI Deprecated Attributes + +Describes deprecated `gen_ai` attributes. + +| Attribute | Type | Description | Examples | Stability | +| -------------------------------- | ---- | ----------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------ | +| `gen_ai.usage.completion_tokens` | int | Deprecated, use `gen_ai.usage.output_tokens` instead. | `42` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `gen_ai.usage.output_tokens` attribute. | +| `gen_ai.usage.prompt_tokens` | int | Deprecated, use `gen_ai.usage.input_tokens` instead. | `42` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `gen_ai.usage.input_tokens` attribute. | diff --git a/docs/gen-ai/gen-ai-spans.md b/docs/gen-ai/gen-ai-spans.md index d2fb54b987..1615d18c48 100644 --- a/docs/gen-ai/gen-ai-spans.md +++ b/docs/gen-ai/gen-ai-spans.md @@ -57,8 +57,8 @@ These attributes track input data and metadata for a request to an GenAI model. | [`gen_ai.response.finish_reasons`](/docs/attributes-registry/gen-ai.md) | string[] | Array of reasons the model stopped generating tokens, corresponding to each generation received. | `["stop"]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`gen_ai.response.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier for the completion. | `chatcmpl-123` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`gen_ai.response.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the model that generated the response. [3] | `gpt-4-0613` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gen_ai.usage.completion_tokens`](/docs/attributes-registry/gen-ai.md) | int | The number of tokens used in the GenAI response (completion). | `180` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gen_ai.usage.prompt_tokens`](/docs/attributes-registry/gen-ai.md) | int | The number of tokens used in the GenAI input or prompt. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.usage.input_tokens`](/docs/attributes-registry/gen-ai.md) | int | The number of tokens used in the GenAI input (prompt). | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.usage.output_tokens`](/docs/attributes-registry/gen-ai.md) | int | The number of tokens used in the GenAI response (completion). | `180` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The name of the GenAI model a request is being made to. If the model is supplied by a vendor, then the value must be the exact name of the model requested. If the model is a fine-tuned custom model, the value should have a more specific name than the base model that's been fine-tuned. diff --git a/model/registry/deprecated/gen-ai.yaml b/model/registry/deprecated/gen-ai.yaml new file mode 100644 index 0000000000..ca6abd6732 --- /dev/null +++ b/model/registry/deprecated/gen-ai.yaml @@ -0,0 +1,17 @@ +groups: + - id: registry.gen_ai.deprecated + type: attribute_group + brief: Describes deprecated `gen_ai` attributes. + attributes: + - id: gen_ai.usage.prompt_tokens + type: int + stability: experimental + deprecated: Replaced by `gen_ai.usage.input_tokens` attribute. + brief: "Deprecated, use `gen_ai.usage.input_tokens` instead." + examples: [42] + - id: gen_ai.usage.completion_tokens + type: int + stability: experimental + deprecated: Replaced by `gen_ai.usage.output_tokens` attribute. + brief: "Deprecated, use `gen_ai.usage.output_tokens` instead." + examples: [42] diff --git a/model/registry/gen-ai.yaml b/model/registry/gen-ai.yaml index 2bbf16e7c4..06b994bfc0 100644 --- a/model/registry/gen-ai.yaml +++ b/model/registry/gen-ai.yaml @@ -90,12 +90,12 @@ groups: type: string[] brief: Array of reasons the model stopped generating tokens, corresponding to each generation received. examples: ['stop'] - - id: usage.prompt_tokens + - id: usage.input_tokens stability: experimental type: int - brief: The number of tokens used in the GenAI input or prompt. + brief: The number of tokens used in the GenAI input (prompt). examples: [100] - - id: usage.completion_tokens + - id: usage.output_tokens stability: experimental type: int brief: The number of tokens used in the GenAI response (completion). diff --git a/model/trace/gen-ai.yaml b/model/trace/gen-ai.yaml index ef77733e83..1c2418efab 100644 --- a/model/trace/gen-ai.yaml +++ b/model/trace/gen-ai.yaml @@ -36,9 +36,9 @@ groups: fine-tuned custom model, the value should have a more specific name than the base model that's been fine-tuned. - ref: gen_ai.response.finish_reasons requirement_level: recommended - - ref: gen_ai.usage.prompt_tokens + - ref: gen_ai.usage.input_tokens requirement_level: recommended - - ref: gen_ai.usage.completion_tokens + - ref: gen_ai.usage.output_tokens requirement_level: recommended events: - gen_ai.content.prompt diff --git a/schema-next.yaml b/schema-next.yaml index f87f1059d9..b2d310bd77 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -11,6 +11,11 @@ versions: messaging.rocketmq.client_group: messaging.consumer.group.name messaging.evenhubs.consumer.group: messaging.consumer.group.name message.servicebus.destination.subscription_name: messaging.destination.subscription.name + # https://github.com/open-telemetry/semantic-conventions/pull/1200 + - rename_attributes: + attribute_map: + gen_ai.usage.completion_tokens: gen_ai.usage.output_tokens + gen_ai.usage.prompt_tokens: gen_ai.usage.input_tokens spans: changes: # https://github.com/open-telemetry/semantic-conventions/pull/1002