From 026fad16d73816efc9b2eb064140959459531b55 Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Thu, 17 Jul 2025 23:34:06 +0200 Subject: [PATCH 01/36] Add empty value to attribute --- specification/common/README.md | 12 +++++------- specification/common/attribute-type-mapping.md | 6 ++++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/specification/common/README.md b/specification/common/README.md index 4b95d8b8508..1724db3cfcd 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -8,7 +8,7 @@ path_base_for_github_subdir: # Common specification concepts -**Status**: [Stable](../document-status.md) +**Status**: [Stable](../document-status.md), except where otherwise specified
Table of Contents @@ -38,15 +38,13 @@ An `Attribute` is a key-value pair, which MUST have the following properties: - A primitive type: string, boolean, double precision floating point (IEEE 754-1985) or signed 64 bit integer. - An array of primitive type values. The array MUST be homogeneous, i.e., it MUST NOT contain values of different types. + - **Status**: [Stable](../document-status.md) - An empty value (e.g. `null`). For protocols that do not natively support non-string values, non-string values SHOULD be represented as JSON-encoded strings. For example, the expression `int64(100)` will be encoded as `100`, `float64(1.5)` will be encoded as `1.5`, and an empty array of any type will be encoded as `[]`. -Attribute values expressing a numerical value of zero, an empty string, or an -empty array are considered meaningful and MUST be stored and passed on to -processors / exporters. - -Attribute values of `null` are not valid and attempting to set a `null` value is -undefined behavior. +Attribute values expressing an empty value, a numerical value of zero, +an empty string, or an empty array are considered meaningful and MUST be stored +and passed on to processors / exporters. `null` values SHOULD NOT be allowed in arrays. However, if it is impossible to make sure that no `null` values are accepted diff --git a/specification/common/attribute-type-mapping.md b/specification/common/attribute-type-mapping.md index e936eb1695c..56251663268 100644 --- a/specification/common/attribute-type-mapping.md +++ b/specification/common/attribute-type-mapping.md @@ -54,6 +54,12 @@ follow the rules described below. ### Primitive Values +#### Empty Value + +Empty values SHOULD be converted to AnyValue with no +[value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L28-L30) +field being set. + #### Integer Values Integer values which are within the range of 64 bit signed numbers From 18311641df520e578137ef9ca11fc6766825595a Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Thu, 17 Jul 2025 23:35:32 +0200 Subject: [PATCH 02/36] Update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23a27cd2a00..139c4fadc81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,6 +57,9 @@ release. ### Common +- Add empty value to attribute. + ([#4595](https://github.com/open-telemetry/opentelemetry-specification/pull/4595)) + ### Supplementary Guidelines ### OTEPs From 82e8913989e8d3250fb546ea7398efe6b0f8f5d0 Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Thu, 17 Jul 2025 23:44:16 +0200 Subject: [PATCH 03/36] toc --- specification/common/attribute-type-mapping.md | 1 + 1 file changed, 1 insertion(+) diff --git a/specification/common/attribute-type-mapping.md b/specification/common/attribute-type-mapping.md index 56251663268..015847c8aeb 100644 --- a/specification/common/attribute-type-mapping.md +++ b/specification/common/attribute-type-mapping.md @@ -13,6 +13,7 @@ linkTitle: Mapping to AnyValue - [Converting to AnyValue](#converting-to-anyvalue) * [Primitive Values](#primitive-values) + + [Empty Value](#empty-value) + [Integer Values](#integer-values) + [Enumerations](#enumerations) + [Floating Point Values](#floating-point-values) From 9cab0c47c347298743bb795ac327d80187052b70 Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Thu, 17 Jul 2025 23:47:49 +0200 Subject: [PATCH 04/36] fix status --- specification/common/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/README.md b/specification/common/README.md index 1724db3cfcd..06806a5bc2b 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -38,7 +38,7 @@ An `Attribute` is a key-value pair, which MUST have the following properties: - A primitive type: string, boolean, double precision floating point (IEEE 754-1985) or signed 64 bit integer. - An array of primitive type values. The array MUST be homogeneous, i.e., it MUST NOT contain values of different types. - - **Status**: [Stable](../document-status.md) - An empty value (e.g. `null`). + - **Status**: [Development](../document-status.md) - An empty value (e.g. `null`). For protocols that do not natively support non-string values, non-string values SHOULD be represented as JSON-encoded strings. For example, the expression `int64(100)` will be encoded as `100`, `float64(1.5)` will be encoded as `1.5`, and an empty array of any type will be encoded as `[]`. From 85db60a47e8dfc50e793059dd229fcc60fccb22b Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Thu, 17 Jul 2025 23:58:27 +0200 Subject: [PATCH 05/36] Remove the note that extending attributes is a breaking change --- specification/common/README.md | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/specification/common/README.md b/specification/common/README.md index 06806a5bc2b..95ad05fbd08 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -81,21 +81,6 @@ reflects that LogRecord attributes are expected to model data produced from external log APIs, which do not necessarily have the same value type restrictions as the standard attribute definition. -Note: Extending the set of standard attribute value types is a breaking change. -This was decided after extensive debate, with arguments as follows: - -* Limiting the types of attribute values to a set which has proved sufficient - during several years of OpenTelemetry's development is a useful guardrail for - design. In taking additional value types off the table, we narrow the solution - space and have more productive design conversations. -* Upon proposing to extend support for complex value types, we received significant - pushback. Limiting attribute value types to primitives and arrays of primitives - simplifies data consumers' efforts to create search indexes and perform statistical - analysis. -* To address concerns over restricting standard attributes to primitive types, it was - called out that complex types can be encoded as existing primitive types, such as - representing datetime as a string or 64 bit integer. - ### Attribute Limits Execution of erroneous code can result in unintended attributes. If there are no From eaea1ea7dbe664bad1f6ae2b9cace004bb19d951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Paj=C4=85k?= Date: Fri, 18 Jul 2025 00:24:52 +0200 Subject: [PATCH 06/36] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 139c4fadc81..f36b92b717b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,7 +57,7 @@ release. ### Common -- Add empty value to attribute. +- Add empty value attribute. ([#4595](https://github.com/open-telemetry/opentelemetry-specification/pull/4595)) ### Supplementary Guidelines From 25c2c257e4975284bf76b3fe3b70d12b4c71f0e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Paj=C4=85k?= Date: Fri, 18 Jul 2025 04:03:32 +0200 Subject: [PATCH 07/36] Update specification/common/attribute-type-mapping.md Co-authored-by: Tyler Yahn --- specification/common/attribute-type-mapping.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/attribute-type-mapping.md b/specification/common/attribute-type-mapping.md index 015847c8aeb..d41ebc82979 100644 --- a/specification/common/attribute-type-mapping.md +++ b/specification/common/attribute-type-mapping.md @@ -57,7 +57,7 @@ follow the rules described below. #### Empty Value -Empty values SHOULD be converted to AnyValue with no +Empty values MUST be converted to AnyValue with no [value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L28-L30) field being set. From c5400989f60bb90e4e47407ec1c3b3c45322d61d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Paj=C4=85k?= Date: Tue, 22 Jul 2025 17:46:08 +0200 Subject: [PATCH 08/36] revert breaking change note --- specification/common/README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/specification/common/README.md b/specification/common/README.md index 95ad05fbd08..06806a5bc2b 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -81,6 +81,21 @@ reflects that LogRecord attributes are expected to model data produced from external log APIs, which do not necessarily have the same value type restrictions as the standard attribute definition. +Note: Extending the set of standard attribute value types is a breaking change. +This was decided after extensive debate, with arguments as follows: + +* Limiting the types of attribute values to a set which has proved sufficient + during several years of OpenTelemetry's development is a useful guardrail for + design. In taking additional value types off the table, we narrow the solution + space and have more productive design conversations. +* Upon proposing to extend support for complex value types, we received significant + pushback. Limiting attribute value types to primitives and arrays of primitives + simplifies data consumers' efforts to create search indexes and perform statistical + analysis. +* To address concerns over restricting standard attributes to primitive types, it was + called out that complex types can be encoded as existing primitive types, such as + representing datetime as a string or 64 bit integer. + ### Attribute Limits Execution of erroneous code can result in unintended attributes. If there are no From aa3c41ced17343159958d71b317c2b3b85da969c Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Tue, 26 Aug 2025 15:51:27 +0200 Subject: [PATCH 09/36] remove changelog entry --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3ffc2288cb..71ec5ceaeb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,8 +33,6 @@ release. - ⚠️ **IMPORTANT**: Extending the set of standard attribute value types is no longer a breaking change. ([#4614](https://github.com/open-telemetry/opentelemetry-specification/pull/4614)) -- Add empty value attribute. - ([#4595](https://github.com/open-telemetry/opentelemetry-specification/pull/4595)) ### Supplementary Guidelines From 20043e347776af83df01e68fef233d5bf33822df Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Tue, 26 Aug 2025 16:10:46 +0200 Subject: [PATCH 10/36] remove "standard attribute" term --- ...nding-attributes-to-support-complex-values.md | 2 +- spec-compliance-matrix.md | 1 - specification/common/README.md | 16 ---------------- specification/entities/data-model.md | 4 ++-- specification/logs/api.md | 8 -------- specification/logs/data-model.md | 3 --- specification/resource/data-model.md | 6 +++--- specification/resource/sdk.md | 3 ++- 8 files changed, 8 insertions(+), 35 deletions(-) diff --git a/oteps/4485-extending-attributes-to-support-complex-values.md b/oteps/4485-extending-attributes-to-support-complex-values.md index 737c03732d4..8a3cbfe81d0 100644 --- a/oteps/4485-extending-attributes-to-support-complex-values.md +++ b/oteps/4485-extending-attributes-to-support-complex-values.md @@ -94,7 +94,7 @@ extending the standard attributes provides a more seamless and user-friendly API Currently, the SDK specification has a clause that says extending the set of standard attribute would be -[considered a breaking change](/specification/common/README.md#standard-attribute). +[considered a breaking change](/specification/common/README.md#attribute). We believe that removing this clause and extending standard attributes can be done gracefully across the OpenTelemetry ecosystem diff --git a/spec-compliance-matrix.md b/spec-compliance-matrix.md index 336058fd51d..eb9e585df41 100644 --- a/spec-compliance-matrix.md +++ b/spec-compliance-matrix.md @@ -199,7 +199,6 @@ Disclaimer: this list of features is still a work in progress, please refer to t | LoggerProvider.Shutdown | | | + | | + | | | + | | + | - | | | LoggerProvider.ForceFlush | | | + | | + | | | + | | + | - | | | Logger.Emit(LogRecord) | | | + | | + | | | + | | + | - | | -| Reuse Standard Attributes | X | + | | | | | | | | | | | | LogRecord.Set EventName | | + | | | | | | | + | + | | | | Logger.Enabled | X | + | | | | | | | + | + | | | | SimpleLogRecordProcessor | | | + | | + | | | + | | + | | | diff --git a/specification/common/README.md b/specification/common/README.md index 95ad05fbd08..ad4b94cacd3 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -16,7 +16,6 @@ path_base_for_github_subdir: - [Attribute](#attribute) - * [Standard Attribute](#standard-attribute) * [Attribute Limits](#attribute-limits) + [Configurable Parameters](#configurable-parameters) + [Exempt Entities](#exempt-entities) @@ -66,21 +65,6 @@ See [Requirement Level](https://github.com/open-telemetry/semantic-conventions/b See [this document](attribute-type-mapping.md) to find out how to map values obtained outside OpenTelemetry into OpenTelemetry attribute values. -### Standard Attribute - -Attributes are used in various places throughout the OpenTelemetry data model. -We designate the [previous attribute section](#attribute) as the standard -attribute definition, in order to facilitate more intuitive and consistent API / -SDK design. - -The standard attribute definition SHOULD be used to represent attributes in data -modeling unless there is a strong justification to diverge. For example, the Log -Data Model has an extended [attributes](../logs/data-model.md#field-attributes) -definition allowing values of [type `Any`](../logs/data-model.md#type-any). This -reflects that LogRecord attributes are expected to model data produced from -external log APIs, which do not necessarily have the same value type -restrictions as the standard attribute definition. - ### Attribute Limits Execution of erroneous code can result in unintended attributes. If there are no diff --git a/specification/entities/data-model.md b/specification/entities/data-model.md index 22c277edd82..4c7c088657c 100644 --- a/specification/entities/data-model.md +++ b/specification/entities/data-model.md @@ -48,8 +48,8 @@ physical format and encoding of how entity data is recorded). | Field | Type | Description | |--------------|----------------------------------------|-----------------| | Type | string | Defines the type of the entity. MUST not change during the lifetime of the entity. For example: "service" or "host". This field is required and MUST not be empty for valid entities. | -| Id | map | Attributes that identify the entity.

