|
| 1 | +--- |
| 2 | +title: Announcing Support for Complex Attribute Types in OTel |
| 3 | +linkTitle: Announcing Support for Complex Attribute Types in OTel |
| 4 | +date: 2025-11-05 |
| 5 | +author: >- |
| 6 | + [Liudmila Molkova](https://github.com/lmolkova) (Grafana Labs), [Robert |
| 7 | + Pajak](https://github.com/pellared) (Splunk), [Trask |
| 8 | + Stalnaker](https://github.com/trask) (Microsoft), [Austin |
| 9 | + Parker](https://github.com/austinlparker) (honeycomb.io) |
| 10 | +sig: Specification, Logs |
| 11 | +issue: https://github.com/open-telemetry/opentelemetry-specification/pull/4485 |
| 12 | +cSpell:ignore: Liudmila Molkova Pajak |
| 13 | +--- |
| 14 | + |
| 15 | +It’s common to use simple key-value properties as attributes in telemetry. Most |
| 16 | +telemetry backends are optimized for this pattern, making it efficient to store, |
| 17 | +index, and query data. |
| 18 | + |
| 19 | +OpenTelemetry is designed with this in mind. Semantic conventions and |
| 20 | +instrumentations aim to provide useful attributes that can be easily filtered |
| 21 | +and aggregated. |
| 22 | + |
| 23 | +But what happens when the data itself is complex? OpenTelemetry also strives to |
| 24 | +capture observability for real-world systems, libraries, and applications whose |
| 25 | +observable properties are sometimes complex. |
| 26 | + |
| 27 | +Recently OpenTelemetry has announced upcoming support for capturing complex data |
| 28 | +across all OTel signals starting with OTLP |
| 29 | +[1.9.0](https://github.com/open-telemetry/opentelemetry-proto/releases/tag/v1.9.0), |
| 30 | +and in future OpenTelemetry API and SDK versions across the ecosystem. |
| 31 | + |
| 32 | +In this post, we’ll cover when and how to use complex data, when to avoid it, |
| 33 | +and how backends can start supporting it. |
| 34 | + |
| 35 | +## Upcoming support for complex attribute types in OpenTelemetry |
| 36 | + |
| 37 | +OpenTelemetry APIs and SDKs are adding support for the following attribute types |
| 38 | +on all signals: |
| 39 | + |
| 40 | +- Maps (with string keys and values of any supported type) |
| 41 | +- Heterogeneous arrays (containing elements of any supported type) |
| 42 | +- Byte arrays |
| 43 | +- Empty values |
| 44 | + |
| 45 | +Until recently, these types were supported only on logs - attributes on other |
| 46 | +signals were limited to primitives and arrays of primitives. |
| 47 | + |
| 48 | +Following |
| 49 | +[OTEP 4485: Extending attributes to support complex values](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.49.0/oteps/4485-extending-attributes-to-support-complex-values.md) |
| 50 | +and its implementation in OTLP and the specification, this support is being |
| 51 | +extended to all OTel signals. |
| 52 | + |
| 53 | +The new attribute types, especially maps and heterogeneous arrays, should be |
| 54 | +used with care. Many observability backends are not optimized to query, index, |
| 55 | +or aggregate complex attributes. Semantic conventions will assume complex |
| 56 | +attributes are not indexed and will avoid using them on metrics or in other |
| 57 | +scenarios where efficient querying is important. |
| 58 | + |
| 59 | +When possible, stick to primitive values. |
| 60 | + |
| 61 | +## Why are we doing this? |
| 62 | + |
| 63 | +As we work on semantic conventions and instrumentations, we increasingly |
| 64 | +encounter cases where flat attributes cannot reasonably capture the complexity |
| 65 | +of real-world scenarios. |
| 66 | + |
| 67 | +Examples include: |
| 68 | + |
| 69 | +- **[LLM operations](/docs/specs/semconv/gen-ai/non-normative/examples-llm-calls)** |
| 70 | + — input parameters like tool definitions and input/output messages are |
| 71 | + inherently structured |
| 72 | +- **GraphQL** — responses may include |
| 73 | + [lists of structured errors](https://graphql.org/learn/response/#errors) |
| 74 | +- **[Database operations](/docs/specs/semconv/database/database-spans)** — batch |
| 75 | + operations have properties that flat attributes cannot adequately capture |
| 76 | + |
| 77 | +Before extending support for complex attributes to all signals, we explored |
| 78 | +several alternatives: |
| 79 | + |
| 80 | +### Limiting support to logs (and spans) |
| 81 | + |
| 82 | +Having different attribute collection types for different signals affects API |
| 83 | +ergonomics, making it less convenient and efficient to work with attributes. |
| 84 | + |
| 85 | +### Flattening |
| 86 | + |
| 87 | +Flattening works well for maps of primitives but breaks down for arrays. For |
| 88 | +example, structured data like: |
| 89 | + |
| 90 | +```json |
| 91 | +{ |
| 92 | + "data": [ |
| 93 | + { |
| 94 | + "foo": "bar", |
| 95 | + "baz": 42 |
| 96 | + } |
| 97 | + ] |
| 98 | +} |
| 99 | +``` |
| 100 | + |
| 101 | +is reported as either: |
| 102 | + |
| 103 | +```text |
| 104 | +data.0.foo = "bar" |
| 105 | +data.0.baz = 42 |
| 106 | +``` |
| 107 | + |
| 108 | +or: |
| 109 | + |
| 110 | +```text |
| 111 | +data.foo = ["bar"] |
| 112 | +data.baz = [ 42 ] |
| 113 | +``` |
| 114 | + |
| 115 | +Both approaches are limited and lead to a poor user experience. |
| 116 | + |
| 117 | +### String serialization |
| 118 | + |
| 119 | +Another option is requiring users or instrumentations to serialize complex data |
| 120 | +into strings. While workable, this risks inconsistencies and errors. It also |
| 121 | +limits post-processing and leads to poor truncation strategies. Ultimately, it |
| 122 | +should be the backend’s decision whether to preserve the structure or serialize |
| 123 | +the data. Handling serialization at the backend side provides greater |
| 124 | +consistency and convenience for end users. |
| 125 | + |
| 126 | +## How should backends support complex attributes? |
| 127 | + |
| 128 | +We encourage backends to build user experiences that leverage structured |
| 129 | +attribute values, allowing users to query data based on nested properties. |
| 130 | + |
| 131 | +In the meantime, we recommend that backends serialize complex attributes to JSON |
| 132 | +(or another suitable format) at ingestion time. |
| 133 | + |
| 134 | +The OTel Specification, Semantic Conventions, and API documentation will clearly |
| 135 | +communicate to instrumentation authors that complex attribute support may be |
| 136 | +limited and will continue to recommend flat attributes whenever possible. |
| 137 | + |
| 138 | +## When should you use complex attributes? |
| 139 | + |
| 140 | +When you can reasonably express data using flat attributes, use flat attributes. |
| 141 | + |
| 142 | +Use complex attributes only when the data is too complex to express with flat |
| 143 | +attributes — for example, when recording lists of complex objects. |
| 144 | + |
| 145 | +For semantic conventions and instrumentation libraries, we don't recommend |
| 146 | +changing anything existing in response to this announcement. This should only |
| 147 | +affect new features which require the use of complex attributes. |
| 148 | + |
| 149 | +## Comments? |
| 150 | + |
| 151 | +We’ve opened a |
| 152 | +[GitHub issue to discuss this post](https://github.com/open-telemetry/community/issues/3119), |
| 153 | +and we’d love your feedback. |
0 commit comments