From 63e309e1b2c4cfa02c51f2b4d7bbcef41a67b6c4 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 9 May 2024 07:35:17 -0700 Subject: [PATCH 1/7] Document patterns and suggestions for semconv code generation (#953) --- .chloggen/953.yaml | 7 ++ .../semantic_conventions_code_generation.md | 118 ++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 .chloggen/953.yaml create mode 100644 supplementary-guidelines/semantic_conventions_code_generation.md diff --git a/.chloggen/953.yaml b/.chloggen/953.yaml new file mode 100644 index 0000000000..b09aa3df1e --- /dev/null +++ b/.chloggen/953.yaml @@ -0,0 +1,7 @@ +change_type: enhancement + +component: other + +note: Document patterns and suggestions for semconv code generation. + +issues: [551, 953] diff --git a/supplementary-guidelines/semantic_conventions_code_generation.md b/supplementary-guidelines/semantic_conventions_code_generation.md new file mode 100644 index 0000000000..76436fed77 --- /dev/null +++ b/supplementary-guidelines/semantic_conventions_code_generation.md @@ -0,0 +1,118 @@ +# Semantic convention libraries + + + +- [Stability and Versioning](#stability-and-versioning) + - [Deprecated Conventions](#deprecated-conventions) +- [Semantic Conventions Artifact Structure](#semantic-conventions-artifact-structure) +- [Generating semantic conventions](#generating-semantic-conventions) + + + +The code for OpenTelemetry Semantic Conventions defined in this repository can be auto-generated. + +OpenTelemetry Language SIGs can generate Semantic Conventions code in the form that's idiomatic for +their language and may (or may not) ship it as a stand-alone library. + +This document outlines common patterns and provides non-normative guidance on how to structure semantic conventions artifact +and generate the code. + +## Stability and Versioning + +Semantic Conventions contain a mix of stability levels. +Language SIGs that ship semantic conventions library may decide to ship a stable artifact with stable part of the Semantic Conventions, a preview artifact with all Semantic Conventions, or other combination that's idiomatic for this language and provides [SemVer 2.0](https://semver.org/) stability guarantees. + +Possible solutions include: + +- Generate all Semantic Conventions for a given version in specific folder while keeping old versions intact. It is used by [opentelemetry-go](https://github.com/open-telemetry/opentelemetry-go/tree/main/semconv/) but could be problematic if the artifact size is a concern. +- Follow language-specific conventions to annotate experimental parts. For example, Semantic Conventions in Python puts experimental attributes in `opentelemetry.semconv._incubating` import path which is considered (following Python underscore convention) to be internal and subject to change. +- Ship two different artifacts: one that contains stable Semantic Conventions and another one with all available conventions. For example, [semantic-conventions in Java](https://github.com/open-telemetry/semantic-conventions-java) are shipped in two artifacts: `opentelemetry-semconv` and `opentelemetry-semconv-incubating`. + +> Note: +> Shipping two versions of the same artifact (stable and preview) could be problematic due to diamond-dependency problems. +> For example, if user application depends on the `semconv v1.0.0-preview` and some library brings transitive dependency on `semconv v1.1.0` that does not contain +> experimental conventions, the latter would be resolved leading to compilation or runtime issues in the application. + +Instrumentation libraries should depend on the stable (part of) semantic convention artifact or copy relevant definitions into their own code base. +Experimental semantic conventions are intended for end-user applications. + +### Deprecated Conventions + +It's recommended to generate code for deprecated attributes, metrics, and other conventions. Use appropriate annotations to mark them as deprecated. +Conventions have a `stability` property which provide the stability level at the deprecation time (`experimental` or `stable`) and +the `deprecated` property that describes deprecation reason which can be used to generate documentation. + +- Deprecated conventions that reached stability should not be removed without major version update according to SemVer. +- Conventions that were deprecated while being experimental should still be generated and kept in the preview (part of) semantic conventions artifact. It minimizes runtime issues + and breaking changes in user applications. + +Keep stable convention definitions inside the preview (part of) semantic conversions artifact. It prevents user code from breaking when semantic convention stabilizes. Deprecate stable definitions inside the preview artifact and point users to the stable location in generated documentation. +For example, in Java `http.request.method` attribute is defined as the deprecated `io.opentelemetry.semconv.incubating.HttpIncubatingAttributes.HTTP_REQUEST_METHOD` field and also as stable `io.opentelemetry.semconv.HttpAttributes.HTTP_REQUEST_METHOD`. + +## Semantic Conventions Artifact Structure + +This section contains suggestions on structuring semantic convention artifact(s) which should be adjusted to the specific language. + +- Artifact name: + - `opentelemetry-semconv` - stable conventions + - `opentelemetry-semconv-incubating` - (if applicable) the preview artifact containing all conventions +- Namespace: `opentelemetry.semconv` and `opentelemetry.semconv.incubating` +- All supported Schema URLs should be listed to allow different instrumentations in the same application to provide the exact version of conventions they follow. +- Attributes, metrics, and other convention definitions should be grouped by the convention type and the root namespace. See the example below: + +``` +├── SchemaUrls.code +├── attributes +│ ├── ClientAttributes.code +│ ├── HttpAttributes.code +│ └── ... +├── metrics +│ ├── HttpMetrics.code +│ └── ... +└── events + └── ... +``` + +## Generating semantic conventions + +> Note: +> The tooling used for code generation may change to [opentelemetry-weaver](https://github.com/open-telemetry/weaver), +> without any breaking changes in the generated code and with minimal changes to generation process and templates. + +The generation is done using [build-tools code generator](https://github.com/open-telemetry/build-tools/blob/main/semantic-conventions/README.md#code-generator). +It's based on YAML definitions of the semantic conventions and uses [Jinja templates](https://palletsprojects.com/p/jinja/). + +For example, this Jinja template can be used to generate Python constant for an attribute name along with the docstring. + +```jinja +{{attribute.fqn | to_const_name}} = "{{attribute.fqn}}" +""" +{{attribute.brief | to_doc_brief}}. +{%- if attribute.note %} +Note: {{attribute.note | to_doc_brief | indent}}. +{%- endif %} +""" +``` + +It generates the following code: + +```python +SERVER_ADDRESS = "server.address" +""" +Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. +Note: 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. +""" +``` + +Language SIGs are expected to create Jinja templates specific to their language. +Code-generation usually involves several steps which could be semi-automated: + +1. Manually update the Semantic Conventions version when necessary +2. Add the new Schema URL to the list of supported versions + - If it's not automated, then it can, at least, be automatically checked. +3. Check out (or download) this version of Semantic Conventions +4. Run code-generation script for each template +5. Fix lint violations in the auto-generated code (if any) +6. Send the PR with new code to the corresponding repository + +Here're the examples of how steps 2-5 are implemented for [Java](https://github.com/open-telemetry/semantic-conventions-java/blob/7da24068eea69dff11a78d59750b115dc4c5854d/build.gradle.kts#L55-L137) and [Python](https://github.com/open-telemetry/opentelemetry-python/blob/397e357dfad3e6ff42c09c74d5945dfdcad24bdd/scripts/semconv/generate.sh). From 28158d8c03ab40e4d3265d28eb1530b0524f5b93 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 9 May 2024 09:55:51 -0700 Subject: [PATCH 2/7] Fix CI: regenerate semconv with latest weaver (#1021) --- Makefile | 8 +++---- docs/object-stores/s3.md | 30 ++++++++++++++++++++----- docs/resource/k8s.md | 48 ++++++++++++++++++++-------------------- 3 files changed, 52 insertions(+), 34 deletions(-) diff --git a/Makefile b/Makefile index 125b4550f1..79bf427273 100644 --- a/Makefile +++ b/Makefile @@ -95,7 +95,7 @@ yamllint: # Generate markdown tables from YAML definitions .PHONY: table-generation table-generation: - docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec \ + docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec --pull=always \ otel/weaver:${WEAVER_VERSION} registry update-markdown \ --registry=/source \ --attribute-registry-base-url=/docs/attributes-registry \ @@ -104,7 +104,7 @@ table-generation: # Generate attribute registry markdown. .PHONY: attribute-registry-generation attribute-registry-generation: - docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec -v $(PWD)/templates:/weaver/templates \ + docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec -v $(PWD)/templates:/weaver/templates --pull=always \ otel/weaver:${WEAVER_VERSION} registry generate \ --registry=/source \ --templates=/weaver/templates \ @@ -115,7 +115,7 @@ attribute-registry-generation: # Check if current markdown tables differ from the ones that would be generated from YAML definitions (weaver). .PHONY: table-check table-check: - docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec \ + docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec --pull=always \ otel/weaver:${WEAVER_VERSION} registry update-markdown \ --registry=/source \ --attribute-registry-base-url=/docs/attributes-registry \ @@ -125,7 +125,7 @@ table-check: LATEST_RELEASED_SEMCONV_VERSION := $(shell git describe --tags --abbrev=0 | sed 's/v//g') .PHONY: compatibility-check compatibility-check: - docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec \ + docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec --pull=always \ otel/semconvgen:$(SEMCONVGEN_VERSION) -f /source compatibility --previous-version $(LATEST_RELEASED_SEMCONV_VERSION) .PHONY: schema-check diff --git a/docs/object-stores/s3.md b/docs/object-stores/s3.md index 3ac6a0ab8f..3f4b92c82e 100644 --- a/docs/object-stores/s3.md +++ b/docs/object-stores/s3.md @@ -14,12 +14,16 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aws.s3.bucket`](../attributes-registry/aws.md) | string | The S3 bucket name the request refers to. Corresponds to the `--bucket` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. [1] | `some-bucket-name` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.s3.copy_source`](../attributes-registry/aws.md) | string | The source object (in the form `bucket`/`key`) for the copy operation. [2] | `someFile.yml` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.s3.delete`](../attributes-registry/aws.md) | string | The delete request container that specifies the objects to be deleted. [3] | `Objects=[{Key=string,VersionId=string},{Key=string,VersionId=string}],Quiet=boolean` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.s3.key`](../attributes-registry/aws.md) | string | The S3 object key the request refers to. Corresponds to the `--key` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. [4] | `someFile.yml` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.s3.part_number`](../attributes-registry/aws.md) | int | The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000. [5] | `3456` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.s3.upload_id`](../attributes-registry/aws.md) | string | Upload ID that identifies the multipart upload. [6] | `dfRtDYWFbkRONycy.Yxwh66Yjlx.cph0gtNBtJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.system`](/docs/attributes-registry/rpc.md) | string | The value `aws-api`. | `aws-api` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.request_id`](/docs/attributes-registry/aws.md) | string | The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. | `79b9da39-b7ae-508a-a6bc-864b2829c622`; `C9ER4AJX75574TDJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.s3.bucket`](/docs/attributes-registry/aws.md) | string | The S3 bucket name the request refers to. Corresponds to the `--bucket` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. [1] | `some-bucket-name` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.s3.copy_source`](/docs/attributes-registry/aws.md) | string | The source object (in the form `bucket`/`key`) for the copy operation. [2] | `someFile.yml` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.s3.delete`](/docs/attributes-registry/aws.md) | string | The delete request container that specifies the objects to be deleted. [3] | `Objects=[{Key=string,VersionId=string},{Key=string,VersionId=string}],Quiet=boolean` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.s3.key`](/docs/attributes-registry/aws.md) | string | The S3 object key the request refers to. Corresponds to the `--key` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. [4] | `someFile.yml` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.s3.part_number`](/docs/attributes-registry/aws.md) | int | The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000. [5] | `3456` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.s3.upload_id`](/docs/attributes-registry/aws.md) | string | Upload ID that identifies the multipart upload. [6] | `dfRtDYWFbkRONycy.Yxwh66Yjlx.cph0gtNBtJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.method`](/docs/attributes-registry/rpc.md) | string | The name of the operation corresponding to the request, as returned by the AWS SDK [7] | `GetItem`; `PutItem` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.service`](/docs/attributes-registry/rpc.md) | string | The name of the service to which a request is made, as returned by the AWS SDK. [8] | `DynamoDB`; `S3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The `bucket` attribute is applicable to all S3 operations that reference a bucket, i.e. that require the bucket name as a mandatory parameter. This applies to almost all S3 operations except `list-buckets`. @@ -66,6 +70,20 @@ This applies in particular to the following operations: - [list-parts](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html) - [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) + +**[7]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). + +**[8]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). + +`rpc.system` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. + +| Value | Description | Stability | +|---|---|---| +| `grpc` | gRPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `java_rmi` | Java RMI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dotnet_wcf` | .NET WCF | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `apache_dubbo` | Apache Dubbo | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `connect_rpc` | Connect RPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/k8s.md b/docs/resource/k8s.md index 0ee64504f5..4eb3082a23 100644 --- a/docs/resource/k8s.md +++ b/docs/resource/k8s.md @@ -24,8 +24,8 @@ Kubernetes object, but "name" is usually more user friendly so can be also set. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`k8s.cluster.name`](../attributes-registry/k8s.md) | string | The name of the cluster. | `opentelemetry-cluster` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`k8s.cluster.uid`](../attributes-registry/k8s.md) | string | A pseudo-ID for the cluster, set to the UID of the `kube-system` namespace. [1] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.cluster.name`](/docs/attributes-registry/k8s.md) | string | The name of the cluster. | `opentelemetry-cluster` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.cluster.uid`](/docs/attributes-registry/k8s.md) | string | A pseudo-ID for the cluster, set to the UID of the `kube-system` namespace. [1] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** K8s doesn't have support for obtaining a cluster ID. If this is ever added, we will recommend collecting the `k8s.cluster.uid` through the @@ -60,8 +60,8 @@ conflict. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`k8s.node.name`](../attributes-registry/k8s.md) | string | The name of the Node. | `node-1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`k8s.node.uid`](../attributes-registry/k8s.md) | string | The UID of the Node. | `1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.node.name`](/docs/attributes-registry/k8s.md) | string | The name of the Node. | `node-1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.node.uid`](/docs/attributes-registry/k8s.md) | string | The UID of the Node. | `1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Namespace @@ -76,7 +76,7 @@ a namespace, but not across namespaces. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`k8s.namespace.name`](../attributes-registry/k8s.md) | string | The name of the namespace that the pod is running in. | `default` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.namespace.name`](/docs/attributes-registry/k8s.md) | string | The name of the namespace that the pod is running in. | `default` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Pod @@ -91,10 +91,10 @@ containers on your cluster. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`k8s.pod.label.`](../attributes-registry/k8s.md) | string | The label key-value pairs placed on the Pod, the `` being the label name, the value being the label value. | `k8s.pod.label.app=my-app`; `k8s.pod.label.mycompany.io/arch=x64`; `k8s.pod.label.data=` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`k8s.pod.name`](../attributes-registry/k8s.md) | string | The name of the Pod. | `opentelemetry-pod-autoconf` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`k8s.pod.uid`](../attributes-registry/k8s.md) | string | The UID of the Pod. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`k8s.pod.annotation.`](../attributes-registry/k8s.md) | string | The annotation key-value pairs placed on the Pod, the `` being the annotation name, the value being the annotation value. | `k8s.pod.annotation.kubernetes.io/enforce-mountable-secrets=true`; `k8s.pod.annotation.mycompany.io/arch=x64`; `k8s.pod.annotation.data=` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.pod.label.`](/docs/attributes-registry/k8s.md) | string | The label key-value pairs placed on the Pod, the `` being the label name, the value being the label value. | `k8s.pod.label.app=my-app`; `k8s.pod.label.mycompany.io/arch=x64`; `k8s.pod.label.data=` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.pod.name`](/docs/attributes-registry/k8s.md) | string | The name of the Pod. | `opentelemetry-pod-autoconf` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.pod.uid`](/docs/attributes-registry/k8s.md) | string | The UID of the Pod. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.pod.annotation.`](/docs/attributes-registry/k8s.md) | string | The annotation key-value pairs placed on the Pod, the `` being the annotation name, the value being the annotation value. | `k8s.pod.annotation.kubernetes.io/enforce-mountable-secrets=true`; `k8s.pod.annotation.mycompany.io/arch=x64`; `k8s.pod.annotation.data=` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Container @@ -113,9 +113,9 @@ to a running container. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`k8s.container.name`](../attributes-registry/k8s.md) | string | The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (`container.name`). | `redis` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`k8s.container.restart_count`](../attributes-registry/k8s.md) | int | Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`k8s.container.status.last_terminated_reason`](../attributes-registry/k8s.md) | string | Last terminated reason of the Container. | `Evicted`; `Error` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.container.name`](/docs/attributes-registry/k8s.md) | string | The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (`container.name`). | `redis` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.container.restart_count`](/docs/attributes-registry/k8s.md) | int | Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.container.status.last_terminated_reason`](/docs/attributes-registry/k8s.md) | string | Last terminated reason of the Container. | `Evicted`; `Error` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## ReplicaSet @@ -130,8 +130,8 @@ any given time. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`k8s.replicaset.name`](../attributes-registry/k8s.md) | string | The name of the ReplicaSet. | `opentelemetry` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`k8s.replicaset.uid`](../attributes-registry/k8s.md) | string | The UID of the ReplicaSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.replicaset.name`](/docs/attributes-registry/k8s.md) | string | The name of the ReplicaSet. | `opentelemetry` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.replicaset.uid`](/docs/attributes-registry/k8s.md) | string | The UID of the ReplicaSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Deployment @@ -147,8 +147,8 @@ distributed among the nodes of a cluster. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`k8s.deployment.name`](../attributes-registry/k8s.md) | string | The name of the Deployment. | `opentelemetry` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`k8s.deployment.uid`](../attributes-registry/k8s.md) | string | The UID of the Deployment. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.deployment.name`](/docs/attributes-registry/k8s.md) | string | The name of the Deployment. | `opentelemetry` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.deployment.uid`](/docs/attributes-registry/k8s.md) | string | The UID of the Deployment. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## StatefulSet @@ -163,8 +163,8 @@ about the ordering and uniqueness of these Pods. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`k8s.statefulset.name`](../attributes-registry/k8s.md) | string | The name of the StatefulSet. | `opentelemetry` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`k8s.statefulset.uid`](../attributes-registry/k8s.md) | string | The UID of the StatefulSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.statefulset.name`](/docs/attributes-registry/k8s.md) | string | The name of the StatefulSet. | `opentelemetry` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.statefulset.uid`](/docs/attributes-registry/k8s.md) | string | The UID of the StatefulSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DaemonSet @@ -178,8 +178,8 @@ A DaemonSet ensures that all (or some) Nodes run a copy of a Pod. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`k8s.daemonset.name`](../attributes-registry/k8s.md) | string | The name of the DaemonSet. | `opentelemetry` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`k8s.daemonset.uid`](../attributes-registry/k8s.md) | string | The UID of the DaemonSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.daemonset.name`](/docs/attributes-registry/k8s.md) | string | The name of the DaemonSet. | `opentelemetry` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.daemonset.uid`](/docs/attributes-registry/k8s.md) | string | The UID of the DaemonSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Job @@ -194,8 +194,8 @@ successfully terminate. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`k8s.job.name`](../attributes-registry/k8s.md) | string | The name of the Job. | `opentelemetry` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`k8s.job.uid`](../attributes-registry/k8s.md) | string | The UID of the Job. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.job.name`](/docs/attributes-registry/k8s.md) | string | The name of the Job. | `opentelemetry` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.job.uid`](/docs/attributes-registry/k8s.md) | string | The UID of the Job. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## CronJob @@ -209,8 +209,8 @@ A CronJob creates Jobs on a repeating schedule. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`k8s.cronjob.name`](../attributes-registry/k8s.md) | string | The name of the CronJob. | `opentelemetry` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`k8s.cronjob.uid`](../attributes-registry/k8s.md) | string | The UID of the CronJob. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.cronjob.name`](/docs/attributes-registry/k8s.md) | string | The name of the CronJob. | `opentelemetry` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.cronjob.uid`](/docs/attributes-registry/k8s.md) | string | The UID of the CronJob. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md From c316b1fb8747b8384b738806cb5068a9bf839f8c Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 9 May 2024 10:03:48 -0700 Subject: [PATCH 3/7] Finalize migration requirement for stable database semconv (#992) --- .chloggen/992.yaml | 22 ++++++++++++++++++++++ docs/database/database-metrics.md | 27 +++++++++++++++++++++++---- docs/database/database-spans.md | 27 ++++++++++----------------- 3 files changed, 55 insertions(+), 21 deletions(-) create mode 100644 .chloggen/992.yaml diff --git a/.chloggen/992.yaml b/.chloggen/992.yaml new file mode 100644 index 0000000000..52b89da098 --- /dev/null +++ b/.chloggen/992.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: Finalizes the migration requirement for instrumentations to follow when updating to stable database semconv. + +# 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: [ 719 ] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/database/database-metrics.md b/docs/database/database-metrics.md index e40ef7bb6a..d56e5b3e1c 100644 --- a/docs/database/database-metrics.md +++ b/docs/database/database-metrics.md @@ -31,11 +31,30 @@ and attributes but more may be added in the future. > **Warning** +> > Existing database instrumentations that are using -> [v1.24.0 of this document](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/database/database-metrics.md) -> (or prior) SHOULD NOT change the version of the database conventions that they emit -> until a transition plan to the (future) stable semantic conventions has been published. -> Conventions include, but are not limited to, attributes, metric and span names, and unit of measure. +> [v1.24.0 of this document](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/database/database-spans.md) +> (or prior): +> +> * SHOULD NOT change the version of the database conventions that they emit +> until the database semantic conventions are marked stable. +> Conventions include, but are not limited to, attributes, +> metric and span names, and unit of measure. +> * SHOULD introduce an environment variable `OTEL_SEMCONV_STABILITY_OPT_IN` +> in the existing major version which is a comma-separated list of values. +> If the list of values includes: +> * `database` - emit the new, stable database conventions, +> and stop emitting the old experimental database conventions +> that the instrumentation emitted previously. +> * `database/dup` - emit both the old and the stable database conventions, +> allowing for a seamless transition. +> * The default behavior (in the absence of one of these values) is to continue +> emitting whatever version of the old experimental database conventions +> the instrumentation was emitting previously. +> * Note: `database/dup` has higher precedence than `database` in case both values are present +> * SHOULD maintain (security patching at a minimum) the existing major version +> for at least six months after it starts emitting both sets of conventions. +> * SHOULD drop the environment variable in the next major version. ## Database operation diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 6425213bff..dd170bedc2 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -18,34 +18,27 @@ linkTitle: Client Calls > **Warning** +> > Existing database instrumentations that are using > [v1.24.0 of this document](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/database/database-spans.md) -> (or prior) SHOULD NOT change the version of the database conventions that they emit -> until a transition plan to the (future) stable semantic conventions has been published. -> Conventions include, but are not limited to, attributes, metric and span names, and unit of measure. -> -> **Warning** -> Existing Database instrumentations that are using -> [v1.20.0 of this document](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/semantic_conventions/database.md) > (or prior): > -> * SHOULD NOT change the version of the networking conventions that they emit -> until the HTTP semantic conventions are marked stable (HTTP stabilization will -> include stabilization of a core set of networking conventions which are also used -> in Database instrumentations). Conventions include, but are not limited to, attributes, +> * SHOULD NOT change the version of the database conventions that they emit +> until the database semantic conventions are marked stable. +> Conventions include, but are not limited to, attributes, > metric and span names, and unit of measure. > * SHOULD introduce an environment variable `OTEL_SEMCONV_STABILITY_OPT_IN` > in the existing major version which is a comma-separated list of values. -> The only values defined so far are: -> * `http` - emit the new, stable networking conventions, -> and stop emitting the old experimental networking conventions +> If the list of values includes: +> * `database` - emit the new, stable database conventions, +> and stop emitting the old experimental database conventions > that the instrumentation emitted previously. -> * `http/dup` - emit both the old and the stable networking conventions, +> * `database/dup` - emit both the old and the stable database conventions, > allowing for a seamless transition. > * The default behavior (in the absence of one of these values) is to continue -> emitting whatever version of the old experimental networking conventions +> emitting whatever version of the old experimental database conventions > the instrumentation was emitting previously. -> * Note: `http/dup` has higher precedence than `http` in case both values are present +> * Note: `database/dup` has higher precedence than `database` in case both values are present > * SHOULD maintain (security patching at a minimum) the existing major version > for at least six months after it starts emitting both sets of conventions. > * SHOULD drop the environment variable in the next major version. From e720865cfe29c72c0bd55d414a9ed55a6d95e2f6 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Fri, 10 May 2024 08:04:08 -0700 Subject: [PATCH 4/7] Clarify that `*.system` captures the client perception (#1016) --- .chloggen/1016.yaml | 4 + docs/attributes-registry/db.md | 8 +- docs/attributes-registry/gen-ai.md | 3 +- docs/attributes-registry/messaging.md | 7 +- docs/database/database-metrics.md | 38 ++++---- docs/database/database-spans.md | 46 +++++----- docs/database/dynamodb.md | 4 +- docs/gen-ai/llm-spans.md | 2 +- docs/messaging/azure-messaging.md | 120 +++++++++++++------------- docs/messaging/messaging-metrics.md | 26 +++--- docs/messaging/messaging-spans.md | 58 +++++++------ model/registry/db.yaml | 6 +- model/registry/gen-ai.yaml | 6 +- model/registry/messaging.yaml | 7 +- 14 files changed, 184 insertions(+), 151 deletions(-) create mode 100644 .chloggen/1016.yaml diff --git a/.chloggen/1016.yaml b/.chloggen/1016.yaml new file mode 100644 index 0000000000..a384eeeeef --- /dev/null +++ b/.chloggen/1016.yaml @@ -0,0 +1,4 @@ +change_type: enhancement +component: db, messaging, gen_ai +note: Clarify that `db.system`, `messaging.system`, `gen_ai.system` attributes capture the client perception and may differ from the actual product name. +issues: [813, 1016] diff --git a/docs/attributes-registry/db.md b/docs/attributes-registry/db.md index 15cb14e64f..0b4fa0e64e 100644 --- a/docs/attributes-registry/db.md +++ b/docs/attributes-registry/db.md @@ -26,7 +26,7 @@ This group defines the attributes used to describe telemetry in the context of d | `db.operation.name` | string | The name of the operation or command being executed. [3] | `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. [4] | `someval`; `55` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.query.text` | string | The database query being executed. | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql`; `mssql`; `mssqlcompact` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.system` | string | The database management system (DBMS) product as identified by the client instrumentation. [5] | `other_sql`; `mssql`; `mssqlcompact` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. @@ -40,6 +40,8 @@ It is RECOMMENDED to capture the value as provided by the application without at **[4]:** 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. +**[5]:** 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. + `db.client.connections.state` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. | Value | Description | Stability | @@ -202,9 +204,9 @@ This group defines attributes for Elasticsearch. | ----------------------------------- | ------ | -------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | | `db.elasticsearch.cluster.name` | string | Represents the identifier of an Elasticsearch cluster. | `e9106fc68e3044f0b1475b04bf4ffd5f` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.elasticsearch.node.name` | string | Represents the human-readable identifier of the node/instance to which a request was routed. | `instance-0000000001` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.elasticsearch.path_parts.` | string | A dynamic value in the url path. [5] | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.elasticsearch.path_parts.` | string | A dynamic value in the url path. [6] | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -**[5]:** Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names. +**[6]:** Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names. ## Db Metrics Deprecated Attributes diff --git a/docs/attributes-registry/gen-ai.md b/docs/attributes-registry/gen-ai.md index e5853b5363..95251faca1 100644 --- a/docs/attributes-registry/gen-ai.md +++ b/docs/attributes-registry/gen-ai.md @@ -21,12 +21,13 @@ 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 LLM a response was generated from. | `gpt-4-0613` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.system` | string | The name of the LLM foundation model vendor. | `openai` | ![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.usage.completion_tokens` | int | The number of tokens used in the LLM response (completion). | `180` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `gen_ai.usage.prompt_tokens` | int | The number of tokens used in the LLM prompt. | `100` | ![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) **[2]:** It's RECOMMENDED to format prompts as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation) +**[3]:** 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. `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. diff --git a/docs/attributes-registry/messaging.md b/docs/attributes-registry/messaging.md index 121e0c0114..fac226fada 100644 --- a/docs/attributes-registry/messaging.md +++ b/docs/attributes-registry/messaging.md @@ -36,7 +36,7 @@ Attributes describing telemetry around messaging systems and messaging activitie | `messaging.message.id` | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `messaging.operation.name` | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `messaging.operation.type` | string | A string identifying the type of the messaging operation. [7] | `publish`; `create`; `receive` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.system` | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq`; `aws_sqs`; `eventgrid` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.system` | string | The messaging system as identified by the client instrumentation. [8] | `activemq`; `aws_sqs`; `eventgrid` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[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. @@ -55,6 +55,7 @@ body size should be used. size should be used. **[7]:** If a custom value is used, it MUST be of low cardinality. +**[8]:** The actual messaging system may differ from the one known by the client. For example, when using Kafka client libraries to communicate with Azure Event Hubs, the `messaging.system` is set to `kafka` based on the instrumentation's best knowledge. `messaging.operation.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. @@ -118,11 +119,11 @@ This group describes attributes specific to Apache Kafka. | Attribute | Type | Description | Examples | Stability | | ----------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- | ---------------------------------------------------------------- | | `messaging.kafka.consumer.group` | string | Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. | `my-group` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.kafka.message.key` | string | Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. [8] | `myKey` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.kafka.message.key` | string | Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. [9] | `myKey` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `messaging.kafka.message.offset` | int | The offset of a record in the corresponding Kafka partition. | `42` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `messaging.kafka.message.tombstone` | boolean | A boolean that is true if the message is a tombstone. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -**[8]:** If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value. +**[9]:** If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value. ## Messaging Rabbitmq Attributes diff --git a/docs/database/database-metrics.md b/docs/database/database-metrics.md index d56e5b3e1c..cc7ecb8652 100644 --- a/docs/database/database-metrics.md +++ b/docs/database/database-metrics.md @@ -79,39 +79,41 @@ of `[ 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10 ]`. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.system`](/docs/attributes-registry/db.md) | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql`; `mssql`; `mssqlcompact` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.collection.name`](/docs/attributes-registry/db.md) | string | The name of a collection (table, container) within the database. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.namespace`](/docs/attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. [3] | `customers`; `test.users` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.operation.name`](/docs/attributes-registry/db.md) | string | The name of the operation or command being executed. [4] | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [5] | ![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. [6] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if the operation failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`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) | -| [`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` If applicable for this database system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.system`](/docs/attributes-registry/db.md) | string | The database management system (DBMS) product as identified by the client instrumentation. [1] | `other_sql`; `mssql`; `mssqlcompact` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.collection.name`](/docs/attributes-registry/db.md) | string | The name of a collection (table, container) within the database. [2] | `public.users`; `customers` | `Conditionally Required` [3] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](/docs/attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. [4] | `customers`; `test.users` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](/docs/attributes-registry/db.md) | string | The name of the operation or command being executed. [5] | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [6] | ![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. [7] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if the operation failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [8] | `80`; `8080`; `443` | `Conditionally Required` [9] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [10] | `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. [10] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`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) | -**[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. +**[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. + +**[2]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. -**[2]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.collection.name`, then it SHOULD be the first collection name found in the query. +**[3]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.collection.name`, then it SHOULD be the first collection name found in the query. -**[3]:** If a database system has multiple namespace components, they SHOULD be concatenated (potentially using database system specific conventions) from most general to most specific namespace component, and more specific namespaces SHOULD NOT be captured without the more general namespaces, to ensure that "startswith" queries for the more general namespaces will be valid. +**[4]:** If a database system has multiple namespace components, they SHOULD be concatenated (potentially using database system specific conventions) from most general to most specific namespace component, and more specific namespaces SHOULD NOT be captured without the more general namespaces, to ensure that "startswith" queries for the more general namespaces will be valid. Semantic conventions for individual database systems SHOULD document what `db.namespace` means in the context of that system. It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. -**[4]:** It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. +**[5]:** It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. -**[5]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. +**[6]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. -**[6]:** The `error.type` SHOULD match the error code returned by the database 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. +**[7]:** The `error.type` SHOULD match the error code returned by the database 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. -**[7]:** 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. +**[8]:** 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. -**[8]:** If using a port other than the default port for this DBMS and if `server.address` is set. +**[9]:** If using a port other than the default port for this DBMS and if `server.address` is set. -**[9]:** 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. +**[10]:** 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. -**[10]:** 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. +**[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. `db.system` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index dd170bedc2..1c39bf7281 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -78,45 +78,47 @@ These attributes will usually be the same for all operations performed over the | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.system`](/docs/attributes-registry/db.md) | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql`; `mssql`; `mssqlcompact` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.collection.name`](/docs/attributes-registry/db.md) | string | The name of a collection (table, container) within the database. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.namespace`](/docs/attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. [3] | `customers`; `test.users` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.operation.name`](/docs/attributes-registry/db.md) | string | The name of the operation or command being executed. [4] | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [5] | ![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. [6] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if the operation failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`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. | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | `Recommended` [9] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [10] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this database system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.system`](/docs/attributes-registry/db.md) | string | The database management system (DBMS) product as identified by the client instrumentation. [1] | `other_sql`; `mssql`; `mssqlcompact` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.collection.name`](/docs/attributes-registry/db.md) | string | The name of a collection (table, container) within the database. [2] | `public.users`; `customers` | `Conditionally Required` [3] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](/docs/attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. [4] | `customers`; `test.users` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](/docs/attributes-registry/db.md) | string | The name of the operation or command being executed. [5] | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [6] | ![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. [7] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if the operation failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [8] | `80`; `8080`; `443` | `Conditionally Required` [9] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.query.text`](/docs/attributes-registry/db.md) | string | The database query being executed. | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | `Recommended` [10] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`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` 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. [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) | +| [`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) | -**[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. +**[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. + +**[2]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. -**[2]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.collection.name`, then it SHOULD be the first collection name found in the query. +**[3]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.collection.name`, then it SHOULD be the first collection name found in the query. -**[3]:** If a database system has multiple namespace components, they SHOULD be concatenated (potentially using database system specific conventions) from most general to most specific namespace component, and more specific namespaces SHOULD NOT be captured without the more general namespaces, to ensure that "startswith" queries for the more general namespaces will be valid. +**[4]:** If a database system has multiple namespace components, they SHOULD be concatenated (potentially using database system specific conventions) from most general to most specific namespace component, and more specific namespaces SHOULD NOT be captured without the more general namespaces, to ensure that "startswith" queries for the more general namespaces will be valid. Semantic conventions for individual database systems SHOULD document what `db.namespace` means in the context of that system. It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. -**[4]:** It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. +**[5]:** It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. -**[5]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. +**[6]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. -**[6]:** The `error.type` SHOULD match the error code returned by the database 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. +**[7]:** The `error.type` SHOULD match the error code returned by the database 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. -**[7]:** 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. +**[8]:** 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. -**[8]:** If using a port other than the default port for this DBMS and if `server.address` is set. +**[9]:** If using a port other than the default port for this DBMS and if `server.address` is set. -**[9]:** 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. -**[10]:** 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. +**[11]:** 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. -**[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. +**[12]:** 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. -**[12]:** Query parameters should only be captured when `db.query.text` is parameterized with placeholders. +**[13]:** Query parameters should only be captured when `db.query.text` is parameterized with placeholders. If a parameter has no name and instead is referenced only by index, then `` SHOULD be the 0-based index. `db.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. diff --git a/docs/database/dynamodb.md b/docs/database/dynamodb.md index 4801428946..0895a7f988 100644 --- a/docs/database/dynamodb.md +++ b/docs/database/dynamodb.md @@ -19,7 +19,9 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.system`](/docs/attributes-registry/db.md) | string | The value `dynamodb`. | `dynamodb` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.system`](/docs/attributes-registry/db.md) | string | The value `dynamodb`. [1] | `dynamodb` | `Required` | ![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. `db.system` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. diff --git a/docs/gen-ai/llm-spans.md b/docs/gen-ai/llm-spans.md index 5cf34e5ffd..f3caf7256f 100644 --- a/docs/gen-ai/llm-spans.md +++ b/docs/gen-ai/llm-spans.md @@ -40,7 +40,7 @@ These attributes track input data and metadata for a request to an LLM. Each att | 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 LLM 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 name of the LLM foundation model vendor. [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 instrumentation. [2] | `openai` | `Required` | ![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 LLM generates for a request. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`gen_ai.request.temperature`](/docs/attributes-registry/gen-ai.md) | double | The temperature setting for the LLM request. | `0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`gen_ai.request.top_p`](/docs/attributes-registry/gen-ai.md) | double | The top_p sampling setting for the LLM request. | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/messaging/azure-messaging.md b/docs/messaging/azure-messaging.md index bcae1c95ba..201d28e420 100644 --- a/docs/messaging/azure-messaging.md +++ b/docs/messaging/azure-messaging.md @@ -19,32 +19,34 @@ The following additional attributes are defined: | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`messaging.operation.type`](/docs/attributes-registry/messaging.md) | string | A string identifying the type of the messaging operation. [1] | `publish`; `create`; `receive` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.system`](/docs/attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq`; `aws_sqs`; `eventgrid` | `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] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` If and only if the messaging operation has failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`messaging.batch.message_count`](/docs/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] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.anonymous`](/docs/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] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.name`](/docs/attributes-registry/messaging.md) | string | The message destination name [6] | `MyQueue`; `MyTopic` | `Conditionally Required` [7] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.template`](/docs/attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [8] | `/customers/{customerId}` | `Conditionally Required` [9] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.temporary`](/docs/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] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.system`](/docs/attributes-registry/messaging.md) | string | The messaging system as identified by the client instrumentation. [2] | `activemq`; `aws_sqs`; `eventgrid` | `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. [3] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` If and only if the messaging operation has failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.batch.message_count`](/docs/attributes-registry/messaging.md) | int | The number of messages sent, received, or processed in the scope of the batching operation. [4] | `0`; `1`; `2` | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.anonymous`](/docs/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` [6] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.name`](/docs/attributes-registry/messaging.md) | string | The message destination name [7] | `MyQueue`; `MyTopic` | `Conditionally Required` [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.template`](/docs/attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [9] | `/customers/{customerId}` | `Conditionally Required` [10] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.temporary`](/docs/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` [11] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.servicebus.destination.subscription_name`](/docs/attributes-registry/messaging.md) | string | The name of the subscription in the topic messages are received from. | `mySubscription` | `Conditionally Required` If messages are received from the subscription. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.servicebus.disposition_status`](/docs/attributes-registry/messaging.md) | string | Describes the [settlement type](https://learn.microsoft.com/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock). | `complete`; `abandon`; `dead_letter` | `Conditionally Required` if and only if `messaging.operation` is `settle`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.servicebus.message.delivery_count`](/docs/attributes-registry/messaging.md) | int | Number of deliveries that have been attempted for this message. | `2` | `Conditionally Required` [11] | ![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. [12] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.servicebus.message.delivery_count`](/docs/attributes-registry/messaging.md) | int | Number of deliveries that have been attempted for this message. | `2` | `Conditionally Required` [12] | ![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. [13] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`messaging.client.id`](/docs/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 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.destination.partition.id`](/docs/attributes-registry/messaging.md) | string | The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. | `1` | `Recommended` When applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.message.body.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body in bytes. [13] | `1439` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.body.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body in bytes. [14] | `1439` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.message.conversation_id`](/docs/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` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.message.envelope.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [14] | `2738` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.envelope.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [15] | `2738` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.message.id`](/docs/attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.operation.name`](/docs/attributes-registry/messaging.md) | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | `Recommended` [15] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.operation.name`](/docs/attributes-registry/messaging.md) | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | `Recommended` [16] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.servicebus.message.enqueued_time`](/docs/attributes-registry/messaging.md) | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [16] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this messaging system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [17] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this messaging system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](/docs/attributes-registry/network.md) | int | Peer port of the messaging intermediary node where the operation was performed. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [17] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [18] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** If a custom value is used, it MUST be of low cardinality. -**[2]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. +**[2]:** The actual messaging system may differ from the one known by the client. For example, when using Kafka client libraries to communicate with Azure Event Hubs, the `messaging.system` is set to `kafka` based on the instrumentation's best knowledge. + +**[3]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. When `error.type` is set to a type (e.g., an exception type), its canonical class name identifying the type within the artifact SHOULD be used. @@ -64,40 +66,40 @@ 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. -**[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]:** 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 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]:** 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 +**[7]:** 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. -**[7]:** If span describes operation on a single message or if the value applies to all messages in the batch. +**[8]:** If span describes operation on a single message or if the value applies to all messages in the batch. -**[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. +**[9]:** 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. -**[9]:** If available. Instrumentations MUST NOT use `messaging.destination.name` as template unless low-cardinality of destination name is guaranteed. +**[10]:** If available. Instrumentations MUST NOT use `messaging.destination.name` as template unless low-cardinality of destination name is guaranteed. -**[10]:** If value is `true`. When missing, the value is assumed to be `false`. +**[11]:** If value is `true`. When missing, the value is assumed to be `false`. -**[11]:** If delivery count is available and is bigger than 0. +**[12]:** If delivery count is available and is bigger than 0. -**[12]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. +**[13]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. -**[13]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed +**[14]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed body size should be used. -**[14]:** This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed +**[15]:** This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed size should be used. -**[15]:** If the operation is not sufficiently described by `messaging.operation.type`. +**[16]:** If the operation is not sufficiently described by `messaging.operation.type`. -**[16]:** Semantic conventions for individual messaging systems SHOULD document whether `network.peer.*` attributes are applicable. +**[17]:** Semantic conventions for individual messaging systems SHOULD document whether `network.peer.*` attributes are applicable. Network peer address and port are important when the application interacts with individual intermediary nodes directly, If a messaging operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. -**[17]:** 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. +**[18]:** 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. `messaging.operation.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. @@ -151,30 +153,32 @@ The following additional attributes are defined: | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`messaging.operation.type`](/docs/attributes-registry/messaging.md) | string | A string identifying the type of the messaging operation. [1] | `publish`; `create`; `receive` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.system`](/docs/attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq`; `aws_sqs`; `eventgrid` | `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] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` If and only if the messaging operation has failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`messaging.batch.message_count`](/docs/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] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.anonymous`](/docs/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] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.name`](/docs/attributes-registry/messaging.md) | string | The message destination name [6] | `MyQueue`; `MyTopic` | `Conditionally Required` [7] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.system`](/docs/attributes-registry/messaging.md) | string | The messaging system as identified by the client instrumentation. [2] | `activemq`; `aws_sqs`; `eventgrid` | `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. [3] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` If and only if the messaging operation has failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.batch.message_count`](/docs/attributes-registry/messaging.md) | int | The number of messages sent, received, or processed in the scope of the batching operation. [4] | `0`; `1`; `2` | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.anonymous`](/docs/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` [6] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.name`](/docs/attributes-registry/messaging.md) | string | The message destination name [7] | `MyQueue`; `MyTopic` | `Conditionally Required` [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.destination.partition.id`](/docs/attributes-registry/messaging.md) | string | String representation of the partition id messages are sent to or received from, unique within the Event Hub. | `1` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.template`](/docs/attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [8] | `/customers/{customerId}` | `Conditionally Required` [9] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.temporary`](/docs/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] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.template`](/docs/attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [9] | `/customers/{customerId}` | `Conditionally Required` [10] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.temporary`](/docs/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` [11] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.eventhubs.consumer.group`](/docs/attributes-registry/messaging.md) | string | The name of the consumer group the event consumer is associated with. | `indexer` | `Conditionally Required` If not default ("$Default"). | ![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. [11] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`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. [12] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`messaging.client.id`](/docs/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 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.eventhubs.message.enqueued_time`](/docs/attributes-registry/messaging.md) | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.message.body.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body in bytes. [12] | `1439` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.body.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body in bytes. [13] | `1439` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.message.conversation_id`](/docs/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` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.message.envelope.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [13] | `2738` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.envelope.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [14] | `2738` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.message.id`](/docs/attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.operation.name`](/docs/attributes-registry/messaging.md) | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | `Recommended` [14] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [15] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this messaging system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.operation.name`](/docs/attributes-registry/messaging.md) | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | `Recommended` [15] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [16] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this messaging system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](/docs/attributes-registry/network.md) | int | Peer port of the messaging intermediary node where the operation was performed. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [16] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [17] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** If a custom value is used, it MUST be of low cardinality. -**[2]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. +**[2]:** The actual messaging system may differ from the one known by the client. For example, when using Kafka client libraries to communicate with Azure Event Hubs, the `messaging.system` is set to `kafka` based on the instrumentation's best knowledge. + +**[3]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. When `error.type` is set to a type (e.g., an exception type), its canonical class name identifying the type within the artifact SHOULD be used. @@ -194,38 +198,38 @@ 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. -**[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]:** 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 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]:** 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 +**[7]:** 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. -**[7]:** If span describes operation on a single message or if the value applies to all messages in the batch. +**[8]:** If span describes operation on a single message or if the value applies to all messages in the batch. -**[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. +**[9]:** 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. -**[9]:** If available. Instrumentations MUST NOT use `messaging.destination.name` as template unless low-cardinality of destination name is guaranteed. +**[10]:** If available. Instrumentations MUST NOT use `messaging.destination.name` as template unless low-cardinality of destination name is guaranteed. -**[10]:** If value is `true`. When missing, the value is assumed to be `false`. +**[11]:** If value is `true`. When missing, the value is assumed to be `false`. -**[11]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. +**[12]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. -**[12]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed +**[13]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed body size should be used. -**[13]:** 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. -**[14]:** If the operation is not sufficiently described by `messaging.operation.type`. +**[15]:** If the operation is not sufficiently described by `messaging.operation.type`. -**[15]:** Semantic conventions for individual messaging systems SHOULD document whether `network.peer.*` attributes are applicable. +**[16]:** Semantic conventions for individual messaging systems SHOULD document whether `network.peer.*` attributes are applicable. Network peer address and port are important when the application interacts with individual intermediary nodes directly, If a messaging operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. -**[16]:** 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. +**[17]:** 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. `messaging.operation.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. diff --git a/docs/messaging/messaging-metrics.md b/docs/messaging/messaging-metrics.md index 43f91ff657..8782e553d6 100644 --- a/docs/messaging/messaging-metrics.md +++ b/docs/messaging/messaging-metrics.md @@ -32,15 +32,17 @@ All messaging metrics share the same set of attributes: | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`messaging.system`](/docs/attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq`; `aws_sqs`; `eventgrid` | `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. [1] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` If and only if the messaging operation has failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`messaging.destination.name`](/docs/attributes-registry/messaging.md) | string | The message destination name [2] | `MyQueue`; `MyTopic` | `Conditionally Required` [3] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.template`](/docs/attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [4] | `/customers/{customerId}` | `Conditionally Required` if available. | ![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. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.system`](/docs/attributes-registry/messaging.md) | string | The messaging system as identified by the client instrumentation. [1] | `activemq`; `aws_sqs`; `eventgrid` | `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] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` If and only if the messaging operation has failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.destination.name`](/docs/attributes-registry/messaging.md) | string | The message destination name [3] | `MyQueue`; `MyTopic` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.template`](/docs/attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [5] | `/customers/{customerId}` | `Conditionally Required` if available. | ![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. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`messaging.destination.partition.id`](/docs/attributes-registry/messaging.md) | string | The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [7] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. +**[1]:** The actual messaging system may differ from the one known by the client. For example, when using Kafka client libraries to communicate with Azure Event Hubs, the `messaging.system` is set to `kafka` based on the instrumentation's best knowledge. + +**[2]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. When `error.type` is set to a type (e.g., an exception type), its canonical class name identifying the type within the artifact SHOULD be used. @@ -60,16 +62,16 @@ 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]:** Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If +**[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. -**[3]:** if and only if `messaging.destination.name` is known to have low cardinality. Otherwise, `messaging.destination.template` MAY be populated. +**[4]:** if and only if `messaging.destination.name` is known to have low cardinality. Otherwise, `messaging.destination.template` MAY be populated. -**[4]:** 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. +**[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. -**[5]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. +**[6]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. -**[6]:** 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. +**[7]:** 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. `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. diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 530a8de492..e7c1301a7c 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -287,28 +287,30 @@ as described in [Attributes specific to certain messaging systems](#attributes-s | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`messaging.operation.type`](/docs/attributes-registry/messaging.md) | string | A string identifying the type of the messaging operation. [1] | `publish`; `create`; `receive` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.system`](/docs/attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq`; `aws_sqs`; `eventgrid` | `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] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` If and only if the messaging operation has failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`messaging.batch.message_count`](/docs/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] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.anonymous`](/docs/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] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.name`](/docs/attributes-registry/messaging.md) | string | The message destination name [6] | `MyQueue`; `MyTopic` | `Conditionally Required` [7] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.template`](/docs/attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [8] | `/customers/{customerId}` | `Conditionally Required` [9] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.temporary`](/docs/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] | ![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. [11] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.system`](/docs/attributes-registry/messaging.md) | string | The messaging system as identified by the client instrumentation. [2] | `activemq`; `aws_sqs`; `eventgrid` | `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. [3] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` If and only if the messaging operation has failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.batch.message_count`](/docs/attributes-registry/messaging.md) | int | The number of messages sent, received, or processed in the scope of the batching operation. [4] | `0`; `1`; `2` | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.anonymous`](/docs/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` [6] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.name`](/docs/attributes-registry/messaging.md) | string | The message destination name [7] | `MyQueue`; `MyTopic` | `Conditionally Required` [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.template`](/docs/attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [9] | `/customers/{customerId}` | `Conditionally Required` [10] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.temporary`](/docs/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` [11] | ![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. [12] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`messaging.client.id`](/docs/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 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.destination.partition.id`](/docs/attributes-registry/messaging.md) | string | The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. | `1` | `Recommended` When applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.message.body.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body in bytes. [12] | `1439` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.body.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body in bytes. [13] | `1439` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.message.conversation_id`](/docs/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` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.message.envelope.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [13] | `2738` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.envelope.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [14] | `2738` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.message.id`](/docs/attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.operation.name`](/docs/attributes-registry/messaging.md) | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | `Recommended` [14] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [15] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this messaging system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.operation.name`](/docs/attributes-registry/messaging.md) | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | `Recommended` [15] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [16] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this messaging system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](/docs/attributes-registry/network.md) | int | Peer port of the messaging intermediary node where the operation was performed. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [16] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [17] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** If a custom value is used, it MUST be of low cardinality. -**[2]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. +**[2]:** The actual messaging system may differ from the one known by the client. For example, when using Kafka client libraries to communicate with Azure Event Hubs, the `messaging.system` is set to `kafka` based on the instrumentation's best knowledge. + +**[3]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. When `error.type` is set to a type (e.g., an exception type), its canonical class name identifying the type within the artifact SHOULD be used. @@ -328,38 +330,38 @@ 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. -**[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]:** 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 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]:** 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 +**[7]:** 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. -**[7]:** If span describes operation on a single message or if the value applies to all messages in the batch. +**[8]:** If span describes operation on a single message or if the value applies to all messages in the batch. -**[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. +**[9]:** 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. -**[9]:** If available. Instrumentations MUST NOT use `messaging.destination.name` as template unless low-cardinality of destination name is guaranteed. +**[10]:** If available. Instrumentations MUST NOT use `messaging.destination.name` as template unless low-cardinality of destination name is guaranteed. -**[10]:** If value is `true`. When missing, the value is assumed to be `false`. +**[11]:** If value is `true`. When missing, the value is assumed to be `false`. -**[11]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. +**[12]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. -**[12]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed +**[13]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed body size should be used. -**[13]:** 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. -**[14]:** If the operation is not sufficiently described by `messaging.operation.type`. +**[15]:** If the operation is not sufficiently described by `messaging.operation.type`. -**[15]:** Semantic conventions for individual messaging systems SHOULD document whether `network.peer.*` attributes are applicable. +**[16]:** Semantic conventions for individual messaging systems SHOULD document whether `network.peer.*` attributes are applicable. Network peer address and port are important when the application interacts with individual intermediary nodes directly, If a messaging operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. -**[16]:** 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. +**[17]:** 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. `messaging.operation.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. diff --git a/model/registry/db.yaml b/model/registry/db.yaml index 386e1fd72d..48bb854ebe 100644 --- a/model/registry/db.yaml +++ b/model/registry/db.yaml @@ -58,7 +58,11 @@ groups: then `` SHOULD be the 0-based index. examples: ['someval', '55'] - id: system - brief: An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + brief: The database management system (DBMS) product as identified by the client instrumentation. + note: > + 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. type: allow_custom_values: true members: diff --git a/model/registry/gen-ai.yaml b/model/registry/gen-ai.yaml index 100523a3b8..ab2ea3700c 100644 --- a/model/registry/gen-ai.yaml +++ b/model/registry/gen-ai.yaml @@ -14,7 +14,11 @@ groups: stability: experimental value: "openai" brief: 'OpenAI' - brief: The name of the LLM foundation model vendor. + brief: The Generative AI product as identified by the client 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` + is set to `openai` based on the instrumentation's best knowledge. examples: 'openai' tag: llm-generic-request - id: request.model diff --git a/model/registry/messaging.yaml b/model/registry/messaging.yaml index 554229ab67..f7c40f203f 100644 --- a/model/registry/messaging.yaml +++ b/model/registry/messaging.yaml @@ -137,8 +137,11 @@ groups: The system-specific name of the messaging operation. examples: [ "ack", "nack", "send" ] - id: system - brief: > - An identifier for the messaging system being used. See below for a list of well-known identifiers. + brief: The messaging system as identified by the client instrumentation. + note: > + The actual messaging system may differ from the one known by the client. + For example, when using Kafka client libraries to communicate with Azure Event Hubs, the `messaging.system` + is set to `kafka` based on the instrumentation's best knowledge. type: allow_custom_values: true members: From 7c3b66874ceae69e9489605c48c92e81b9b600ca Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Fri, 10 May 2024 08:34:23 -0700 Subject: [PATCH 5/7] Render full MD tables for messaging systems (#1018) --- .chloggen/1018.yaml | 4 + docs/messaging/azure-messaging.md | 156 +++++++----------------------- docs/messaging/gcp-pubsub.md | 63 +++++++++++- docs/messaging/kafka.md | 78 +++++++++++++-- docs/messaging/messaging-spans.md | 2 +- docs/messaging/rabbitmq.md | 69 ++++++++++++- docs/messaging/rocketmq.md | 76 ++++++++++++++- model/messaging-common.yaml | 8 +- model/metrics/messaging.yaml | 5 +- model/registry/messaging.yaml | 4 - model/trace/messaging.yaml | 107 ++++++++++++-------- 11 files changed, 379 insertions(+), 193 deletions(-) create mode 100644 .chloggen/1018.yaml diff --git a/.chloggen/1018.yaml b/.chloggen/1018.yaml new file mode 100644 index 0000000000..7b7fffa29c --- /dev/null +++ b/.chloggen/1018.yaml @@ -0,0 +1,4 @@ +change_type: enhancement +component: messaging +note: Show all applicable attributes in individual messaging semantic conventions. +issues: [869, 1018] diff --git a/docs/messaging/azure-messaging.md b/docs/messaging/azure-messaging.md index 201d28e420..eeed30298e 100644 --- a/docs/messaging/azure-messaging.md +++ b/docs/messaging/azure-messaging.md @@ -19,34 +19,22 @@ The following additional attributes are defined: | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`messaging.operation.type`](/docs/attributes-registry/messaging.md) | string | A string identifying the type of the messaging operation. [1] | `publish`; `create`; `receive` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.system`](/docs/attributes-registry/messaging.md) | string | The messaging system as identified by the client instrumentation. [2] | `activemq`; `aws_sqs`; `eventgrid` | `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. [3] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` If and only if the messaging operation has failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`messaging.batch.message_count`](/docs/attributes-registry/messaging.md) | int | The number of messages sent, received, or processed in the scope of the batching operation. [4] | `0`; `1`; `2` | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.anonymous`](/docs/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` [6] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.name`](/docs/attributes-registry/messaging.md) | string | The message destination name [7] | `MyQueue`; `MyTopic` | `Conditionally Required` [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.template`](/docs/attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [9] | `/customers/{customerId}` | `Conditionally Required` [10] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.temporary`](/docs/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` [11] | ![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] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` If and only if the messaging operation has failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.batch.message_count`](/docs/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] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.name`](/docs/attributes-registry/messaging.md) | string | The message destination name [5] | `MyQueue`; `MyTopic` | `Conditionally Required` [6] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.servicebus.destination.subscription_name`](/docs/attributes-registry/messaging.md) | string | The name of the subscription in the topic messages are received from. | `mySubscription` | `Conditionally Required` If messages are received from the subscription. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.servicebus.disposition_status`](/docs/attributes-registry/messaging.md) | string | Describes the [settlement type](https://learn.microsoft.com/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock). | `complete`; `abandon`; `dead_letter` | `Conditionally Required` if and only if `messaging.operation` is `settle`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.servicebus.message.delivery_count`](/docs/attributes-registry/messaging.md) | int | Number of deliveries that have been attempted for this message. | `2` | `Conditionally Required` [12] | ![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. [13] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`messaging.client.id`](/docs/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 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.partition.id`](/docs/attributes-registry/messaging.md) | string | The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. | `1` | `Recommended` When applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.message.body.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body in bytes. [14] | `1439` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.message.conversation_id`](/docs/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` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.message.envelope.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [15] | `2738` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.message.id`](/docs/attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.operation.name`](/docs/attributes-registry/messaging.md) | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | `Recommended` [16] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.servicebus.message.delivery_count`](/docs/attributes-registry/messaging.md) | int | Number of deliveries that have been attempted for this message. | `2` | `Conditionally Required` [7] | ![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. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.message.conversation_id`](/docs/attributes-registry/messaging.md) | string | Message [correlation Id](https://learn.microsoft.com/azure/service-bus-messaging/service-bus-messages-payloads#message-routing-and-correlation) property. | `MyConversationId` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.id`](/docs/attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | `Recommended` If span describes operation on a single message. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.operation.name`](/docs/attributes-registry/messaging.md) | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | `Recommended` [9] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.servicebus.message.enqueued_time`](/docs/attributes-registry/messaging.md) | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [17] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this messaging system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.port`](/docs/attributes-registry/network.md) | int | Peer port of the messaging intermediary node where the operation was performed. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [18] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [10] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** If a custom value is used, it MUST be of low cardinality. -**[2]:** The actual messaging system may differ from the one known by the client. For example, when using Kafka client libraries to communicate with Azure Event Hubs, the `messaging.system` is set to `kafka` based on the instrumentation's best knowledge. - -**[3]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. +**[2]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. When `error.type` is set to a type (e.g., an exception type), its canonical class name identifying the type within the artifact SHOULD be used. @@ -66,40 +54,22 @@ 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. -**[4]:** 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. - -**[5]:** If the span describes an operation on a batch of messages. +**[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. -**[6]:** If value is `true`. When missing, the value is assumed to be `false`. +**[4]:** If the span describes an operation on a batch of messages. -**[7]:** Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If +**[5]:** 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. -**[8]:** If span describes operation on a single message or if the value applies to all messages in the batch. - -**[9]:** 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. - -**[10]:** If available. Instrumentations MUST NOT use `messaging.destination.name` as template unless low-cardinality of destination name is guaranteed. - -**[11]:** If value is `true`. When missing, the value is assumed to be `false`. - -**[12]:** If delivery count is available and is bigger than 0. +**[6]:** If span describes operation on a single message or if the value applies to all messages in the batch. -**[13]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. +**[7]:** If delivery count is available and is bigger than 0. -**[14]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed -body size should be used. +**[8]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. -**[15]:** This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed -size should be used. +**[9]:** If the operation is not sufficiently described by `messaging.operation.type`. -**[16]:** If the operation is not sufficiently described by `messaging.operation.type`. - -**[17]:** Semantic conventions for individual messaging systems SHOULD document whether `network.peer.*` attributes are applicable. -Network peer address and port are important when the application interacts with individual intermediary nodes directly, -If a messaging operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. - -**[18]:** 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. +**[10]:** 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. `messaging.operation.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. @@ -111,21 +81,6 @@ If a messaging operation involved multiple network calls (for example retries), | `process` | One or more messages are delivered to or processed by a consumer. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `settle` | One or more messages are settled. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`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 | Stability | -|---|---|---| -| `activemq` | Apache ActiveMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws_sqs` | Amazon Simple Queue Service (SQS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `eventgrid` | Azure Event Grid | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `eventhubs` | Azure Event Hubs | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `servicebus` | Azure Service Bus | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gcp_pubsub` | Google Cloud Pub/Sub | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `jms` | Java Message Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `kafka` | Apache Kafka | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rabbitmq` | RabbitMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rocketmq` | Apache RocketMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - `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 | @@ -153,32 +108,20 @@ The following additional attributes are defined: | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`messaging.operation.type`](/docs/attributes-registry/messaging.md) | string | A string identifying the type of the messaging operation. [1] | `publish`; `create`; `receive` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.system`](/docs/attributes-registry/messaging.md) | string | The messaging system as identified by the client instrumentation. [2] | `activemq`; `aws_sqs`; `eventgrid` | `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. [3] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` If and only if the messaging operation has failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`messaging.batch.message_count`](/docs/attributes-registry/messaging.md) | int | The number of messages sent, received, or processed in the scope of the batching operation. [4] | `0`; `1`; `2` | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.anonymous`](/docs/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` [6] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.name`](/docs/attributes-registry/messaging.md) | string | The message destination name [7] | `MyQueue`; `MyTopic` | `Conditionally Required` [8] | ![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] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` If and only if the messaging operation has failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.batch.message_count`](/docs/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] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.name`](/docs/attributes-registry/messaging.md) | string | The message destination name [5] | `MyQueue`; `MyTopic` | `Conditionally Required` [6] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.destination.partition.id`](/docs/attributes-registry/messaging.md) | string | String representation of the partition id messages are sent to or received from, unique within the Event Hub. | `1` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.template`](/docs/attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [9] | `/customers/{customerId}` | `Conditionally Required` [10] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.temporary`](/docs/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` [11] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.eventhubs.consumer.group`](/docs/attributes-registry/messaging.md) | string | The name of the consumer group the event consumer is associated with. | `indexer` | `Conditionally Required` If not default ("$Default"). | ![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. [12] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`messaging.client.id`](/docs/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 | ![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. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`messaging.eventhubs.message.enqueued_time`](/docs/attributes-registry/messaging.md) | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.message.body.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body in bytes. [13] | `1439` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.message.conversation_id`](/docs/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` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.message.envelope.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [14] | `2738` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.message.id`](/docs/attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.operation.name`](/docs/attributes-registry/messaging.md) | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | `Recommended` [15] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [16] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this messaging system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.port`](/docs/attributes-registry/network.md) | int | Peer port of the messaging intermediary node where the operation was performed. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [17] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.message.id`](/docs/attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | `Recommended` If span describes operation on a single message. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.operation.name`](/docs/attributes-registry/messaging.md) | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | `Recommended` [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [9] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** If a custom value is used, it MUST be of low cardinality. -**[2]:** The actual messaging system may differ from the one known by the client. For example, when using Kafka client libraries to communicate with Azure Event Hubs, the `messaging.system` is set to `kafka` based on the instrumentation's best knowledge. - -**[3]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. +**[2]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. When `error.type` is set to a type (e.g., an exception type), its canonical class name identifying the type within the artifact SHOULD be used. @@ -198,38 +141,20 @@ 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. -**[4]:** 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. - -**[5]:** If the span describes an operation on a batch of messages. +**[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. -**[6]:** If value is `true`. When missing, the value is assumed to be `false`. +**[4]:** If the span describes an operation on a batch of messages. -**[7]:** Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If +**[5]:** 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. -**[8]:** If span describes operation on a single message or if the value applies to all messages in the batch. - -**[9]:** 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. - -**[10]:** If available. Instrumentations MUST NOT use `messaging.destination.name` as template unless low-cardinality of destination name is guaranteed. - -**[11]:** If value is `true`. When missing, the value is assumed to be `false`. - -**[12]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. +**[6]:** If span describes operation on a single message or if the value applies to all messages in the batch. -**[13]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed -body size should be used. +**[7]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. -**[14]:** This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed -size should be used. +**[8]:** If the operation is not sufficiently described by `messaging.operation.type`. -**[15]:** If the operation is not sufficiently described by `messaging.operation.type`. - -**[16]:** Semantic conventions for individual messaging systems SHOULD document whether `network.peer.*` attributes are applicable. -Network peer address and port are important when the application interacts with individual intermediary nodes directly, -If a messaging operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. - -**[17]:** 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. +**[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. `messaging.operation.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. @@ -241,21 +166,6 @@ If a messaging operation involved multiple network calls (for example retries), | `process` | One or more messages are delivered to or processed by a consumer. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `settle` | One or more messages are settled. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`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 | Stability | -|---|---|---| -| `activemq` | Apache ActiveMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws_sqs` | Amazon Simple Queue Service (SQS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `eventgrid` | Azure Event Grid | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `eventhubs` | Azure Event Hubs | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `servicebus` | Azure Service Bus | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gcp_pubsub` | Google Cloud Pub/Sub | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `jms` | Java Message Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `kafka` | Apache Kafka | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rabbitmq` | RabbitMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rocketmq` | Apache RocketMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - `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 5707da5b31..15d791ff9b 100644 --- a/docs/messaging/gcp-pubsub.md +++ b/docs/messaging/gcp-pubsub.md @@ -14,13 +14,74 @@ The Semantic Conventions for [Google Cloud Pub/Sub](https://cloud.google.com/pub For Google Cloud Pub/Sub, the following additional attributes are defined: - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| +| [`messaging.operation.type`](/docs/attributes-registry/messaging.md) | string | A string identifying the type of the messaging operation. [1] | `publish`; `create`; `receive` | `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] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` If and only if the messaging operation has failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.batch.message_count`](/docs/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] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.name`](/docs/attributes-registry/messaging.md) | string | The message destination name [5] | `MyQueue`; `MyTopic` | `Conditionally Required` [6] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.gcp_pubsub.message.ordering_key`](/docs/attributes-registry/messaging.md) | string | The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. | `ordering_key` | `Conditionally Required` If the message type has an ordering key set. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`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. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`messaging.gcp_pubsub.message.ack_deadline`](/docs/attributes-registry/messaging.md) | int | The ack deadline in seconds set for the modify ack deadline request. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.gcp_pubsub.message.ack_id`](/docs/attributes-registry/messaging.md) | string | The ack id for a given message. | `ack_id` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.gcp_pubsub.message.delivery_attempt`](/docs/attributes-registry/messaging.md) | int | The delivery attempt for a given message. | `2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.id`](/docs/attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | `Recommended` If span describes operation on a single message. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.operation.name`](/docs/attributes-registry/messaging.md) | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | `Recommended` [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [9] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +**[1]:** If a custom value is used, it MUST be of low cardinality. + +**[2]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. + +When `error.type` is set to a type (e.g., an exception type), its +canonical class name identifying the type within the artifact SHOULD be used. + +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low. +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. + +**[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]:** 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. + +**[6]:** If span describes operation on a single message or if the value applies to all messages in the batch. + +**[7]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. + +**[8]:** If the operation is not sufficiently described by `messaging.operation.type`. + +**[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. + +`messaging.operation.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 | +|---|---|---| +| `publish` | One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `create` | A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `receive` | One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process` | One or more messages are delivered to or processed by a consumer. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `settle` | One or more messages are settled. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`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) | ## Span names diff --git a/docs/messaging/kafka.md b/docs/messaging/kafka.md index 54aa67bf43..07dd75db40 100644 --- a/docs/messaging/kafka.md +++ b/docs/messaging/kafka.md @@ -24,18 +24,84 @@ described on this page. For Apache Kafka, the following additional attributes are defined: - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`messaging.kafka.message.tombstone`](/docs/attributes-registry/messaging.md) | boolean | A boolean that is true if the message is a tombstone. | | `Conditionally Required` [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.operation.type`](/docs/attributes-registry/messaging.md) | string | A string identifying the type of the messaging operation. [1] | `publish`; `create`; `receive` | `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] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` If and only if the messaging operation has failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.batch.message_count`](/docs/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] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.name`](/docs/attributes-registry/messaging.md) | string | The message destination name [5] | `MyQueue`; `MyTopic` | `Conditionally Required` [6] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.kafka.message.tombstone`](/docs/attributes-registry/messaging.md) | boolean | A boolean that is true if the message is a tombstone. | | `Conditionally Required` [7] | ![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. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.client.id`](/docs/attributes-registry/messaging.md) | string | A unique identifier for the client that consumes or produces a message. | `client-5`; `myhost@8742@s8083jm` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.destination.partition.id`](/docs/attributes-registry/messaging.md) | string | String representation of the partition id the message (or batch) is sent to or received from. | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.kafka.consumer.group`](/docs/attributes-registry/messaging.md) | string | Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. | `my-group` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.kafka.message.key`](/docs/attributes-registry/messaging.md) | string | Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. [2] | `myKey` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.kafka.message.offset`](/docs/attributes-registry/messaging.md) | int | The offset of a record in the corresponding Kafka partition. | `42` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.kafka.message.key`](/docs/attributes-registry/messaging.md) | string | Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. [9] | `myKey` | `Recommended` If span describes operation on a single message. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.kafka.message.offset`](/docs/attributes-registry/messaging.md) | int | The offset of a record in the corresponding Kafka partition. | `42` | `Recommended` If span describes operation on a single message. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.body.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body in bytes. [10] | `1439` | `Recommended` If span describes operation on a single message. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.id`](/docs/attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | `Recommended` If span describes operation on a single message. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.operation.name`](/docs/attributes-registry/messaging.md) | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | `Recommended` [11] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [12] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** If value is `true`. When missing, the value is assumed to be `false`. +**[1]:** If a custom value is used, it MUST be of low cardinality. -**[2]:** If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value. +**[2]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. + +When `error.type` is set to a type (e.g., an exception type), its +canonical class name identifying the type within the artifact SHOULD be used. + +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low. +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. + +**[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]:** 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. + +**[6]:** If span describes operation on a single message or if the value applies to all messages in the batch. + +**[7]:** If value is `true`. When missing, the value is assumed to be `false`. + +**[8]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. + +**[9]:** If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value. + +**[10]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed +body size should be used. + +**[11]:** If the operation is not sufficiently described by `messaging.operation.type`. + +**[12]:** 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. + +`messaging.operation.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 | +|---|---|---| +| `publish` | One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `create` | A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `receive` | One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process` | One or more messages are delivered to or processed by a consumer. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `settle` | One or more messages are settled. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`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) | For Apache Kafka producers, [`peer.service`](/docs/general/attributes.md#general-remote-service-attributes) SHOULD be set to the name of the broker or service the message will be sent to. diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index e7c1301a7c..b8b8bf0de6 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -300,7 +300,7 @@ as described in [Attributes specific to certain messaging systems](#attributes-s | [`messaging.message.body.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body in bytes. [13] | `1439` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.message.conversation_id`](/docs/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` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.message.envelope.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [14] | `2738` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.message.id`](/docs/attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.id`](/docs/attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | `Recommended` If span describes operation on a single message. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.operation.name`](/docs/attributes-registry/messaging.md) | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | `Recommended` [15] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [16] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this messaging system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](/docs/attributes-registry/network.md) | int | Peer port of the messaging intermediary node where the operation was performed. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | diff --git a/docs/messaging/rabbitmq.md b/docs/messaging/rabbitmq.md index c489cb7ebb..94b55f154e 100644 --- a/docs/messaging/rabbitmq.md +++ b/docs/messaging/rabbitmq.md @@ -17,15 +17,76 @@ described on this page. In RabbitMQ, the destination is defined by an *exchange* and a *routing key*. `messaging.destination.name` MUST be set to the name of the exchange. This will be an empty string if the default exchange is used. - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| +| [`messaging.operation.type`](/docs/attributes-registry/messaging.md) | string | A string identifying the type of the messaging operation. [1] | `publish`; `create`; `receive` | `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] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` If and only if the messaging operation has failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.destination.name`](/docs/attributes-registry/messaging.md) | string | The message destination name [3] | `MyQueue`; `MyTopic` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.rabbitmq.destination.routing_key`](/docs/attributes-registry/messaging.md) | string | RabbitMQ message routing key. | `myKey` | `Conditionally Required` If not empty. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.rabbitmq.message.delivery_tag`](/docs/attributes-registry/messaging.md) | int | RabbitMQ message delivery tag | `123` | `Conditionally Required` When available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [1] | `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 of the messaging intermediary node where the operation was performed. | `65123` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`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. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.message.body.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body in bytes. [6] | `1439` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.conversation_id`](/docs/attributes-registry/messaging.md) | string | Message [correlation Id](https://www.rabbitmq.com/tutorials/tutorial-six-java#correlation-id) property. | `MyConversationId` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.id`](/docs/attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | `Recommended` If span describes operation on a single message. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.operation.name`](/docs/attributes-registry/messaging.md) | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | `Recommended` [7] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. [8] | `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` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [9] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** If an operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. +**[1]:** If a custom value is used, it MUST be of low cardinality. + +**[2]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. + +When `error.type` is set to a type (e.g., an exception type), its +canonical class name identifying the type within the artifact SHOULD be used. + +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low. +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. + +**[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 span describes operation on a single message or if the value applies to all messages in the batch. + +**[5]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. + +**[6]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed +body size should be used. + +**[7]:** If the operation is not sufficiently described by `messaging.operation.type`. + +**[8]:** If an operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. + +**[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. + +`messaging.operation.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 | +|---|---|---| +| `publish` | One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `create` | A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `receive` | One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process` | One or more messages are delivered to or processed by a consumer. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `settle` | One or more messages are settled. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`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) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/messaging/rocketmq.md b/docs/messaging/rocketmq.md index c48d052fca..1316bce430 100644 --- a/docs/messaging/rocketmq.md +++ b/docs/messaging/rocketmq.md @@ -16,22 +16,88 @@ described on this page. Specific attributes for Apache RocketMQ are defined below. - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| +| [`messaging.operation.type`](/docs/attributes-registry/messaging.md) | string | A string identifying the type of the messaging operation. [1] | `publish`; `create`; `receive` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.rocketmq.client_group`](/docs/attributes-registry/messaging.md) | string | Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. | `myConsumerGroup` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.rocketmq.namespace`](/docs/attributes-registry/messaging.md) | string | Namespace of RocketMQ resources, resources in different namespaces are individual. | `myNamespace` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.rocketmq.message.delay_time_level`](/docs/attributes-registry/messaging.md) | int | The delay time level for delay message, which determines the message delay time. | `3` | `Conditionally Required` [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.rocketmq.message.delivery_timestamp`](/docs/attributes-registry/messaging.md) | int | The timestamp in milliseconds that the delay message is expected to be delivered to consumer. | `1665987217045` | `Conditionally Required` [2] | ![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] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` If and only if the messaging operation has failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.batch.message_count`](/docs/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] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.name`](/docs/attributes-registry/messaging.md) | string | The message destination name [5] | `MyQueue`; `MyTopic` | `Conditionally Required` [6] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.rocketmq.message.delay_time_level`](/docs/attributes-registry/messaging.md) | int | The delay time level for delay message, which determines the message delay time. | `3` | `Conditionally Required` [7] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.rocketmq.message.delivery_timestamp`](/docs/attributes-registry/messaging.md) | int | The timestamp in milliseconds that the delay message is expected to be delivered to consumer. | `1665987217045` | `Conditionally Required` [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.rocketmq.message.group`](/docs/attributes-registry/messaging.md) | string | It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. | `myMessageGroup` | `Conditionally Required` If the message type is FIFO. | ![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. [9] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.client.id`](/docs/attributes-registry/messaging.md) | string | A unique identifier for the client that consumes or produces a message. | `client-5`; `myhost@8742@s8083jm` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.body.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body in bytes. [10] | `1439` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.id`](/docs/attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | `Recommended` If span describes operation on a single message. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.operation.name`](/docs/attributes-registry/messaging.md) | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | `Recommended` [11] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.rocketmq.consumption_model`](/docs/attributes-registry/messaging.md) | string | Model of message consumption. This only applies to consumer spans. | `clustering`; `broadcasting` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.rocketmq.message.keys`](/docs/attributes-registry/messaging.md) | string[] | Key(s) of message, another way to mark message besides message id. | `keyA`; `keyB` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.rocketmq.message.tag`](/docs/attributes-registry/messaging.md) | string | The secondary classifier of message besides topic. | `tagA` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.rocketmq.message.type`](/docs/attributes-registry/messaging.md) | string | Type of message. | `normal`; `fifo`; `delay` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [12] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** If the message type is delay and delivery timestamp is not specified. +**[1]:** If a custom value is used, it MUST be of low cardinality. -**[2]:** If the message type is delay and delay time level is not specified. +**[2]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. + +When `error.type` is set to a type (e.g., an exception type), its +canonical class name identifying the type within the artifact SHOULD be used. + +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low. +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. + +**[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]:** 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. + +**[6]:** If span describes operation on a single message or if the value applies to all messages in the batch. + +**[7]:** If the message type is delay and delivery timestamp is not specified. + +**[8]:** If the message type is delay and delay time level is not specified. + +**[9]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. + +**[10]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed +body size should be used. + +**[11]:** If the operation is not sufficiently described by `messaging.operation.type`. + +**[12]:** 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. + +`messaging.operation.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 | +|---|---|---| +| `publish` | One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `create` | A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `receive` | One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process` | One or more messages are delivered to or processed by a consumer. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `settle` | One or more messages are settled. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`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) | `messaging.rocketmq.consumption_model` 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 index 4728e516fa..403eeb4535 100644 --- a/model/messaging-common.yaml +++ b/model/messaging-common.yaml @@ -1,12 +1,10 @@ groups: - - id: messaging.attributes.common + - id: attributes.messaging.common.minimal type: attribute_group - brief: "Common messaging attributes." + brief: "Common cross-signal messaging attributes." prefix: messaging attributes: - - ref: messaging.system - requirement_level: required - - ref: messaging.destination.partition.id + # TODO: Not adding `messaging.system` to the minimal because of https://github.com/open-telemetry/build-tools/issues/192 - ref: error.type examples: ['amqp:decode-error', 'KAFKA_STORAGE_ERROR', 'channel-error'] requirement_level: diff --git a/model/metrics/messaging.yaml b/model/metrics/messaging.yaml index 03a1a5b44b..43c76a9eb8 100644 --- a/model/metrics/messaging.yaml +++ b/model/metrics/messaging.yaml @@ -3,8 +3,11 @@ groups: type: attribute_group stability: experimental brief: "Common messaging metrics attributes." - extends: messaging.attributes.common + extends: attributes.messaging.common.minimal attributes: + - ref: messaging.system + requirement_level: required + - ref: messaging.destination.partition.id - 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. diff --git a/model/registry/messaging.yaml b/model/registry/messaging.yaml index f7c40f203f..cefed2688e 100644 --- a/model/registry/messaging.yaml +++ b/model/registry/messaging.yaml @@ -336,28 +336,24 @@ groups: brief: > The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. examples: 'ordering_key' - tag: tech-specific-gcp-pubsub - id: gcp_pubsub.message.ack_id type: string stability: experimental brief: > The ack id for a given message. examples: 'ack_id' - tag: tech-specific-gcp-pubsub - id: gcp_pubsub.message.ack_deadline type: int stability: experimental brief: > The ack deadline in seconds set for the modify ack deadline request. examples: 10 - tag: tech-specific-gcp-pubsub - id: gcp_pubsub.message.delivery_attempt type: int stability: experimental brief: > The delivery attempt for a given message. examples: 2 - tag: tech-specific-gcp-pubsub - id: registry.messaging.servicebus prefix: messaging type: attribute_group diff --git a/model/trace/messaging.yaml b/model/trace/messaging.yaml index 02870702ab..e20ecc3e00 100644 --- a/model/trace/messaging.yaml +++ b/model/trace/messaging.yaml @@ -47,27 +47,35 @@ groups: - ref: messaging.destination_publish.name - ref: messaging.destination_publish.anonymous - - id: messaging - type: span + - id: attributes.messaging.trace.minimal + type: attribute_group brief: > - This document defines general attributes used in - messaging systems. - extends: messaging.attributes.common + Defines minimal set of attributes used by all messaging systems. + extends: attributes.messaging.common.minimal attributes: - ref: messaging.operation.type requirement_level: required - ref: messaging.operation.name requirement_level: recommended: If the operation is not sufficiently described by `messaging.operation.type`. - - ref: messaging.batch.message_count + - ref: messaging.destination.name requirement_level: - conditionally_required: If the span describes an operation on a batch of messages. + conditionally_required: If span describes operation on a single message or if the value applies to all messages in the batch. + - ref: messaging.message.id + requirement_level: + recommended: If span describes operation on a single message. + + - id: messaging + type: span + brief: > + Defines a full set of attributes used in messaging systems. + extends: attributes.messaging.trace.minimal + attributes: + - ref: messaging.system + requirement_level: required - ref: messaging.client.id requirement_level: recommended: If a client id is available - - 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. - ref: messaging.destination.partition.id requirement_level: recommended: When applicable. @@ -82,10 +90,12 @@ groups: - ref: messaging.destination.anonymous requirement_level: conditionally_required: If value is `true`. When missing, the value is assumed to be `false`. - - ref: messaging.message.id - ref: messaging.message.conversation_id - ref: messaging.message.envelope.size - ref: messaging.message.body.size + - ref: messaging.batch.message_count + requirement_level: + conditionally_required: If the span describes an operation on a batch of messages. - ref: network.peer.address brief: Peer address of the messaging intermediary node where the operation was performed. requirement_level: @@ -101,10 +111,10 @@ groups: requirement_level: recommended: if and only if `network.peer.address` is set. - - id: messaging.tech_specific.network.attributes + - id: messaging.network.attributes type: attribute_group brief: Attributes that describe messaging operation along with network information. - extends: messaging + extends: attributes.messaging.trace.minimal attributes: - ref: network.peer.address requirement_level: recommended @@ -115,26 +125,24 @@ groups: - id: messaging.rabbitmq type: attribute_group - extends: messaging.tech_specific.network.attributes + extends: messaging.network.attributes brief: > Attributes for RabbitMQ attributes: - ref: messaging.rabbitmq.destination.routing_key requirement_level: conditionally_required: If not empty. - tag: tech-specific - ref: messaging.rabbitmq.message.delivery_tag requirement_level: conditionally_required: When available. - tag: tech-specific - - ref: network.peer.address - tag: tech-specific - - ref: network.peer.port - tag: tech-specific + - ref: messaging.message.conversation_id + brief: > + Message [correlation Id](https://www.rabbitmq.com/tutorials/tutorial-six-java#correlation-id) property. + - ref: messaging.message.body.size - id: messaging.kafka type: attribute_group - extends: messaging + extends: attributes.messaging.trace.minimal brief: > Attributes for Apache Kafka attributes: @@ -142,73 +150,77 @@ groups: brief: > String representation of the partition id the message (or batch) is sent to or received from. requirement_level: recommended - tag: tech-specific - ref: messaging.kafka.message.key - tag: tech-specific + requirement_level: + recommended: If span describes operation on a single message. - ref: messaging.kafka.consumer.group - tag: tech-specific - ref: messaging.kafka.message.offset - tag: tech-specific + requirement_level: + recommended: If span describes operation on a single message. - ref: messaging.kafka.message.tombstone requirement_level: conditionally_required: If value is `true`. When missing, the value is assumed to be `false`. - tag: tech-specific + - ref: messaging.batch.message_count + requirement_level: + conditionally_required: If the span describes an operation on a batch of messages. + - ref: messaging.client.id + - ref: messaging.message.body.size + requirement_level: + recommended: If span describes operation on a single message. - id: messaging.rocketmq type: attribute_group - extends: messaging + extends: attributes.messaging.trace.minimal brief: > Attributes for Apache RocketMQ attributes: - ref: messaging.rocketmq.namespace requirement_level: required - tag: tech-specific - ref: messaging.rocketmq.client_group requirement_level: required - tag: tech-specific - ref: messaging.rocketmq.message.delivery_timestamp requirement_level: conditionally_required: If the message type is delay and delay time level is not specified. - tag: tech-specific - ref: messaging.rocketmq.message.delay_time_level requirement_level: conditionally_required: If the message type is delay and delivery timestamp is not specified. - tag: tech-specific - ref: messaging.rocketmq.message.group requirement_level: conditionally_required: If the message type is FIFO. - tag: tech-specific - ref: messaging.rocketmq.message.type - tag: tech-specific - ref: messaging.rocketmq.message.tag - tag: tech-specific - ref: messaging.rocketmq.message.keys - tag: tech-specific - ref: messaging.rocketmq.consumption_model - tag: tech-specific + - ref: messaging.client.id + - ref: messaging.message.body.size + - ref: messaging.batch.message_count + requirement_level: + conditionally_required: If the span describes an operation on a batch of messages. + - id: messaging.gcp_pubsub type: attribute_group stability: experimental - extends: messaging + extends: attributes.messaging.trace.minimal brief: > Attributes for Google Cloud Pub/Sub attributes: - ref: messaging.gcp_pubsub.message.ordering_key - tag: tech-specific-gcp-pubsub requirement_level: conditionally_required: If the message type has an ordering key set. - ref: messaging.gcp_pubsub.message.delivery_attempt - tag: tech-specific-gcp-pubsub - ref: messaging.gcp_pubsub.message.ack_deadline - tag: tech-specific-gcp-pubsub - ref: messaging.gcp_pubsub.message.ack_id - tag: tech-specific-gcp-pubsub + - ref: messaging.batch.message_count + requirement_level: + conditionally_required: If the span describes an operation on a batch of messages. + - id: messaging.servicebus type: attribute_group - extends: messaging + extends: attributes.messaging.trace.minimal brief: > Attributes for Azure Service Bus attributes: + - ref: messaging.operation.name - ref: messaging.servicebus.message.delivery_count requirement_level: conditionally_required: If delivery count is available and is bigger than 0. @@ -219,12 +231,18 @@ groups: - ref: messaging.servicebus.disposition_status requirement_level: conditionally_required: if and only if `messaging.operation` is `settle`. + - ref: messaging.message.conversation_id + brief: Message [correlation Id](https://learn.microsoft.com/azure/service-bus-messaging/service-bus-messages-payloads#message-routing-and-correlation) property. + - ref: messaging.batch.message_count + requirement_level: + conditionally_required: If the span describes an operation on a batch of messages. - id: messaging.eventhubs type: attribute_group - extends: messaging + extends: attributes.messaging.trace.minimal brief: > Attributes for Azure Event Hubs attributes: + - ref: messaging.operation.name - ref: messaging.destination.partition.id brief: > String representation of the partition id messages are sent to or received from, unique within the Event Hub. @@ -234,3 +252,6 @@ groups: - ref: messaging.eventhubs.consumer.group requirement_level: conditionally_required: If not default ("$Default"). + - ref: messaging.batch.message_count + requirement_level: + conditionally_required: If the span describes an operation on a batch of messages. From 597364dc5857cece7421bd0b49353f6997eeb1f7 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Fri, 10 May 2024 12:57:42 -0400 Subject: [PATCH 6/7] Add `net.peer.ip` and `net.host.ip` to deprecated yaml (#1029) Co-authored-by: Trask Stalnaker --- .chloggen/deprecated-net.yaml | 22 ++++++++++++++++++++++ docs/attributes-registry/network.md | 2 ++ model/registry/deprecated/network.yaml | 12 ++++++++++++ 3 files changed, 36 insertions(+) create mode 100755 .chloggen/deprecated-net.yaml diff --git a/.chloggen/deprecated-net.yaml b/.chloggen/deprecated-net.yaml new file mode 100755 index 0000000000..956d01ff28 --- /dev/null +++ b/.chloggen/deprecated-net.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: bug_fix + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: net + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add previously deprecated net attributes to registry + +# 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: [1029] + +# (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: These attributes were deprecated in 1.13 diff --git a/docs/attributes-registry/network.md b/docs/attributes-registry/network.md index 9d038e5e0a..bd23b59169 100644 --- a/docs/attributes-registry/network.md +++ b/docs/attributes-registry/network.md @@ -107,8 +107,10 @@ These attributes may be used for any network related operation. | Attribute | Type | Description | Examples | Stability | | ---------------------- | ------ | -------------------------------------------------------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `net.host.ip` | string | Deprecated, use `network.local.address`. | `192.168.0.1` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.local.address`. | | `net.host.name` | string | Deprecated, use `server.address`. | `example.com` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `server.address`. | | `net.host.port` | int | Deprecated, use `server.port`. | `8080` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `server.port`. | +| `net.peer.ip` | string | Deprecated, use `network.peer.address`. | `127.0.0.1` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.peer.address`. | | `net.peer.name` | string | Deprecated, use `server.address` on client spans and `client.address` on server spans. | `example.com` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `server.address` on client spans and `client.address` on server spans. | | `net.peer.port` | int | Deprecated, use `server.port` on client spans and `client.port` on server spans. | `8080` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `server.port` on client spans and `client.port` on server spans. | | `net.protocol.name` | string | Deprecated, use `network.protocol.name`. | `amqp`; `http`; `mqtt` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.protocol.name`. | diff --git a/model/registry/deprecated/network.yaml b/model/registry/deprecated/network.yaml index 6614467174..f13c79f9a9 100644 --- a/model/registry/deprecated/network.yaml +++ b/model/registry/deprecated/network.yaml @@ -35,12 +35,24 @@ groups: stability: experimental brief: Deprecated, use `server.port` on client spans and `client.port` on server spans. examples: [8080] + - id: peer.ip + type: string + deprecated: "Replaced by `network.peer.address`." + stability: experimental + brief: Deprecated, use `network.peer.address`. + examples: '127.0.0.1' - id: host.name type: string deprecated: "Replaced by `server.address`." stability: experimental brief: Deprecated, use `server.address`. examples: ['example.com'] + - id: host.ip + type: string + deprecated: "Replaced by `network.local.address`." + stability: experimental + brief: Deprecated, use `network.local.address`. + examples: '192.168.0.1' - id: host.port type: int deprecated: "Replaced by `server.port`." From 507daf4bb9b9abe615bd641bbad248d810791177 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Fri, 10 May 2024 13:19:53 -0400 Subject: [PATCH 7/7] Add `http` deprecated attributes to model (#1025) Co-authored-by: Trask Stalnaker Co-authored-by: Liudmila Molkova --- .chloggen/deprecated-http.client_ip.yaml | 22 +++++++++++++++++ docs/attributes-registry/http.md | 27 ++++++++++++--------- model/registry/deprecated/http.yaml | 30 ++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 11 deletions(-) create mode 100755 .chloggen/deprecated-http.client_ip.yaml diff --git a/.chloggen/deprecated-http.client_ip.yaml b/.chloggen/deprecated-http.client_ip.yaml new file mode 100755 index 0000000000..57e6224137 --- /dev/null +++ b/.chloggen/deprecated-http.client_ip.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: 'bug_fix' + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: http + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add previously deprecated http attributes to registry + +# 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: [1025] + +# (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: These attributes were deprecated in 1.13 diff --git a/docs/attributes-registry/http.md b/docs/attributes-registry/http.md index 5877bc0421..21b3eca99b 100644 --- a/docs/attributes-registry/http.md +++ b/docs/attributes-registry/http.md @@ -82,17 +82,22 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin Describes deprecated HTTP attributes. -| Attribute | Type | Description | Examples | Stability | -| ------------------------------ | ------ | -------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | -| `http.flavor` | string | Deprecated, use `network.protocol.name` instead. | `1.0`; `1.1`; `2.0` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.protocol.name`. | -| `http.method` | string | Deprecated, use `http.request.method` instead. | `GET`; `POST`; `HEAD` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `http.request.method`. | -| `http.request_content_length` | int | Deprecated, use `http.request.header.content-length` instead. | `3495` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `http.request.header.content-length`. | -| `http.response_content_length` | int | Deprecated, use `http.response.header.content-length` instead. | `3495` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `http.response.header.content-length`. | -| `http.scheme` | string | Deprecated, use `url.scheme` instead. | `http`; `https` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `url.scheme` instead. | -| `http.status_code` | int | Deprecated, use `http.response.status_code` instead. | `200` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `http.response.status_code`. | -| `http.target` | string | Deprecated, use `url.path` and `url.query` instead. | `/search?q=OpenTelemetry#SemConv` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Split to `url.path` and `url.query. | -| `http.url` | string | Deprecated, use `url.full` instead. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `url.full`. | -| `http.user_agent` | string | Deprecated, use `user_agent.original` instead. | `CERN-LineMode/2.15 libwww/2.17b3`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `user_agent.original`. | +| Attribute | Type | Description | Examples | Stability | +| ------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `http.client_ip` | string | Deprecated, use `client.address` instead. | `83.164.160.102` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `client.address`. | +| `http.flavor` | string | Deprecated, use `network.protocol.name` instead. | `1.0`; `1.1`; `2.0` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.protocol.name`. | +| `http.host` | string | Deprecated, use one of `server.address`, `client.address` or `http.request.header.host` instead, depending on the usage. | `www.example.org` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by one of `server.address`, `client.address` or `http.request.header.host`, depending on the usage. | +| `http.method` | string | Deprecated, use `http.request.method` instead. | `GET`; `POST`; `HEAD` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `http.request.method`. | +| `http.request_content_length` | int | Deprecated, use `http.request.header.content-length` instead. | `3495` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `http.request.header.content-length`. | +| `http.request_content_length_uncompressed` | int | Deprecated, use `http.request.body.size` instead. | `5493` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `http.request.body.size`. | +| `http.response_content_length` | int | Deprecated, use `http.response.header.content-length` instead. | `3495` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `http.response.header.content-length`. | +| `http.response_content_length_uncompressed` | int | Deprecated, use `http.response.body.size` instead. | `5493` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replace by `http.response.body.size`. | +| `http.scheme` | string | Deprecated, use `url.scheme` instead. | `http`; `https` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `url.scheme` instead. | +| `http.server_name` | string | Deprecated, use `server.address` instead. | `example.com` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `server.address`. | +| `http.status_code` | int | Deprecated, use `http.response.status_code` instead. | `200` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `http.response.status_code`. | +| `http.target` | string | Deprecated, use `url.path` and `url.query` instead. | `/search?q=OpenTelemetry#SemConv` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Split to `url.path` and `url.query. | +| `http.url` | string | Deprecated, use `url.full` instead. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `url.full`. | +| `http.user_agent` | string | Deprecated, use `user_agent.original` instead. | `CERN-LineMode/2.15 libwww/2.17b3`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `user_agent.original`. | `http.flavor` 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/registry/deprecated/http.yaml b/model/registry/deprecated/http.yaml index 4eaaa6ce19..6fc36ef838 100644 --- a/model/registry/deprecated/http.yaml +++ b/model/registry/deprecated/http.yaml @@ -46,6 +46,36 @@ groups: stability: experimental deprecated: "Replaced by `http.response.header.content-length`." examples: 3495 + - id: client_ip + type: string + stability: experimental + deprecated: "Replaced by `client.address`." + brief: "Deprecated, use `client.address` instead." + examples: '83.164.160.102' + - id: host + type: string + stability: experimental + deprecated: "Replaced by one of `server.address`, `client.address` or `http.request.header.host`, depending on the usage." + brief: "Deprecated, use one of `server.address`, `client.address` or `http.request.header.host` instead, depending on the usage." + examples: ['www.example.org'] + - id: request_content_length_uncompressed + stability: experimental + deprecated: "Replaced by `http.request.body.size`." + type: int + brief: "Deprecated, use `http.request.body.size` instead." + examples: 5493 + - id: response_content_length_uncompressed + stability: experimental + deprecated: "Replace by `http.response.body.size`." + type: int + brief: "Deprecated, use `http.response.body.size` instead." + examples: 5493 + - id: server_name + type: string + stability: experimental + deprecated: "Replaced by `server.address`." + brief: "Deprecated, use `server.address` instead." + examples: ['example.com'] - id: flavor type: allow_custom_values: true