MUST not change during the lifetime of the entity. The Id must contain at least one attribute.

Follows OpenTelemetry [Standard attribute definition](../common/README.md#standard-attribute). SHOULD follow OpenTelemetry [semantic conventions](https://github.com/open-telemetry/semantic-conventions) for attributes. | -| Description | map | Descriptive (non-identifying) attributes of the entity.

MAY change over the lifetime of the entity. MAY be empty. These attributes are not part of entity's identity.

Follows [any](../logs/data-model.md#type-any) value definition in the OpenTelemetry spec. Arbitrary deep nesting of values for arrays and maps is allowed.

SHOULD follow OpenTelemetry [semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/README.md) for attributes. | +| Id | map | Attributes that identify the entity.

MUST not change during the lifetime of the entity. The Id must contain at least one attribute.

Follows OpenTelemetry [attribute definition](../common/README.md#attribute). SHOULD follow OpenTelemetry [semantic conventions](https://github.com/open-telemetry/semantic-conventions) for attributes. | +| Description | map | Descriptive (non-identifying) attributes of the entity.

MAY change over the lifetime of the entity. MAY be empty. These attributes are not part of entity's identity.

Follows OpenTelemetry [attribute definition](../common/README.md#attribute). SHOULD follow OpenTelemetry [semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/README.md) for attributes. | ## Minimally Sufficient Identity diff --git a/specification/logs/api.md b/specification/logs/api.md index 977770be6fb..a0f11ce49fc 100644 --- a/specification/logs/api.md +++ b/specification/logs/api.md @@ -124,14 +124,6 @@ The API MUST accept the following parameters: - [Attributes](./data-model.md#field-attributes) (optional) - [Event Name](./data-model.md#field-eventname) (optional) -**Status**: [Development](../document-status.md) - -The API SHOULD provide functionality for users to convert -[Standard Attributes](../common/README.md#standard-attribute) -so they can be used, or directly accept them, in the log signal. -This allows the reuse of [Standard Attributes](../common/README.md#standard-attribute) -across signals. - ### Enabled To help users avoid performing computationally expensive operations when diff --git a/specification/logs/data-model.md b/specification/logs/data-model.md index 807e5899aa1..b8ba6c428e4 100644 --- a/specification/logs/data-model.md +++ b/specification/logs/data-model.md @@ -470,9 +470,6 @@ Description: Additional information about the specific event occurrence. Unlike the `Resource` field, which is fixed for a particular source, `Attributes` can vary for each occurrence of the event coming from the same source. Can contain information about the request context (other than [Trace Context Fields](#trace-context-fields)). -The log attribute model MUST support [`any` type](#type-any), -a superset of [standard Attribute](../common/README.md#attribute), -to preserve the semantics of structured attributes emitted by the applications. This field is optional. #### Errors and Exceptions diff --git a/specification/resource/data-model.md b/specification/resource/data-model.md index 60b924ddebb..6a9d579dc07 100644 --- a/specification/resource/data-model.md +++ b/specification/resource/data-model.md @@ -24,8 +24,8 @@ running in a container on Kubernetes, which is associated to a Pod running on a Node that is a VM but also is in a namespace and possibly is part of a Deployment. Resource could have attributes to denote information about the Container, the Pod, the Node, the VM or the Deployment. All of these help -identify what produced the telemetry. Note that there are certain "standard -attributes" that have prescribed meanings. +identify what produced the telemetry. Note that there are certain attributes +that have prescribed meanings. A resource is composed of 0 or more [`Entities`](../entities/README.md) and 0 or more attributes not associated with any entity. @@ -35,7 +35,7 @@ The data model below defines a logical model for an Resource (irrespective of th | Field | Type | Description | |------------|----------|-----------------| | Entities | set\ | Defines the set of Entities associated with this resource.

[Entity is defined here](../entities/data-model.md) | -| Attributes | map\ | Additional Attributes that identify the resource.

MUST not change during the lifetime of the resource.

Follows OpenTelemetry [Standard attribute definition](../common/README.md#standard-attribute). | +| Attributes | map\ | Additional Attributes that identify the resource.

MUST not change during the lifetime of the resource.

Follows OpenTelemetry [attribute definition](../common/README.md#attribute). | ## Identity diff --git a/specification/resource/sdk.md b/specification/resource/sdk.md index b7cb8cfa976..8a9a08b4cb0 100644 --- a/specification/resource/sdk.md +++ b/specification/resource/sdk.md @@ -13,7 +13,8 @@ For example, a process producing telemetry that is running in a container on Kubernetes has a Pod name, it is in a namespace and possibly is part of a Deployment which also has a name. All three of these attributes can be included in the `Resource`. Note that there are certain -["standard attributes"](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/resource/README.md) that have prescribed meanings. +[attributes](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/resource/README.md) +that have prescribed meanings. The primary purpose of resources as a first-class concept in the SDK is decoupling of discovery of resource information from exporters. This allows for From bfaf650c3c8541b24d22be4e055a9872c261e6a1 Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Tue, 26 Aug 2025 16:45:03 +0200 Subject: [PATCH 11/36] merge log attributes and standard attribute types --- specification/common/README.md | 60 +++++++++++++------- specification/logs/data-model.md | 94 ++------------------------------ 2 files changed, 46 insertions(+), 108 deletions(-) diff --git a/specification/common/README.md b/specification/common/README.md index ad4b94cacd3..74f066a4c82 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -8,7 +8,7 @@ path_base_for_github_subdir: # Common specification concepts -**Status**: [Stable](../document-status.md), except where otherwise specified +**Status**: [Stable](../document-status.md)

Table of Contents @@ -33,11 +33,28 @@ An `Attribute` is a key-value pair, which MUST have the following properties: - The attribute key MUST be a non-`null` and non-empty string. - Case sensitivity of keys is preserved. Keys that differ in casing are treated as distinct keys. -- The attribute value is either: - - A primitive type: string, boolean, double precision floating point (IEEE 754-1985) or signed 64 bit integer. - - An array of primitive type values. The array MUST be homogeneous, - i.e., it MUST NOT contain values of different types. - - **Status**: [Development](../document-status.md) - An empty value (e.g. `null`). +- The attribute value MUST be one of types defined in [Attribute Value](#attribute-value). + +Attributes are equal when their keys and values are equal. + +See [Attribute Naming](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/naming.md#attributes) for naming guidelines. + +See [Requirement Level](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/attribute-requirement-level.md) for requirement levels guidelines. + +See [this document](attribute-type-mapping.md) to find out how to map values obtained +outside OpenTelemetry into OpenTelemetry attribute values. + +### Attribute Value + +The attribute value is either: + + - a primitive type: string, boolean, double precision floating point (IEEE 754-1985), or signed 64 bit integer, + - an homogeneous array of primitive type values. An homogeneous array MUST NOT contain values of different types. + - a byte array. + - an heteregonous array of [Attribute Value](#attribute-value), + - an [Attribute Collection](#attribute-collections), + - an empty value (e.g. `null`). + For protocols that do not natively support non-string values, non-string values SHOULD be represented as JSON-encoded strings. For example, the expression `int64(100)` will be encoded as `100`, `float64(1.5)` will be encoded as `1.5`, and an empty array of any type will be encoded as `[]`. @@ -45,10 +62,10 @@ Attribute values expressing an empty value, a numerical value of zero, an empty string, or an empty array are considered meaningful and MUST be stored and passed on to processors / exporters. -`null` values SHOULD NOT be allowed in arrays. However, if it is impossible to -make sure that no `null` values are accepted +`null` values SHOULD NOT be allowed in homogeneous arrays. +However, if it is impossible to make sure that no `null` values are accepted (e.g. in languages that do not have appropriate compile-time type checking), -`null` values within arrays MUST be preserved as-is (i.e., passed on to span +`null` values within homogeneous arrays MUST be preserved as-is (i.e., passed on to span processors / exporters as `null`). If exporters do not support exporting `null` values, they MAY replace those values by 0, `false`, or empty strings. This is required for map/dictionary structures represented as two arrays with @@ -56,14 +73,8 @@ indices that are kept in sync (e.g., two attributes `header_keys` and `header_va both containing an array of strings to represent a mapping `header_keys[i] -> header_values[i]`). -Attributes are equal when their keys and values are equal. - -See [Attribute Naming](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/naming.md#attributes) for naming guidelines. - -See [Requirement Level](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/attribute-requirement-level.md) for requirement levels guidelines. - -See [this document](attribute-type-mapping.md) to find out how to map values obtained -outside OpenTelemetry into OpenTelemetry attribute values. +Arbitrary deep nesting of values for heteregonous arrays and attribute collections +is allowed (essentially allows to represent an equivalent of a JSON object). ### Attribute Limits @@ -130,9 +141,12 @@ at this time, as discussed in [Spans](../trace/api.md#set-attributes), Span [Events](../trace/api.md#add-events), Span [Links](../trace/api.md#link) and -[Log Records](../logs/data-model.md) may contain a collection of attributes. The -keys in each such collection are unique, i.e. there MUST NOT exist more than one -key-value pair with the same key. The enforcement of uniqueness may be performed +[Log Records](../logs/data-model.md), +and even [Attribute Value](#attribute-value) itself +may contain a collection of attributes. + +Implementation MUST by default ensure that the exported attribute collections +contain only unique keys. The enforcement of uniqueness may be performed in a variety of ways as it best fits the limitations of the particular implementation. @@ -155,6 +169,12 @@ that individual attribute value being exported using a streaming wire protocol. In such cases the enforcement of uniqueness will likely be the responsibility of the recipient of this data. +Implementations MAY have an option to allow exporting attribute collections +with duplicate keys (e.g. for better performance). +If such option is provided, it MUST be documented that for many receivers, +handling of maps with duplicate keys is unpredictable and it is the users' +responsibility to ensure keys are not duplicate. + Collection of attributes are equal when they contain the same attributes, irrespective of the order in which those elements appear (unordered collection equality). diff --git a/specification/logs/data-model.md b/specification/logs/data-model.md index b8ba6c428e4..67ac031b55d 100644 --- a/specification/logs/data-model.md +++ b/specification/logs/data-model.md @@ -15,10 +15,6 @@ weight: 2 - [Design Notes](#design-notes) * [Requirements](#requirements) * [Events](#events) - * [Definitions Used in this Document](#definitions-used-in-this-document) - + [Type `any`](#type-any) - + [Type `map`](#type-mapstring-any) - * [Field Kinds](#field-kinds) - [Log and Event Record Definition](#log-and-event-record-definition) * [Field: `Timestamp`](#field-timestamp) * [Field: `ObservedTimestamp`](#field-observedtimestamp) @@ -112,85 +108,6 @@ conventions defined for logs SHOULD be formatted as Events. Requirements and det Events are intended to be used by OpenTelemetry instrumentation. It is not a requirement that all LogRecords are formatted as Events. -### Definitions Used in this Document - -In this document we refer to types `any` and `map`, defined as -follows. - -#### Type `any` - -Value of type `any` can be one of the following: - -- A scalar value: string, boolean, signed 64 bit integer, or double precision floating point (IEEE 754-1985) - -- A byte array, - -- An array (a list) of `any` values, - -- A `map`, - -- [since 1.31.0] An empty value (e.g. `null`). - -#### Type `map` - -Value of type `map` is a map of string keys to `any` values. The -keys in the map are unique (duplicate keys are not allowed). - -Arbitrary deep nesting of values for arrays and maps is allowed (essentially -allows to represent an equivalent of a JSON object). - -The representation of the map is language-dependent. - -The implementation MUST by default ensure that the exported maps contain only unique keys. - -The implementation MAY have an option to allow exporting maps with duplicate keys -(e.g. for better performance). -If such option is provided, it MUST be documented that for many receivers, -handling of maps with duplicate keys is unpredictable and it is the users' -responsibility to ensure keys are not duplicate. - -### Field Kinds - -This Data Model defines a logical model for a log record (irrespective of the -physical format and encoding of the record). Each record contains 2 kinds of -fields: - -- Named top-level fields of specific type and meaning. - -- Fields stored as `map`, which can contain arbitrary values of - different types. The keys and values for well-known fields follow semantic - conventions for key names and possible values that allow all parties that work - with the field to have the same interpretation of the data. See references to - semantic conventions for `Resource` and `Attributes` fields and examples in - [Appendix A](./data-model-appendix.md#appendix-a-example-mappings). - -The reasons for having these 2 kinds of fields are: - -- Ability to efficiently represent named top-level fields, which are almost - always present (e.g. when using encodings like Protocol Buffers where fields - are enumerated but not named on the wire). - -- Ability to enforce types of named fields, which is very useful for compiled - languages with type checks. - -- Flexibility to represent less frequent data as `map`. This - includes well-known data that has standardized semantics as well as arbitrary - custom data that the application may want to include in the logs. - -When designing this data model we followed the following reasoning to make a -decision about when to use a top-level named field: - -- The field needs to be either mandatory for all records or be frequently - present in well-known log and event formats (such as `Timestamp`) or is - expected to be often present in log records in upcoming logging systems (such - as `TraceId`). - -- The field’s semantics must be the same for all known log and event formats and - can be mapped directly and unambiguously to this data model. - -Both of the above conditions were required to give the field a place in the -top-level structure of the record. - ## Log and Event Record Definition [Appendix A](./data-model-appendix.md#appendix-a-example-mappings) contains many examples that show how @@ -430,14 +347,15 @@ when it is used to represent an unspecified severity. ### Field: `Body` -Type: [`any`](#type-any). +Type: [Attribute Value](../common/README.md#attribute-value). Description: A value containing the body of the log record. Can be for example a human-readable string message (including multi-line) describing the event in a free form or it can be a structured data composed of arrays and maps of other -values. Body MUST support [`any` type](#type-any) to preserve the semantics of -structured logs emitted by the applications. Can vary for each occurrence of the -event coming from the same source. This field is optional. +values. Body MUST support [Attribute Value](../common/README.md#attribute-value) +types to preserve the semantics of structured logs emitted by the applications. +Can vary for each occurrence of the event coming from the same source. +This field is optional. ### Field: `Resource` @@ -464,7 +382,7 @@ they all have the same value of `InstrumentationScope`. This field is optional. ### Field: `Attributes` -Type: [`map`](#type-mapstring-any). +Type: [Attribute Collection](../common/README.md#attribute-collections). Description: Additional information about the specific event occurrence. Unlike the `Resource` field, which is fixed for a particular source, `Attributes` can From c17aec624a0c00f64b3e5347a44c1b30a6e59024 Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Tue, 26 Aug 2025 16:50:21 +0200 Subject: [PATCH 12/36] rename "Attribute Value" to "AnyValue" --- specification/common/README.md | 13 +++++++------ specification/logs/data-model.md | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/specification/common/README.md b/specification/common/README.md index 74f066a4c82..14bfa164581 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -16,6 +16,7 @@ path_base_for_github_subdir: - [Attribute](#attribute) + * [AnyValue](#anyvalue) * [Attribute Limits](#attribute-limits) + [Configurable Parameters](#configurable-parameters) + [Exempt Entities](#exempt-entities) @@ -33,7 +34,7 @@ An `Attribute` is a key-value pair, which MUST have the following properties: - The attribute key MUST be a non-`null` and non-empty string. - Case sensitivity of keys is preserved. Keys that differ in casing are treated as distinct keys. -- The attribute value MUST be one of types defined in [Attribute Value](#attribute-value). +- The attribute value MUST be one of types defined in [AnyValue](#anyvalue). Attributes are equal when their keys and values are equal. @@ -44,21 +45,21 @@ See [Requirement Level](https://github.com/open-telemetry/semantic-conventions/b See [this document](attribute-type-mapping.md) to find out how to map values obtained outside OpenTelemetry into OpenTelemetry attribute values. -### Attribute Value +### AnyValue -The attribute value is either: +`AnyValue` is either: - a primitive type: string, boolean, double precision floating point (IEEE 754-1985), or signed 64 bit integer, - an homogeneous array of primitive type values. An homogeneous array MUST NOT contain values of different types. - a byte array. - - an heteregonous array of [Attribute Value](#attribute-value), + - an heteregonous array of [AnyValue](#anyvalue), - an [Attribute Collection](#attribute-collections), - an empty value (e.g. `null`). For protocols that do not natively support non-string values, non-string values SHOULD be represented as JSON-encoded strings. For example, the expression `int64(100)` will be encoded as `100`, `float64(1.5)` will be encoded as `1.5`, and an empty array of any type will be encoded as `[]`. -Attribute values expressing an empty value, a numerical value of zero, +`AnyValue` expressing an empty value, a numerical value of zero, an empty string, or an empty array are considered meaningful and MUST be stored and passed on to processors / exporters. @@ -142,7 +143,7 @@ at this time, as discussed in [Events](../trace/api.md#add-events), Span [Links](../trace/api.md#link) and [Log Records](../logs/data-model.md), -and even [Attribute Value](#attribute-value) itself +and even [AnyValue](#anyvalue) may contain a collection of attributes. Implementation MUST by default ensure that the exported attribute collections diff --git a/specification/logs/data-model.md b/specification/logs/data-model.md index 67ac031b55d..3faf5f9224f 100644 --- a/specification/logs/data-model.md +++ b/specification/logs/data-model.md @@ -347,7 +347,7 @@ when it is used to represent an unspecified severity. ### Field: `Body` -Type: [Attribute Value](../common/README.md#attribute-value). +Type: [AnyValue](../common/README.md#anyvalue). Description: A value containing the body of the log record. Can be for example a human-readable string message (including multi-line) describing the event in From 95b049ba1c24f6327d9e5641429790cfb9d31a90 Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Tue, 26 Aug 2025 16:54:32 +0200 Subject: [PATCH 13/36] mdlint --- specification/common/README.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/specification/common/README.md b/specification/common/README.md index 14bfa164581..fa1d5e7b0dd 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -49,13 +49,12 @@ outside OpenTelemetry into OpenTelemetry attribute values. `AnyValue` is either: - - a primitive type: string, boolean, double precision floating point (IEEE 754-1985), or signed 64 bit integer, - - an homogeneous array of primitive type values. An homogeneous array MUST NOT contain values of different types. - - a byte array. - - an heteregonous array of [AnyValue](#anyvalue), - - an [Attribute Collection](#attribute-collections), - - an empty value (e.g. `null`). - +- a primitive type: string, boolean, double precision floating point (IEEE 754-1985), or signed 64 bit integer, +- an homogeneous array of primitive type values. An homogeneous array MUST NOT contain values of different types. +- a byte array. +- an heteregonous array of [AnyValue](#anyvalue), +- an [Attribute Collection](#attribute-collections), +- an empty value (e.g. `null`). For protocols that do not natively support non-string values, non-string values SHOULD be represented as JSON-encoded strings. For example, the expression `int64(100)` will be encoded as `100`, `float64(1.5)` will be encoded as `1.5`, and an empty array of any type will be encoded as `[]`. From b98d714abf2f695859a21eb8e423c238907639ce Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Tue, 26 Aug 2025 16:56:38 +0200 Subject: [PATCH 14/36] fix links --- oteps/entities/0256-entities-data-model.md | 4 ++-- specification/logs/data-model.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/oteps/entities/0256-entities-data-model.md b/oteps/entities/0256-entities-data-model.md index 51d5a00faae..70d0fde0b5f 100644 --- a/oteps/entities/0256-entities-data-model.md +++ b/oteps/entities/0256-entities-data-model.md @@ -139,7 +139,7 @@ MAY change over the lifetime of the entity. MAY be empty. These attributes are not part of entity's identity.

Follows any +href="https://github.com/open-telemetry/opentelemetry-specification/blob/v1.44.0/specification/logs/data-model.md#type-any">any value definition in the OpenTelemetry spec - it can be a scalar value, byte array, an array or map of values. Arbitrary deep nesting of values for arrays and maps is allowed. @@ -682,7 +682,7 @@ There are a couple of reasons: ### Attribute Data Type The data model requires the Attributes field to use the extended -[any](../../specification/logs/data-model.md#type-any) +[any](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.44.0/specification/logs/data-model.md#type-any) attribute values, that allows more complex data types. This is different from the data type used by the Id field, which is more restricted in the shape. diff --git a/specification/logs/data-model.md b/specification/logs/data-model.md index 3faf5f9224f..ea95cb3d6e5 100644 --- a/specification/logs/data-model.md +++ b/specification/logs/data-model.md @@ -352,8 +352,8 @@ Type: [AnyValue](../common/README.md#anyvalue). Description: A value containing the body of the log record. Can be for example a human-readable string message (including multi-line) describing the event in a free form or it can be a structured data composed of arrays and maps of other -values. Body MUST support [Attribute Value](../common/README.md#attribute-value) -types to preserve the semantics of structured logs emitted by the applications. +values. Body MUST support [AnyValue](../common/README.md#anyvalue) to preserve +the semantics of structured logs emitted by the applications. Can vary for each occurrence of the event coming from the same source. This field is optional. From e55416d5e74a9ba71b562482de5e87b6f3cd9a2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Paj=C4=85k?= Date: Tue, 26 Aug 2025 18:15:10 +0200 Subject: [PATCH 15/36] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- specification/common/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/specification/common/README.md b/specification/common/README.md index fa1d5e7b0dd..f7bd073e56e 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -50,9 +50,9 @@ outside OpenTelemetry into OpenTelemetry attribute values. `AnyValue` is either: - a primitive type: string, boolean, double precision floating point (IEEE 754-1985), or signed 64 bit integer, -- an homogeneous array of primitive type values. An homogeneous array MUST NOT contain values of different types. +- a homogeneous array of primitive type values. A homogeneous array MUST NOT contain values of different types. - a byte array. -- an heteregonous array of [AnyValue](#anyvalue), +- a heterogeneous array of [AnyValue](#anyvalue), - an [Attribute Collection](#attribute-collections), - an empty value (e.g. `null`). @@ -73,7 +73,7 @@ indices that are kept in sync (e.g., two attributes `header_keys` and `header_va both containing an array of strings to represent a mapping `header_keys[i] -> header_values[i]`). -Arbitrary deep nesting of values for heteregonous arrays and attribute collections +Arbitrary deep nesting of values for heterogeneous arrays and attribute collections is allowed (essentially allows to represent an equivalent of a JSON object). ### Attribute Limits From 49b41b4f37086e37f4c1073ac8d50ea896fa7ac5 Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Tue, 26 Aug 2025 19:42:07 +0200 Subject: [PATCH 16/36] Revert "rename "Attribute Value" to "AnyValue"" This reverts commit c17aec624a0c00f64b3e5347a44c1b30a6e59024. --- specification/common/README.md | 13 ++++++------- specification/logs/data-model.md | 6 +++--- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/specification/common/README.md b/specification/common/README.md index f7bd073e56e..7143a9203be 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -16,7 +16,6 @@ path_base_for_github_subdir: - [Attribute](#attribute) - * [AnyValue](#anyvalue) * [Attribute Limits](#attribute-limits) + [Configurable Parameters](#configurable-parameters) + [Exempt Entities](#exempt-entities) @@ -34,7 +33,7 @@ An `Attribute` is a key-value pair, which MUST have the following properties: - The attribute key MUST be a non-`null` and non-empty string. - Case sensitivity of keys is preserved. Keys that differ in casing are treated as distinct keys. -- The attribute value MUST be one of types defined in [AnyValue](#anyvalue). +- The attribute value MUST be one of types defined in [Attribute Value](#attribute-value). Attributes are equal when their keys and values are equal. @@ -45,20 +44,20 @@ See [Requirement Level](https://github.com/open-telemetry/semantic-conventions/b See [this document](attribute-type-mapping.md) to find out how to map values obtained outside OpenTelemetry into OpenTelemetry attribute values. -### AnyValue +### Attribute Value -`AnyValue` is either: +The attribute value is either: - a primitive type: string, boolean, double precision floating point (IEEE 754-1985), or signed 64 bit integer, - a homogeneous array of primitive type values. A homogeneous array MUST NOT contain values of different types. - a byte array. -- a heterogeneous array of [AnyValue](#anyvalue), +- a heterogeneous array of [Attribute Values](#attribute-value), - an [Attribute Collection](#attribute-collections), - an empty value (e.g. `null`). For protocols that do not natively support non-string values, non-string values SHOULD be represented as JSON-encoded strings. For example, the expression `int64(100)` will be encoded as `100`, `float64(1.5)` will be encoded as `1.5`, and an empty array of any type will be encoded as `[]`. -`AnyValue` expressing an empty value, a numerical value of zero, +Attribute values expressing an empty value, a numerical value of zero, an empty string, or an empty array are considered meaningful and MUST be stored and passed on to processors / exporters. @@ -142,7 +141,7 @@ at this time, as discussed in [Events](../trace/api.md#add-events), Span [Links](../trace/api.md#link) and [Log Records](../logs/data-model.md), -and even [AnyValue](#anyvalue) +and even [Attribute Value](#attribute-value) itself may contain a collection of attributes. Implementation MUST by default ensure that the exported attribute collections diff --git a/specification/logs/data-model.md b/specification/logs/data-model.md index ea95cb3d6e5..5ba29aec4e6 100644 --- a/specification/logs/data-model.md +++ b/specification/logs/data-model.md @@ -347,13 +347,13 @@ when it is used to represent an unspecified severity. ### Field: `Body` -Type: [AnyValue](../common/README.md#anyvalue). +Type: [Attribute Value](../common/README.md#attribute-value). Description: A value containing the body of the log record. Can be for example a human-readable string message (including multi-line) describing the event in a free form or it can be a structured data composed of arrays and maps of other -values. Body MUST support [AnyValue](../common/README.md#anyvalue) to preserve -the semantics of structured logs emitted by the applications. +values. Body MUST support [Attribute Value](../common/README.md#attribute-value) +to preserve the semantics of structured logs emitted by the applications. Can vary for each occurrence of the event coming from the same source. This field is optional. From db81d62d2c36d6eadc51e960c436404fde582c30 Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Tue, 26 Aug 2025 19:43:50 +0200 Subject: [PATCH 17/36] toc --- specification/common/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/specification/common/README.md b/specification/common/README.md index 7143a9203be..9a88d8b464f 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -16,6 +16,7 @@ path_base_for_github_subdir: - [Attribute](#attribute) + * [Attribute Value](#attribute-value) * [Attribute Limits](#attribute-limits) + [Configurable Parameters](#configurable-parameters) + [Exempt Entities](#exempt-entities) From ad107698d73b2556cfbd01235d972241efee367e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Paj=C4=85k?= Date: Tue, 26 Aug 2025 19:45:23 +0200 Subject: [PATCH 18/36] Update specification/common/README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- specification/common/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/README.md b/specification/common/README.md index 9a88d8b464f..a41a5cf6984 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -54,7 +54,7 @@ The attribute value is either: - a byte array. - a heterogeneous array of [Attribute Values](#attribute-value), - an [Attribute Collection](#attribute-collections), -- an empty value (e.g. `null`). +- an empty value (e.g. `null`, `undefined` in JavaScript/TypeScript, `None` in Python, `nil` in Go/Ruby, etc.). For protocols that do not natively support non-string values, non-string values SHOULD be represented as JSON-encoded strings. For example, the expression `int64(100)` will be encoded as `100`, `float64(1.5)` will be encoded as `1.5`, and an empty array of any type will be encoded as `[]`. From cc41e2f727b71b22b2b938aaa027d2a7e869e357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Paj=C4=85k?= Date: Tue, 26 Aug 2025 19:45:40 +0200 Subject: [PATCH 19/36] Update specification/common/README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- specification/common/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/README.md b/specification/common/README.md index a41a5cf6984..36f256fdc46 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -62,7 +62,7 @@ Attribute values expressing an empty value, a numerical value of zero, an empty string, or an empty array are considered meaningful and MUST be stored and passed on to processors / exporters. -`null` values SHOULD NOT be allowed in homogeneous arrays. +While `null` is a valid attribute value, its use within homogeneous arrays SHOULD generally be avoided unless language constraints make this impossible. However, if it is impossible to make sure that no `null` values are accepted (e.g. in languages that do not have appropriate compile-time type checking), `null` values within homogeneous arrays MUST be preserved as-is (i.e., passed on to span From 8b029c8cd913713fad95103dc38c91e78abb2b27 Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Thu, 28 Aug 2025 10:40:03 +0200 Subject: [PATCH 20/36] propose Attribute Limits changes --- specification/common/README.md | 132 ++++++++++++++++++--------------- 1 file changed, 71 insertions(+), 61 deletions(-) diff --git a/specification/common/README.md b/specification/common/README.md index 36f256fdc46..e9e418e2507 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -17,10 +17,10 @@ path_base_for_github_subdir: - [Attribute](#attribute) * [Attribute Value](#attribute-value) - * [Attribute Limits](#attribute-limits) - + [Configurable Parameters](#configurable-parameters) - + [Exempt Entities](#exempt-entities) -- [Attribute Collections](#attribute-collections) + * [Attribute Collections](#attribute-collections) +- [Attribute Limits](#attribute-limits) + * [Configurable Parameters](#configurable-parameters) + * [Exempt Entities](#exempt-entities) @@ -49,14 +49,19 @@ outside OpenTelemetry into OpenTelemetry attribute values. The attribute value is either: -- a primitive type: string, boolean, double precision floating point (IEEE 754-1985), or signed 64 bit integer, -- a homogeneous array of primitive type values. A homogeneous array MUST NOT contain values of different types. +- a primitive type: string, boolean, double precision floating point + (IEEE 754-1985), or signed 64 bit integer, +- a homogeneous array of primitive type values. A homogeneous array MUST NOT + contain values of different types. - a byte array. - a heterogeneous array of [Attribute Values](#attribute-value), - an [Attribute Collection](#attribute-collections), - an empty value (e.g. `null`, `undefined` in JavaScript/TypeScript, `None` in Python, `nil` in Go/Ruby, etc.). -For protocols that do not natively support non-string values, non-string values SHOULD be represented as JSON-encoded strings. For example, the expression `int64(100)` will be encoded as `100`, `float64(1.5)` will be encoded as `1.5`, and an empty array of any type will be encoded as `[]`. +For protocols that do not natively support non-string values, non-string values +SHOULD be represented as JSON-encoded strings. For example, the expression +`int64(100)` will be encoded as `100`, `float64(1.5)` will be encoded as `1.5`, +and an empty array of any type will be encoded as `[]`. Attribute values expressing an empty value, a numerical value of zero, an empty string, or an empty array are considered meaningful and MUST be stored @@ -76,7 +81,53 @@ both containing an array of strings to represent a mapping Arbitrary deep nesting of values for heterogeneous arrays and attribute collections is allowed (essentially allows to represent an equivalent of a JSON object). -### Attribute Limits +### Attribute Collections + +[Resources](../resource/sdk.md), +[Instrumentation Scopes](instrumentation-scope.md), +[Metric points](../metrics/data-model.md#metric-points), +[Spans](../trace/api.md#set-attributes), Span +[Events](../trace/api.md#add-events), Span +[Links](../trace/api.md#link) and +[Log Records](../logs/data-model.md), +and even [Attribute Value](#attribute-value) itself +may contain a collection of attributes. + +Implementation MUST by default ensure that the exported attribute collections +contain only unique keys. The enforcement of uniqueness may be performed +in a variety of ways as it best fits the limitations of the particular +implementation. + +Normally for the telemetry generated using OpenTelemetry SDKs the attribute +key-value pairs are set via an API that either accepts a single key-value pair +or a collection of key-value pairs. Setting an attribute with the same key as an +existing attribute SHOULD overwrite the existing attribute's value. See for +example Span's [SetAttribute](../trace/api.md#set-attributes) API. + +A typical implementation of [SetAttribute](../trace/api.md#set-attributes) API +will enforce the uniqueness by overwriting any existing attribute values pending +to be exported, so that when the Span is eventually exported the exporters see +only unique attributes. The OTLP format in particular requires that exported +Resources, Spans, Metric data points and Log Records contain only unique +attributes. + +Some other implementations may use a streaming approach where every +[SetAttribute](../trace/api.md#set-attributes) API call immediately results in +that individual attribute value being exported using a streaming wire protocol. +In such cases the enforcement of uniqueness will likely be the responsibility of +the recipient of this data. + +Implementations MAY have an option to allow exporting attribute collections +with duplicate keys (e.g. for better performance). +If such option is provided, it MUST be documented that for many receivers, +handling of maps with duplicate keys is unpredictable and it is the users' +responsibility to ensure keys are not duplicate. + +Collection of attributes are equal when they contain the same attributes, +irrespective of the order in which those elements appear +(unordered collection equality). + +## Attribute Limits Execution of erroneous code can result in unintended attributes. If there are no limits placed on attributes, they can quickly exhaust available memory, resulting @@ -90,14 +141,18 @@ If an SDK provides a way to: - set an attribute value length limit such that for each attribute value: - if it is a string, if it exceeds that limit (counting any character in it as - 1), SDKs MUST truncate that value, so that its length is at most equal + 1), SDK MUST truncate that value, so that its length is at most equal to the limit, - - if it is an array of strings, then apply the above rule to each of the - values separately, + - if it is an array or attributes collection, then apply the above rule to + each of its string values separately, - otherwise a value MUST NOT be truncated; -- set a limit of unique attribute keys such that: - - for each unique attribute key, addition of which would result in exceeding - the limit, SDK MUST discard that key/value pair. +- set an attribute count limit such that: + - if an attribute addition into an attribute collection would result + in exceeding the limit (counting any attribute in it as 1 and nested + collections do contribute to the count of their parent), + SDK MUST discard that attribute, so that the total number of attributes in + an attribute collection is at most equal to the limit; + - otherwise an attribute MUST NOT be discarded. There MAY be a log emitted to indicate to the user that an attribute was truncated or discarded. To prevent excessive logging, the log MUST NOT be @@ -114,12 +169,12 @@ use the model-specific limit, if it isn't set, then the SDK MUST attempt to use the general limit. If neither are defined, then the SDK MUST try to use the model-specific limit default value, followed by the global limit default value. -#### Configurable Parameters +### Configurable Parameters * `AttributeCountLimit` (Default=128) - Maximum allowed attribute count per record; * `AttributeValueLengthLimit` (Default=Infinity) - Maximum allowed attribute value length; -#### Exempt Entities +### Exempt Entities Resource attributes SHOULD be exempt from the limits described above as resources are not susceptible to the scenarios (auto-instrumentation) that result in @@ -133,48 +188,3 @@ Attributes, which belong to Metrics, are exempt from the limits described above at this time, as discussed in [Metrics Attribute Limits](../metrics/sdk.md#attribute-limits). -## Attribute Collections - -[Resources](../resource/sdk.md), -[Instrumentation Scopes](instrumentation-scope.md), -[Metric points](../metrics/data-model.md#metric-points), -[Spans](../trace/api.md#set-attributes), Span -[Events](../trace/api.md#add-events), Span -[Links](../trace/api.md#link) and -[Log Records](../logs/data-model.md), -and even [Attribute Value](#attribute-value) itself -may contain a collection of attributes. - -Implementation MUST by default ensure that the exported attribute collections -contain only unique keys. The enforcement of uniqueness may be performed -in a variety of ways as it best fits the limitations of the particular -implementation. - -Normally for the telemetry generated using OpenTelemetry SDKs the attribute -key-value pairs are set via an API that either accepts a single key-value pair -or a collection of key-value pairs. Setting an attribute with the same key as an -existing attribute SHOULD overwrite the existing attribute's value. See for -example Span's [SetAttribute](../trace/api.md#set-attributes) API. - -A typical implementation of [SetAttribute](../trace/api.md#set-attributes) API -will enforce the uniqueness by overwriting any existing attribute values pending -to be exported, so that when the Span is eventually exported the exporters see -only unique attributes. The OTLP format in particular requires that exported -Resources, Spans, Metric data points and Log Records contain only unique -attributes. - -Some other implementations may use a streaming approach where every -[SetAttribute](../trace/api.md#set-attributes) API call immediately results in -that individual attribute value being exported using a streaming wire protocol. -In such cases the enforcement of uniqueness will likely be the responsibility of -the recipient of this data. - -Implementations MAY have an option to allow exporting attribute collections -with duplicate keys (e.g. for better performance). -If such option is provided, it MUST be documented that for many receivers, -handling of maps with duplicate keys is unpredictable and it is the users' -responsibility to ensure keys are not duplicate. - -Collection of attributes are equal when they contain the same attributes, -irrespective of the order in which those elements appear -(unordered collection equality). From a5851af0c21d67384b077b4d79062e1a5f069876 Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Thu, 28 Aug 2025 10:41:24 +0200 Subject: [PATCH 21/36] format --- specification/common/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/specification/common/README.md b/specification/common/README.md index e9e418e2507..b8d937c3e4c 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -56,7 +56,8 @@ The attribute value is either: - a byte array. - a heterogeneous array of [Attribute Values](#attribute-value), - an [Attribute Collection](#attribute-collections), -- an empty value (e.g. `null`, `undefined` in JavaScript/TypeScript, `None` in Python, `nil` in Go/Ruby, etc.). +- an empty value (e.g. `null`, `undefined` in JavaScript/TypeScript, + `None` in Python, `nil` in Go/Ruby, etc.). For protocols that do not natively support non-string values, non-string values SHOULD be represented as JSON-encoded strings. For example, the expression @@ -67,7 +68,8 @@ Attribute values expressing an empty value, a numerical value of zero, an empty string, or an empty array are considered meaningful and MUST be stored and passed on to processors / exporters. -While `null` is a valid attribute value, its use within homogeneous arrays SHOULD generally be avoided unless language constraints make this impossible. +While `null` is a valid attribute value, its use within homogeneous arrays +SHOULD generally be avoided unless language constraints make this impossible. However, if it is impossible to make sure that no `null` values are accepted (e.g. in languages that do not have appropriate compile-time type checking), `null` values within homogeneous arrays MUST be preserved as-is (i.e., passed on to span From 52ccb34e4689f9d222ebd8af8dd22589a956465c Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Thu, 28 Aug 2025 11:01:36 +0200 Subject: [PATCH 22/36] remove EOL --- specification/common/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/specification/common/README.md b/specification/common/README.md index b8d937c3e4c..e5474027fdc 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -189,4 +189,3 @@ attribute limits for Resources. Attributes, which belong to Metrics, are exempt from the limits described above at this time, as discussed in [Metrics Attribute Limits](../metrics/sdk.md#attribute-limits). - From ecebf40fc8f79180f3db89d6fbfb78d868250afa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Paj=C4=85k?= Date: Thu, 28 Aug 2025 11:20:41 +0200 Subject: [PATCH 23/36] Update specification/common/README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- specification/common/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/README.md b/specification/common/README.md index e5474027fdc..b6ebaf25120 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -145,7 +145,7 @@ If an SDK provides a way to: - if it is a string, if it exceeds that limit (counting any character in it as 1), SDK MUST truncate that value, so that its length is at most equal to the limit, - - if it is an array or attributes collection, then apply the above rule to + - if it is an array or an attributes collection, then apply the above rule to each of its string values separately, - otherwise a value MUST NOT be truncated; - set an attribute count limit such that: From abfd0634885e99d82e07f53375c40496a85cb5a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Paj=C4=85k?= Date: Thu, 28 Aug 2025 11:20:48 +0200 Subject: [PATCH 24/36] Update specification/common/README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- specification/common/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/README.md b/specification/common/README.md index b6ebaf25120..8f3fa4a298a 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -143,7 +143,7 @@ If an SDK provides a way to: - set an attribute value length limit such that for each attribute value: - if it is a string, if it exceeds that limit (counting any character in it as - 1), SDK MUST truncate that value, so that its length is at most equal + 1), SDKs MUST truncate that value, so that its length is at most equal to the limit, - if it is an array or an attributes collection, then apply the above rule to each of its string values separately, From cbe15f58170a33825fcad9dc126ea773cd23a5a5 Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Thu, 28 Aug 2025 11:22:22 +0200 Subject: [PATCH 25/36] Apply code review suggestion --- specification/common/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/README.md b/specification/common/README.md index 8f3fa4a298a..c939c74049d 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -72,7 +72,7 @@ While `null` is a valid attribute value, its use within homogeneous arrays SHOULD generally be avoided unless language constraints make this impossible. However, if it is impossible to make sure that no `null` values are accepted (e.g. in languages that do not have appropriate compile-time type checking), -`null` values within homogeneous arrays MUST be preserved as-is (i.e., passed on to span +`null` values within homogeneous arrays MUST be preserved as-is (i.e., passed on to processors / exporters as `null`). If exporters do not support exporting `null` values, they MAY replace those values by 0, `false`, or empty strings. This is required for map/dictionary structures represented as two arrays with From 7a3c387fbbcc3c7d68467a61324611f66446331b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Paj=C4=85k?= Date: Thu, 28 Aug 2025 11:39:46 +0200 Subject: [PATCH 26/36] Update specification/common/README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- specification/common/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/specification/common/README.md b/specification/common/README.md index c939c74049d..e1953aa0152 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -150,8 +150,7 @@ If an SDK provides a way to: - otherwise a value MUST NOT be truncated; - set an attribute count limit such that: - if an attribute addition into an attribute collection would result - in exceeding the limit (counting any attribute in it as 1 and nested - collections do contribute to the count of their parent), + in exceeding the limit (counting each attribute in the collection as 1; if an attribute is itself a collection, each key-value pair within the nested collection is also counted as a separate attribute of the parent), SDK MUST discard that attribute, so that the total number of attributes in an attribute collection is at most equal to the limit; - otherwise an attribute MUST NOT be discarded. From f2a508be995b057f94868b81f1eaa30d889332ee Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Thu, 28 Aug 2025 11:42:21 +0200 Subject: [PATCH 27/36] format --- specification/common/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/specification/common/README.md b/specification/common/README.md index e1953aa0152..923e362918b 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -150,7 +150,9 @@ If an SDK provides a way to: - otherwise a value MUST NOT be truncated; - set an attribute count limit such that: - if an attribute addition into an attribute collection would result - in exceeding the limit (counting each attribute in the collection as 1; if an attribute is itself a collection, each key-value pair within the nested collection is also counted as a separate attribute of the parent), + in exceeding the limit (counting each attribute in the collection as 1; + if an attribute is itself a collection, each key-value pair within + the nested collection is also counted as a separate attribute of the parent), SDK MUST discard that attribute, so that the total number of attributes in an attribute collection is at most equal to the limit; - otherwise an attribute MUST NOT be discarded. From ee4d8ba583465511f23cfc6f67d93f423d0f12a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Paj=C4=85k?= Date: Thu, 28 Aug 2025 11:43:30 +0200 Subject: [PATCH 28/36] Update specification/common/README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- specification/common/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/README.md b/specification/common/README.md index 923e362918b..4678fc9f124 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -145,7 +145,7 @@ If an SDK provides a way to: - if it is a string, if it exceeds that limit (counting any character in it as 1), SDKs MUST truncate that value, so that its length is at most equal to the limit, - - if it is an array or an attributes collection, then apply the above rule to + - if it is an array or an attribute collection, then apply the above rule to each of its string values separately, - otherwise a value MUST NOT be truncated; - set an attribute count limit such that: From 10400ef53285cf11ad86c25b16ddd7b076e4a58b Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Thu, 28 Aug 2025 12:16:46 +0200 Subject: [PATCH 29/36] add attribute count example --- specification/common/README.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/specification/common/README.md b/specification/common/README.md index 4678fc9f124..118cc32aa18 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -151,12 +151,25 @@ If an SDK provides a way to: - set an attribute count limit such that: - if an attribute addition into an attribute collection would result in exceeding the limit (counting each attribute in the collection as 1; - if an attribute is itself a collection, each key-value pair within - the nested collection is also counted as a separate attribute of the parent), + if an attribute is itself a collection, each attribute within the nested + collection is also counted as a separate attribute of the parent), SDK MUST discard that attribute, so that the total number of attributes in an attribute collection is at most equal to the limit; - otherwise an attribute MUST NOT be discarded. +**Attribute count example:** +Consider an attribute collection with two attributes: + +- `a: 1` +- `b: { x: "foo", y: "bar", z: "baz" }` + +Here, `a` is a primitive attribute, and `b` is itself a collection with 3 attributes. +The total attribute count is calculated as follows: +- `a` counts as 1 +- Each attribute in `b` (`x`, `y`, `z`) counts as 1 each (total 3) +- `b` itself counts as 1 (the parent attribute) +- **Total attribute count = 1 (a) + 1 (b) + 3 (x, y, z) = 5**; + There MAY be a log emitted to indicate to the user that an attribute was truncated or discarded. To prevent excessive logging, the log MUST NOT be emitted more than once per record on which an attribute is set. From f8236e7674c3a85de1baea70d8fd57dfdf8f736c Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Thu, 28 Aug 2025 12:21:19 +0200 Subject: [PATCH 30/36] format --- specification/common/README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/specification/common/README.md b/specification/common/README.md index 118cc32aa18..0d93b2dc1be 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -165,10 +165,12 @@ Consider an attribute collection with two attributes: Here, `a` is a primitive attribute, and `b` is itself a collection with 3 attributes. The total attribute count is calculated as follows: -- `a` counts as 1 -- Each attribute in `b` (`x`, `y`, `z`) counts as 1 each (total 3) -- `b` itself counts as 1 (the parent attribute) -- **Total attribute count = 1 (a) + 1 (b) + 3 (x, y, z) = 5**; + +- `a` counts as 1, +- each attribute in `b` (`x`, `y`, `z`) counts as 1 each (total 3), +- `b` itself counts as 1 (the parent attribute). + +Total attribute count = 1 (`a`) + 1 (`b`) + 3 (`x`, `y`, `z`) = 5 There MAY be a log emitted to indicate to the user that an attribute was truncated or discarded. To prevent excessive logging, the log MUST NOT be From 5b46a71a85205d267ab69e690adc9fd21493130f Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Wed, 3 Sep 2025 09:33:27 +0200 Subject: [PATCH 31/36] add AnyValue and map --- specification/common/README.md | 77 +++++++++++++++++++------------- specification/logs/data-model.md | 4 +- 2 files changed, 48 insertions(+), 33 deletions(-) diff --git a/specification/common/README.md b/specification/common/README.md index 0d93b2dc1be..1a8e5d7ecfb 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -15,8 +15,9 @@ path_base_for_github_subdir: +- [AnyValue](#anyvalue) +- [map](#mapstring-anyvalue) - [Attribute](#attribute) - * [Attribute Value](#attribute-value) * [Attribute Collections](#attribute-collections) - [Attribute Limits](#attribute-limits) * [Configurable Parameters](#configurable-parameters) @@ -26,36 +27,17 @@ path_base_for_github_subdir:

-## Attribute - - - -An `Attribute` is a key-value pair, which MUST have the following properties: - -- The attribute key MUST be a non-`null` and non-empty string. - - Case sensitivity of keys is preserved. Keys that differ in casing are treated as distinct keys. -- The attribute value MUST be one of types defined in [Attribute Value](#attribute-value). - -Attributes are equal when their keys and values are equal. - -See [Attribute Naming](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/naming.md#attributes) for naming guidelines. - -See [Requirement Level](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/attribute-requirement-level.md) for requirement levels guidelines. - -See [this document](attribute-type-mapping.md) to find out how to map values obtained -outside OpenTelemetry into OpenTelemetry attribute values. +## AnyValue -### Attribute Value - -The attribute value is either: +`AnyValue` is either: - a primitive type: string, boolean, double precision floating point (IEEE 754-1985), or signed 64 bit integer, - a homogeneous array of primitive type values. A homogeneous array MUST NOT contain values of different types. - a byte array. -- a heterogeneous array of [Attribute Values](#attribute-value), -- an [Attribute Collection](#attribute-collections), +- a heterogeneous array of `AnyValue`, +- a [`map`](#mapstring-anyvalue), - an empty value (e.g. `null`, `undefined` in JavaScript/TypeScript, `None` in Python, `nil` in Go/Ruby, etc.). @@ -64,9 +46,9 @@ SHOULD be represented as JSON-encoded strings. For example, the expression `int64(100)` will be encoded as `100`, `float64(1.5)` will be encoded as `1.5`, and an empty array of any type will be encoded as `[]`. -Attribute values expressing an empty value, a numerical value of zero, -an empty string, or an empty array are considered meaningful and MUST be stored -and passed on to processors / exporters. +AnyValues expressing an empty value, a numerical value of zero, an empty string, +or an empty array are considered meaningful and MUST be stored and passed on to +processors / exporters. While `null` is a valid attribute value, its use within homogeneous arrays SHOULD generally be avoided unless language constraints make this impossible. @@ -80,8 +62,42 @@ indices that are kept in sync (e.g., two attributes `header_keys` and `header_va both containing an array of strings to represent a mapping `header_keys[i] -> header_values[i]`). -Arbitrary deep nesting of values for heterogeneous arrays and attribute collections -is allowed (essentially allows to represent an equivalent of a JSON object). +## map + +`map` is a map of string keys to `AnyValue` values. +The keys in the map are unique (duplicate keys are not allowed). + +Arbitrary deep nesting of values for arrays and maps is allowed (essentially +allows to represent an equivalent of a JSON object). + +The representation of the map is language-dependent. + +The implementation MUST by default ensure that the exported maps contain only unique keys. + +The implementation MAY have an option to allow exporting maps with duplicate keys +(e.g. for better performance). +If such option is provided, it MUST be documented that for many receivers, +handling of maps with duplicate keys is unpredictable and it is the users' +responsibility to ensure keys are not duplicate. + +## Attribute + + + +An `Attribute` is a key-value pair, which MUST have the following properties: + +- The attribute key MUST be a non-`null` and non-empty string. + - Case sensitivity of keys is preserved. Keys that differ in casing are treated as distinct keys. +- The attribute value MUST be one of types defined in [AnyValue](#anyvalue). + +Attributes are equal when their keys and values are equal. + +See [Attribute Naming](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/naming.md#attributes) for naming guidelines. + +See [Requirement Level](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/attribute-requirement-level.md) for requirement levels guidelines. + +See [this document](attribute-type-mapping.md) to find out how to map values obtained +outside OpenTelemetry into OpenTelemetry attribute values. ### Attribute Collections @@ -92,8 +108,7 @@ is allowed (essentially allows to represent an equivalent of a JSON object). [Events](../trace/api.md#add-events), Span [Links](../trace/api.md#link) and [Log Records](../logs/data-model.md), -and even [Attribute Value](#attribute-value) itself -may contain a collection of attributes. +contain a collection of attributes. Implementation MUST by default ensure that the exported attribute collections contain only unique keys. The enforcement of uniqueness may be performed diff --git a/specification/logs/data-model.md b/specification/logs/data-model.md index 5ba29aec4e6..260d77187ea 100644 --- a/specification/logs/data-model.md +++ b/specification/logs/data-model.md @@ -347,12 +347,12 @@ when it is used to represent an unspecified severity. ### Field: `Body` -Type: [Attribute Value](../common/README.md#attribute-value). +Type: [AnyValue](../common/README.md#anyvalue). Description: A value containing the body of the log record. Can be for example a human-readable string message (including multi-line) describing the event in a free form or it can be a structured data composed of arrays and maps of other -values. Body MUST support [Attribute Value](../common/README.md#attribute-value) +values. Body MUST support [AnyValue](../common/README.md#anyvalue) to preserve the semantics of structured logs emitted by the applications. Can vary for each occurrence of the event coming from the same source. This field is optional. From 4a15e7cd5666fae9d038a9eb87d4c1158501ddca Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Wed, 3 Sep 2025 09:44:45 +0200 Subject: [PATCH 32/36] update Attribute Limits --- specification/common/README.md | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/specification/common/README.md b/specification/common/README.md index 1a8e5d7ecfb..5c95baf1acf 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -160,33 +160,20 @@ If an SDK provides a way to: - if it is a string, if it exceeds that limit (counting any character in it as 1), SDKs MUST truncate that value, so that its length is at most equal to the limit, - - if it is an array or an attribute collection, then apply the above rule to - each of its string values separately, + - if it is a byte array, if it exceeds that limit (counting each byte as 1), + SDKs MUST truncate that value, so that its length is at most equal to the limit, + - if it is an array of [AnyValue](#anyvalue), then apply the limit to + each value within the array recursively, + - if it is a [`map`](#mapstring-anyvalue), then apply the + limit to each value within the map recursively, - otherwise a value MUST NOT be truncated; - set an attribute count limit such that: - if an attribute addition into an attribute collection would result - in exceeding the limit (counting each attribute in the collection as 1; - if an attribute is itself a collection, each attribute within the nested - collection is also counted as a separate attribute of the parent), + in exceeding the limit (counting each attribute in the collection as 1), SDK MUST discard that attribute, so that the total number of attributes in an attribute collection is at most equal to the limit; - otherwise an attribute MUST NOT be discarded. -**Attribute count example:** -Consider an attribute collection with two attributes: - -- `a: 1` -- `b: { x: "foo", y: "bar", z: "baz" }` - -Here, `a` is a primitive attribute, and `b` is itself a collection with 3 attributes. -The total attribute count is calculated as follows: - -- `a` counts as 1, -- each attribute in `b` (`x`, `y`, `z`) counts as 1 each (total 3), -- `b` itself counts as 1 (the parent attribute). - -Total attribute count = 1 (`a`) + 1 (`b`) + 3 (`x`, `y`, `z`) = 5 - There MAY be a log emitted to indicate to the user that an attribute was truncated or discarded. To prevent excessive logging, the log MUST NOT be emitted more than once per record on which an attribute is set. @@ -205,7 +192,7 @@ model-specific limit default value, followed by the global limit default value. ### Configurable Parameters * `AttributeCountLimit` (Default=128) - Maximum allowed attribute count per record; -* `AttributeValueLengthLimit` (Default=Infinity) - Maximum allowed attribute value length; +* `AttributeValueLengthLimit` (Default=Infinity) - Maximum allowed attribute value length (applies to string values and byte arrays); ### Exempt Entities From 552e997efb6904f5d103db6cfac86b17d0c01e91 Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Wed, 3 Sep 2025 09:51:36 +0200 Subject: [PATCH 33/36] fix toc --- specification/common/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/common/README.md b/specification/common/README.md index 5c95baf1acf..92480f71777 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -16,7 +16,7 @@ path_base_for_github_subdir: - [AnyValue](#anyvalue) -- [map](#mapstring-anyvalue) +- [map](#mapstring-anyvalue) - [Attribute](#attribute) * [Attribute Collections](#attribute-collections) - [Attribute Limits](#attribute-limits) @@ -164,7 +164,7 @@ If an SDK provides a way to: SDKs MUST truncate that value, so that its length is at most equal to the limit, - if it is an array of [AnyValue](#anyvalue), then apply the limit to each value within the array recursively, - - if it is a [`map`](#mapstring-anyvalue), then apply the + - if it is a [map](#mapstring-anyvalue), then apply the limit to each value within the map recursively, - otherwise a value MUST NOT be truncated; - set an attribute count limit such that: From b224937382f23d38faff661c2009722f8c60de86 Mon Sep 17 00:00:00 2001 From: Robert Pajak Date: Wed, 3 Sep 2025 09:54:29 +0200 Subject: [PATCH 34/36] fix limit rules --- specification/common/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/specification/common/README.md b/specification/common/README.md index 92480f71777..c8b68026e37 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -162,10 +162,12 @@ If an SDK provides a way to: to the limit, - if it is a byte array, if it exceeds that limit (counting each byte as 1), SDKs MUST truncate that value, so that its length is at most equal to the limit, + - if it is an array of string, then apply the limit to + each value within the array separately, - if it is an array of [AnyValue](#anyvalue), then apply the limit to - each value within the array recursively, + each value within the array separately, - if it is a [map](#mapstring-anyvalue), then apply the - limit to each value within the map recursively, + limit to each value within the map separately, - otherwise a value MUST NOT be truncated; - set an attribute count limit such that: - if an attribute addition into an attribute collection would result From 022baf916ea1515498c5f327bc837a9107ba81a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Paj=C4=85k?= Date: Mon, 8 Sep 2025 13:56:42 +0200 Subject: [PATCH 35/36] Update oteps/4485-extending-attributes-to-support-complex-values.md --- oteps/4485-extending-attributes-to-support-complex-values.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oteps/4485-extending-attributes-to-support-complex-values.md b/oteps/4485-extending-attributes-to-support-complex-values.md index 8a3cbfe81d0..95f1a0c6423 100644 --- a/oteps/4485-extending-attributes-to-support-complex-values.md +++ b/oteps/4485-extending-attributes-to-support-complex-values.md @@ -94,7 +94,7 @@ extending the standard attributes provides a more seamless and user-friendly API Currently, the SDK specification has a clause that says extending the set of standard attribute would be -[considered a breaking change](/specification/common/README.md#attribute). +[considered a breaking change](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.44.0/specification/common/README.md#standard-attribute). We believe that removing this clause and extending standard attributes can be done gracefully across the OpenTelemetry ecosystem From ce4d50849397b7c5abc6ca656f2ea95f04547b72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Paj=C4=85k?= Date: Tue, 16 Sep 2025 11:08:41 +0200 Subject: [PATCH 36/36] Update attribute-type-mapping.md --- specification/common/attribute-type-mapping.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/specification/common/attribute-type-mapping.md b/specification/common/attribute-type-mapping.md index d41ebc82979..e936eb1695c 100644 --- a/specification/common/attribute-type-mapping.md +++ b/specification/common/attribute-type-mapping.md @@ -13,7 +13,6 @@ linkTitle: Mapping to AnyValue - [Converting to AnyValue](#converting-to-anyvalue) * [Primitive Values](#primitive-values) - + [Empty Value](#empty-value) + [Integer Values](#integer-values) + [Enumerations](#enumerations) + [Floating Point Values](#floating-point-values) @@ -55,12 +54,6 @@ follow the rules described below. ### Primitive Values -#### Empty Value - -Empty values MUST be converted to AnyValue with no -[value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L28-L30) -field being set. - #### Integer Values Integer values which are within the range of 64 bit signed numbers