-
Notifications
You must be signed in to change notification settings - Fork 933
OTEP: Extending attributes to support complex values #4485
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 6 commits
Commits
Show all changes
63 commits
Select commit
Hold shift + click to select a range
1f538b0
Complex attributes OTEP (draft)
e0cf307
why
trask 3209dd7
first round
21558e0
Merge pull request #2 from lmolkova/complex-attributes
trask de20078
clarify metrics
7f27984
Merge pull request #3 from lmolkova/complex-attributes
trask cad874e
more about why not a breaking change
trask f7626c1
newline
trask 6da42db
simplify, move options to the future, add glossary
ffbacf0
Merge pull request #4 from lmolkova/complex-attributes-2
163cfba
rename file
22fb140
clarify
trask 9a14f95
simplify
trask 8a21990
Update oteps/4485-extending-attributes-to-support-complex-values.md
33ed4c2
exporters, null value, prometheus
6ca73a1
comment with link on limits
a883928
toc
017b9fd
another round of feedback
cd58951
Update oteps/4485-extending-attributes-to-support-complex-values.md
b63ad0f
wording
trask 1acc53d
another example
trask 0b43566
refine reasons why non-breaking
trask 95f2bb6
add json serialization stability
bf44dbf
Update oteps/4485-extending-attributes-to-support-complex-values.md
2c04f16
remove note on metrics, added backend research table
5856172
lint
04d148e
Update time table
trask fae4007
SDK requirement matching API requirement. also exemplars
trask 81d0b55
feedback
trask e3d6b89
feedback
trask 8ba65ac
span links
trask 10ad24c
add prototypes and clarify limit
06332e7
remove 'should not provide convenience'
f60117f
Update oteps/4485-extending-attributes-to-support-complex-values.md
trask 1807c5b
Update oteps/4485-extending-attributes-to-support-complex-values.md
trask d535198
Update oteps/4485-extending-attributes-to-support-complex-values.md
trask 89cff55
Update oteps/4485-extending-attributes-to-support-complex-values.md
trask ad41831
update NR behavior
trask fe2d853
Update oteps/4485-extending-attributes-to-support-complex-values.md
trask 03bd028
Update oteps/4485-extending-attributes-to-support-complex-values.md
trask b019ddf
Update oteps/4485-extending-attributes-to-support-complex-values.md
trask 09c6b56
Update oteps/4485-extending-attributes-to-support-complex-values.md
trask 6abe3a4
Update oteps/4485-extending-attributes-to-support-complex-values.md
trask 907386c
add note about backend research
trask b639028
sdk and collector
trask cf9af50
Update oteps/4485-extending-attributes-to-support-complex-values.md
trask 7f0dd09
Update oteps/4485-extending-attributes-to-support-complex-values.md
trask 7af24d3
Update oteps/4485-extending-attributes-to-support-complex-values.md
trask 9d3629f
feedback
trask 85dd9b7
clarification
trask 9eb9601
fix toc
trask 6582fd6
Update oteps/4485-extending-attributes-to-support-complex-values.md
trask 69fe9d0
exemplar attributes are from metrics
trask 1b3b5ba
explain why MUST/MAY support for different areas
trask c1d9a5a
remove attribute limits from the OTEP - it's tracked in #4487
5e3e53f
replace Oct 1 with 6 months from merge
d7565e6
address some of the anyvalue comments
1f93651
remove confusing statement on AnyValue enforcement
7125cd0
equality notes
3235744
Add AnyValue definition and clean up some usages
5f35562
lint
45a82c0
add pointer/ref as a future possibility, limit deep equailty requirem…
e0d8748
toc
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
220 changes: 220 additions & 0 deletions
220
oteps/XXXX-extending-attributes-to-support-complex-values.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,220 @@ | ||
# Extending attributes to support complex values | ||
|
||
* [Why?](#why) | ||
* [Why do we want complex attributes on spans?](#why-do-we-want-complex-attributes-on-spans) | ||
* [Why do we want to extend standard attributes?](#why-do-we-want-to-extend-standard-attributes) | ||
* [Why isn't it a breaking change?](#why-isnt-it-a-breaking-change) | ||
* [How](#how) | ||
* [API](#api) | ||
* [SDK](#sdk) | ||
* [Signals that support complex attributes](#signals-that-support-complex-attributes) | ||
* [Signals that don't support complex attributes](#signals-that-dont-support-complex-attributes) | ||
* [Handling complex attributes](#handling-complex-attributes) | ||
* [Semantic conventions](#semantic-conventions) | ||
* [Trade-offs and mitigations](#trade-offs-and-mitigations) | ||
* [Prior art and alternatives](#prior-art-and-alternatives) | ||
* [Open questions](#open-questions) | ||
* [Future possibilities](#future-possibilities) | ||
|
||
## Why? | ||
|
||
### Why do we want complex attributes on spans? | ||
|
||
There are a number of reasons why we want to allow complex attributes on spans: | ||
|
||
- Emerging semantic conventions, such as Generative AI, | ||
demonstrate the usefulness of including complex attributes on spans. | ||
- Many users already add complex attributes to spans by JSON-encoding them. | ||
Supporting complex attributes natively enables future possibilities like | ||
collector transformations, better attribute truncation, and native | ||
storage of complex attributes in backends. | ||
- During the span event deprecation process, we found that some people | ||
use span events to represent complex data on spans. | ||
Providing support for complex attributes on spans would offer a more natural | ||
way to store this data. | ||
- During the event stabilization process, it became clear that | ||
[spans and events are often thought of as being conceptual | ||
twins.](https://opentelemetry.io/blog/2025/opentelemetry-logging-and-you/#how-is-this-different-from-other-signals), | ||
and the choice between modeling something as a span or an event should not | ||
be influenced by whether complex attributes are needed. | ||
|
||
### Why do we want to extend standard attributes? | ||
|
||
Instead of introducing a second set of "extended" attributes that can be used on | ||
spans and events, we propose to extend the standard attributes. | ||
|
||
Having multiple attribute sets across the API | ||
[creates ergonomic challenges](https://github.com/open-telemetry/opentelemetry-specification/issues/4201). | ||
While there are some mitigations ([as demonstrated in | ||
Java](https://github.com/open-telemetry/opentelemetry-java/pull/7123)), | ||
lmolkova marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
extending the standard attributes provides a more seamless and user-friendly API experience. | ||
|
||
### Why isn't it a breaking change? | ||
|
||
Currently, the SDK specification states that extending the set of standard | ||
attribute types to the full set of attribute types supported by OTLP would be | ||
[considered a breaking change](../specification/common/README.md#standard-attribute). | ||
|
||
We propose revisiting this and allowing extending the set of standard attribute | ||
types to the full set of attribute types supported by OTLP, without treating it as | ||
a breaking change, for the following reasons: | ||
|
||
- Language SDKs can implement this without breaking their backwards | ||
compatibility guarantees (e.g., [Java's](https://github.com/open-telemetry/opentelemetry-java/blob/main/VERSIONING.md)). | ||
- While backends will need to add support for complex attributes, this is | ||
consistent with the introduction of other new features that enable | ||
new capabilities. | ||
A reasonably straightforward implementation option for backends is to JSON serialize | ||
complex attribute values and store them as strings. | ||
|
||
## How | ||
|
||
### API | ||
|
||
Existing APIs that create or add attributes will be extended to support value with type `AnyValue`. | ||
|
||
It's up to the language to expose an `AnyValue` API for type checking, ergonomics, or performance. | ||
Alternatively, it may use a base object or another standard library type. | ||
|
||
Exposing multiple `Attributes` types is NOT RECOMMENDED if conversion between them | ||
is non-trivial in terms of usability or performance. | ||
|
||
The SDK is responsible for handling attribute types depending on the signal. | ||
|
||
> [!NOTE] | ||
> | ||
> While OTel metrics are designed for aggregation, future SDK implementations | ||
> may choose to record measurements as individual events. This would make complex | ||
> values acceptable in metrics. | ||
> | ||
> Ultimately, it’s up to the SDK implementation to decide whether to support complex | ||
> values for a given signal. Guidance for OTel-hosted SDKs is provided in the next section. | ||
> | ||
> The API, however, is less opinionated. It should not offer conveniences for recording | ||
> complex attributes on metrics (resources, etc), but it does not have to make it impossible. | ||
|
||
### SDK | ||
|
||
#### Signals that support complex attributes | ||
|
||
**The OTel SDK MUST support complex attributes on spans, logs, profiles, and descriptive | ||
entity attributes.** | ||
lmolkova marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
Any future OTel signals SHOULD support complex attributes unless there is a | ||
reason not to, which MUST be documented in the specification. | ||
|
||
By default, the OTel SDK SHOULD pass complex attributes to the processing pipeline. | ||
The SDK MUST support reading and modifying complex attributes during processing. | ||
|
||
If `AnyValue` is not defined at the API level, the OTel SDK SHOULD provide it as | ||
a contract for processors and exporters. The SDK MUST document the contract and | ||
SHOULD convert non-primitive input values to this common type. If conversion is | ||
not possible - e.g., when a non-serializable or unknown object is passed - the SDK | ||
SHOULD record string representation of the provided object. | ||
|
||
See the [Configuring complex attribute handling](#configuring-complex-attribute-handling) | ||
section for customization options. | ||
|
||
#### Signals that don't support complex attributes | ||
|
||
**The OTel SDK SHOULD serialize complex attributes to JSON string if they are added | ||
to metrics, resources, instrumentation scope, or used as identifying attributes on entities.** | ||
lmolkova marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
The SDK MAY allow customizing this behavior, see [Configuring | ||
complex attribute handling](#allow-recording-structured-attributes) section. | ||
|
||
> [!Note] | ||
> | ||
> Complex attributes are not intended to be used on metrics and other | ||
> signals in this category. Their usage is discouraged and expected to be accidental. | ||
> | ||
> JSON serialization overhead is limited to specific applications and is used as a | ||
> fallback (better than dropping). | ||
|
||
#### Handling complex attributes | ||
|
||
The SDK SHOULD allow per-signal configuration of [attribute limits](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/README.md#attribute-limits). | ||
|
||
**Attribute value length limit** SHOULD be applied to all leaf string nodes in `AnyValue`. | ||
String values SHOULD be truncated to the configured limit. | ||
|
||
Leaf nodes of an `AnyValue` attribute SHOULD count toward the **attribute count limit**. | ||
If the limit is reached, the SDK MUST drop the entire `AnyValue` attribute; | ||
partial exports are not allowed. | ||
|
||
A **new attribute limit** property will be introduced to control how and if complex | ||
attributes are handled, with the following options: | ||
lmolkova marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
- **pass as is** | ||
- Default for spans, logs, profiles, and descriptive entity attributes. | ||
- The SDK MAY support this option for all signals. | ||
|
||
- **serialize to JSON string** | ||
jack-berg marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
- Default for metrics, resources, instrumentation scopes, and identifying entity attributes. | ||
- The SDK MUST support this option for all signals and SHOULD provide per-signal configuration. | ||
lmolkova marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
- **drop** | ||
- The SDK MAY support this option | ||
|
||
### Semantic conventions | ||
|
||
Semantic conventions will be updated with the following guidance | ||
|
||
- Standard attributes SHOULD be used whenever possible. Semantic conventions SHOULD | ||
lmolkova marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
assume that backends do not index individual properties of complex attributes, | ||
that querying or aggregating on such properties is inefficient and complicated, | ||
and that reporting complex attributes carries higher performance overhead. | ||
|
||
- Complex attributes that are likely to be large (when serialized to a string) SHOULD | ||
be added as *opt-in* attributes. *Large* will be defined based on common backend | ||
attribute limits, typically around 4–16 KB. | ||
|
||
- Complex attributes MUST NOT be used on metrics, resources, instrumentation scopes, | ||
or as identifying attributes on entities. | ||
|
||
## Trade-offs and mitigations | ||
|
||
1. Allowing arbitrary objects as attributes is convenient but increases the risk of | ||
including large, sensitive, mutable, non-serializable, or otherwise problematic | ||
data in telemetry. | ||
|
||
It is RECOMMENDED to enforce `AnyValue` compatibility at the API level. | ||
Users and instrumentations SHOULD define custom `AnyValue`-compatible models | ||
to minimize misuse and reduce performance overhead. | ||
|
||
OTel SDKs MAY provide convenience methods to convert arbitrary objects to `AnyValue`. | ||
If such convenience is provided, it is RECOMMENDED to limit supported types | ||
to primitives, arrays, standard library collections, named tuples, JSON objects, and | ||
similar structures. | ||
|
||
If the object has any property with an unrecognized type, it is RECOMMENDED | ||
to fall back to recording a string representation of the whole object to minimize | ||
the risk of unintentional use of complex attributes. | ||
|
||
2. While it should be possible to record complex data in telemetry, many backends do not | ||
support it well - or at all - which can result in individual complex attributes | ||
or entire spans being dropped or rejected. | ||
|
||
In the future, support for complex attributes may be negotiated via OpAMP, | ||
allowing this behavior to be configured based on backend capabilities without | ||
requiring user intervention. | ||
|
||
In the meantime, we plan to mitigate this through: | ||
|
||
- Requiring an SDK mode that serializes complex attributes to JSON | ||
- A collector transformation processor that already can drop, flatten, serialize, or | ||
truncate complex attributes using OTTL | ||
- Semantic conventions guidance that discourages their use | ||
|
||
## Prior art and alternatives | ||
|
||
TODO | ||
|
||
## Open questions | ||
|
||
TODO | ||
|
||
## Future possibilities | ||
|
||
We can consider a separate set of attribute limits specifically for complex values, | ||
including a total size limit and ability to estimate `AnyValue` object size. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.