From f51df2fdbcadef64686da1d037b09707403ab260 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 30 Nov 2023 08:06:23 -0800 Subject: [PATCH] Define messaging metrics and add `error.type` attribute to spans (#163) --- CHANGELOG.md | 2 + docs/messaging/README.md | 1 + docs/messaging/messaging-metrics.md | 182 ++++++++++++++++++++++++++++ docs/messaging/messaging-spans.md | 100 +++++++++------ model/messaging-common.yaml | 23 ++++ model/metrics/messaging.yaml | 62 ++++++++++ model/trace/messaging.yaml | 10 +- 7 files changed, 335 insertions(+), 45 deletions(-) create mode 100644 docs/messaging/messaging-metrics.md create mode 100644 model/messaging-common.yaml create mode 100644 model/metrics/messaging.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index e27d9b938e..201ae39221 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,8 @@ release. ([#21](https://github.com/open-telemetry/semantic-conventions/pull/21)) - Add `messaging.gcp_pubsub.message.ordering_key` attribute. ([#528](https://github.com/open-telemetry/semantic-conventions/pull/528)) +- Add messaging metrics + ([#163](https://github.com/open-telemetry/semantic-conventions/pull/163)) ### Fixes diff --git a/docs/messaging/README.md b/docs/messaging/README.md index 39b488e05e..5308786270 100644 --- a/docs/messaging/README.md +++ b/docs/messaging/README.md @@ -14,6 +14,7 @@ This document defines semantic conventions for messaging systems spans, metrics Semantic conventions for messaging systems are defined for the following signals: * [Messaging Spans](messaging-spans.md): Semantic Conventions for messaging *spans*. +* [Messaging Metrics](messaging-metrics.md): Semantic Conventions for messaging *metrics*. Technology specific semantic conventions are defined for the following messaging systems: diff --git a/docs/messaging/messaging-metrics.md b/docs/messaging/messaging-metrics.md new file mode 100644 index 0000000000..b2f7046bdd --- /dev/null +++ b/docs/messaging/messaging-metrics.md @@ -0,0 +1,182 @@ +# Semantic Conventions for Messaging Metrics + +**Status**: [Experimental][DocumentStatus] + + + + + +- [Common attributes](#common-attributes) +- [Producer metrics](#producer-metrics) + * [Metric: `messaging.publish.duration`](#metric-messagingpublishduration) + * [Metric: `messaging.publish.messages`](#metric-messagingpublishmessages) +- [Consumer metrics](#consumer-metrics) + * [Metric: `messaging.receive.duration`](#metric-messagingreceiveduration) + * [Metric: `messaging.receive.messages`](#metric-messagingreceivemessages) + * [Metric: `messaging.deliver.duration`](#metric-messagingdeliverduration) + * [Metric: `messaging.deliver.messages`](#metric-messagingdelivermessages) + + + +## Common attributes + +All messaging metrics share the same set of attributes: + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | Conditionally Required: [2] | +| [`messaging.destination.name`](../attributes-registry/messaging.md) | string | The message destination name [3] | `MyQueue`; `MyTopic` | Conditionally Required: [4] | +| [`messaging.destination.template`](../attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [5] | `/customers/{customerId}` | Conditionally Required: if available. | +| [`messaging.system`](../attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq` | Required | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [6] | `amqp`; `mqtt` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [7] | `3.1.1` | Recommended | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [9] | `80`; `8080`; `443` | Recommended | + +**[1]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low. +Telemetry consumers that aggregate data from multiple instrumentation libraries and applications +should be prepared for `error.type` to have high cardinality at query time when no +additional filters are applied. + +If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. + +If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), +it's RECOMMENDED to: + +* Use a domain-specific attribute +* Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. + +**[2]:** If and only if the messaging operation has failed. + +**[3]:** Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If +the broker doesn't have such notion, the destination name SHOULD uniquely identify the broker. + +**[4]:** if and only if `messaging.destination.name` is known to have low cardinality. Otherwise, `messaging.destination.template` MAY be populated. + +**[5]:** Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. + +**[6]:** The value SHOULD be normalized to lowercase. + +**[7]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + +**[8]:** This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. + +**[9]:** 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. + +`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 | +|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | + +`messaging.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 | +|---|---| +| `activemq` | Apache ActiveMQ | +| `aws_sqs` | Amazon Simple Queue Service (SQS) | +| `azure_eventgrid` | Azure Event Grid | +| `azure_eventhubs` | Azure Event Hubs | +| `azure_servicebus` | Azure Service Bus | +| `gcp_pubsub` | Google Cloud Pub/Sub | +| `jms` | Java Message Service | +| `kafka` | Apache Kafka | +| `rabbitmq` | RabbitMQ | +| `rocketmq` | Apache RocketMQ | + + +## Producer metrics + +### Metric: `messaging.publish.duration` + +This metric is [required][MetricRequired]. + +When this metric is reported alongside a messaging publish span, the metric value SHOULD be the same as the corresponding span duration. + +This metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advice) +of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `messaging.publish.duration` | Histogram | `s` | Measures the duration of publish operation. | + + +### Metric: `messaging.publish.messages` + +This metric is [required][MetricRequired] when the messaging system supports batch publishing. It's [opt-in][MetricOptIn] when the messaging system does not support batch publishing, since the message count can be derived from the `messaging.publish.duration` histogram. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `messaging.publish.messages` | Counter | `{message}` | Measures the number of published messages. | + + +> The need to report `messaging.publish.messages` depends on the messaging system capabilities and not application scenarios or client library limitations. For example, RabbitMQ does not support batch publishing and corresponding instrumentations don't need to report `messaging.publish.messages`. Kafka supports both, single and batch publishing, and instrumentations MUST report `messaging.publish.messages` counter regardless of application scenarios or APIs available in the client library. + +## Consumer metrics + +### Metric: `messaging.receive.duration` + +This metric is [required][MetricRequired] for operations that are initiated by the application code (pull-based). + +This metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advice) +of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. + +When this metric is reported alongside a messaging receive span, the metric value SHOULD be the same as the corresponding span duration. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `messaging.receive.duration` | Histogram | `s` | Measures the duration of receive operation. | + + +### Metric: `messaging.receive.messages` + +This metric is [required][MetricRequired] for batch receive operations. It's [opt-in][MetricOptIn] when the messaging system does not support batch receive since the message count can be derived from the `messaging.receive.duration` histogram. + +_Note: The need to report `messaging.receive.messages` depends on the messaging system capabilities and not application scenarios or client library limitations._ + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `messaging.receive.messages` | Counter | `{message}` | Measures the number of received messages. | + + +### Metric: `messaging.deliver.duration` + +This metric is [required][MetricRequired] for operations are not initiated by the application code (push-based deliver). + +When this metric is reported alongside a messaging deliver span, the metric value SHOULD be the same as the corresponding span duration. + +This metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advice) +of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `messaging.deliver.duration` | Histogram | `s` | Measures the duration of deliver operation. | + + +### Metric: `messaging.deliver.messages` + +This metric is [required][MetricRequired] for batch delivery operations. It's [opt-in][MetricOptIn] when the messaging system does not support batch delivery since the message count can be derived from the `messaging.deliver.duration` histogram. + +_Note: The need to report `messaging.deliver.messages` depends on the messaging system capabilities and not application scenarios or client library limitations._ + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `messaging.deliver.messages` | Counter | `{message}` | Measures the number of delivered messages. | + + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/document-status.md +[MetricRequired]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/metrics/metric-requirement-level.md#required +[MetricOptIn]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/metrics/metric-requirement-level.md#opt-in diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index eb1d1ffce6..7562e2972b 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -1,4 +1,4 @@ -# Messaging Systems +# Semantic Conventions for Messaging Spans **Status**: [Experimental][DocumentStatus] @@ -275,72 +275,100 @@ messages were received). For each message it accounts for, the "Deliver" or | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`messaging.batch.message_count`](../attributes-registry/messaging.md) | int | The number of messages sent, received, or processed in the scope of the batching operation. [1] | `0`; `1`; `2` | Conditionally Required: [2] | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | Conditionally Required: [2] | +| [`messaging.batch.message_count`](../attributes-registry/messaging.md) | int | The number of messages sent, received, or processed in the scope of the batching operation. [3] | `0`; `1`; `2` | Conditionally Required: [4] | | [`messaging.client_id`](../attributes-registry/messaging.md) | string | A unique identifier for the client that consumes or produces a message. | `client-5`; `myhost@8742@s8083jm` | Recommended: If a client id is available | -| [`messaging.destination.anonymous`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). | | Conditionally Required: [3] | -| [`messaging.destination.name`](../attributes-registry/messaging.md) | string | The message destination name [4] | `MyQueue`; `MyTopic` | Conditionally Required: [5] | -| [`messaging.destination.template`](../attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [6] | `/customers/{customerId}` | Conditionally Required: [7] | -| [`messaging.destination.temporary`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | Conditionally Required: [8] | -| [`messaging.message.body.size`](../attributes-registry/messaging.md) | int | The size of the message body in bytes. [9] | `1439` | Recommended: [10] | -| [`messaging.message.conversation_id`](../attributes-registry/messaging.md) | string | The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | Recommended: [11] | -| [`messaging.message.envelope.size`](../attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [12] | `2738` | Recommended: [13] | -| [`messaging.message.id`](../attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | Recommended: [14] | -| [`messaging.operation`](../attributes-registry/messaging.md) | string | A string identifying the kind of messaging operation. [15] | `publish` | Required | +| [`messaging.destination.anonymous`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). | | Conditionally Required: [5] | +| [`messaging.destination.name`](../attributes-registry/messaging.md) | string | The message destination name [6] | `MyQueue`; `MyTopic` | Conditionally Required: [7] | +| [`messaging.destination.template`](../attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [8] | `/customers/{customerId}` | Conditionally Required: [9] | +| [`messaging.destination.temporary`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | Conditionally Required: [10] | +| [`messaging.message.body.size`](../attributes-registry/messaging.md) | int | The size of the message body in bytes. [11] | `1439` | Recommended: [12] | +| [`messaging.message.conversation_id`](../attributes-registry/messaging.md) | string | The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | Recommended: [13] | +| [`messaging.message.envelope.size`](../attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [14] | `2738` | Recommended: [15] | +| [`messaging.message.id`](../attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | Recommended: [16] | +| [`messaging.operation`](../attributes-registry/messaging.md) | string | A string identifying the kind of messaging operation. [17] | `publish` | Required | | [`messaging.system`](../attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq` | Required | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [16] | `amqp`; `mqtt` | Recommended | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [17] | `3.1.1` | Recommended | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [18] | `tcp`; `udp` | Recommended | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [19] | `ipv4`; `ipv6` | Recommended | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [20] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [18] | `amqp`; `mqtt` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [19] | `3.1.1` | Recommended | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [20] | `tcp`; `udp` | Recommended | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [21] | `ipv4`; `ipv6` | Recommended | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [22] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [23] | `80`; `8080`; `443` | Recommended | -**[1]:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. +**[1]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. +Instrumentations SHOULD document the list of errors they report. -**[2]:** If the span describes an operation on a batch of messages. +The cardinality of `error.type` within one instrumentation library SHOULD be low. +Telemetry consumers that aggregate data from multiple instrumentation libraries and applications +should be prepared for `error.type` to have high cardinality at query time when no +additional filters are applied. -**[3]:** If value is `true`. When missing, the value is assumed to be `false`. +If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. -**[4]:** Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If +If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), +it's RECOMMENDED to: + +* Use a domain-specific attribute +* Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. + +**[2]:** If and only if the messaging operation has failed. + +**[3]:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. + +**[4]:** If the span describes an operation on a batch of messages. + +**[5]:** If value is `true`. When missing, the value is assumed to be `false`. + +**[6]:** Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If the broker doesn't have such notion, the destination name SHOULD uniquely identify the broker. -**[5]:** If span describes operation on a single message or if the value applies to all messages in the batch. +**[7]:** If span describes operation on a single message or if the value applies to all messages in the batch. -**[6]:** Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. +**[8]:** Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. -**[7]:** If available. Instrumentations MUST NOT use `messaging.destination.name` as template unless low-cardinality of destination name is guaranteed. +**[9]:** If available. Instrumentations MUST NOT use `messaging.destination.name` as template unless low-cardinality of destination name is guaranteed. -**[8]:** If value is `true`. When missing, the value is assumed to be `false`. +**[10]:** If value is `true`. When missing, the value is assumed to be `false`. -**[9]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed +**[11]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed body size should be used. -**[10]:** Only if span represents operation on a single message. +**[12]:** Only if span represents operation on a single message. -**[11]:** Only if span represents operation on a single message. +**[13]:** Only if span represents operation on a single message. -**[12]:** This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed +**[14]:** This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed size should be used. -**[13]:** Only if span represents operation on a single message. +**[15]:** Only if span represents operation on a single message. -**[14]:** Only for spans that represent an operation on a single message. +**[16]:** Only for spans that represent an operation on a single message. -**[15]:** If a custom value is used, it MUST be of low cardinality. +**[17]:** If a custom value is used, it MUST be of low cardinality. -**[16]:** The value SHOULD be normalized to lowercase. +**[18]:** The value SHOULD be normalized to lowercase. -**[17]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[19]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[18]:** The value SHOULD be normalized to lowercase. +**[20]:** The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport. For example different processes could be listening on TCP port 12345 and UDP port 12345. -**[19]:** The value SHOULD be normalized to lowercase. +**[21]:** The value SHOULD be normalized to lowercase. + +**[22]:** This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. + +**[23]:** 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. -**[20]:** This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. +`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 | +|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | `messaging.operation` 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/model/messaging-common.yaml b/model/messaging-common.yaml new file mode 100644 index 0000000000..07ef5f4a78 --- /dev/null +++ b/model/messaging-common.yaml @@ -0,0 +1,23 @@ +groups: + - id: messaging.attributes.common + type: attribute_group + brief: "Common messaging attributes." + prefix: messaging + attributes: + - ref: messaging.system + requirement_level: required + - ref: error.type + examples: ['amqp:decode-error', 'KAFKA_STORAGE_ERROR', 'channel-error'] + requirement_level: + conditionally_required: If and only if the messaging operation has failed. + - ref: server.address + note: > + This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. + requirement_level: + conditionally_required: If available. + - ref: server.port + - ref: network.protocol.name + examples: ['amqp', 'mqtt'] + tag: connection-level + - ref: network.protocol.version + tag: connection-level diff --git a/model/metrics/messaging.yaml b/model/metrics/messaging.yaml new file mode 100644 index 0000000000..2d2f2a29ef --- /dev/null +++ b/model/metrics/messaging.yaml @@ -0,0 +1,62 @@ +groups: + - id: metric.messaging.attributes + type: attribute_group + brief: "Common messaging metrics attributes." + extends: messaging.attributes.common + attributes: + - ref: messaging.destination.name + requirement_level: + conditionally_required: if and only if `messaging.destination.name` is known to have low cardinality. Otherwise, `messaging.destination.template` MAY be populated. + - ref: messaging.destination.template + requirement_level: + conditionally_required: if available. + + # durations + - id: metric.messaging.publish.duration + type: metric + metric_name: messaging.publish.duration + brief: "Measures the duration of publish operation." + instrument: histogram + unit: "s" + extends: metric.messaging.attributes + + - id: metric.messaging.receive.duration + type: metric + metric_name: messaging.receive.duration + brief: "Measures the duration of receive operation." + instrument: histogram + unit: "s" + extends: metric.messaging.attributes + + - id: metric.messaging.deliver.duration + type: metric + metric_name: messaging.deliver.duration + brief: "Measures the duration of deliver operation." + instrument: histogram + unit: "s" + extends: metric.messaging.attributes + + # counters + - id: metric.messaging.publish.messages + type: metric + metric_name: messaging.publish.messages + brief: "Measures the number of published messages." + instrument: counter + unit: "{message}" + extends: metric.messaging.attributes + + - id: metric.messaging.receive.messages + type: metric + metric_name: messaging.receive.messages + brief: "Measures the number of received messages." + instrument: counter + unit: "{message}" + extends: metric.messaging.attributes + + - id: metric.messaging.deliver.messages + type: metric + metric_name: messaging.deliver.messages + brief: "Measures the number of delivered messages." + instrument: counter + unit: "{message}" + extends: metric.messaging.attributes diff --git a/model/trace/messaging.yaml b/model/trace/messaging.yaml index 9163de0b4b..be7a4441c7 100644 --- a/model/trace/messaging.yaml +++ b/model/trace/messaging.yaml @@ -52,9 +52,8 @@ groups: brief: > This document defines general attributes used in messaging systems. + extends: messaging.attributes.common attributes: - - ref: messaging.system - requirement_level: required - ref: messaging.operation requirement_level: required - ref: messaging.batch.message_count @@ -90,10 +89,6 @@ groups: requirement_level: recommended: Only if span represents operation on a single message. - ref: server.address - note: > - This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. - requirement_level: - conditionally_required: If available. - ref: network.peer.address tag: connection-level - ref: network.peer.port @@ -104,9 +99,6 @@ groups: tag: connection-level - ref: network.type tag: connection-level - - ref: network.protocol.name - examples: ['amqp', 'mqtt'] - - ref: network.protocol.version - id: messaging.rabbitmq type: attribute_group