From 956de92eae44a27a6947e4e751247a8699d13239 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan Date: Mon, 17 Oct 2022 17:44:11 -0400 Subject: [PATCH] Support maps and heterogeneous arrays as attribute values Resolves https://github.com/open-telemetry/opentelemetry-specification/issues/376 Use cases where this is necessary or useful: 1. Specify more than one resource in the telemetry: https://github.com/open-telemetry/opentelemetry-specification/issues/579 2. Data coming from external source, e.g. AWS Metadata: https://github.com/open-telemetry/opentelemetry-specification/pull/596#issuecomment-628983680 or https://github.com/open-telemetry/opentelemetry-specification/issues/376#issuecomment-1227501082 3. Capturing HTTP headers: https://github.com/open-telemetry/opentelemetry-specification/issues/376#issuecomment-908493520 4. Structured stack traces: https://github.com/open-telemetry/opentelemetry-specification/pull/2841 5. Payloads as attributes: https://github.com/open-telemetry/oteps/pull/219#discussion_r971065645 This is a draft PR to see what the change looks like. If this PR is merged it will be nice to follow it up with: - A standard way of flattening maps and nested objects when converting from OTLP to formats that don't support maps/nested objects. - Recommendations for semantic conventions to use/not use complex objects. --- CHANGELOG.md | 3 + spec-compliance-matrix.md | 225 ++++++++++---------- specification/common/README.md | 16 +- specification/trace/sdk_exporters/jaeger.md | 4 +- specification/trace/sdk_exporters/zipkin.md | 4 +- 5 files changed, 134 insertions(+), 118 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f32c9810177..4ba4fa2a7b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,9 @@ release. ### Common +- Support maps and heterogeneous arrays as attribute values + ([#](https://github.com/open-telemetry/opentelemetry-specification/pull/)) + ## v1.14.0 (2022-10-04) ### Context diff --git a/spec-compliance-matrix.md b/spec-compliance-matrix.md index 2809cc4f8b9..493bb1b6845 100644 --- a/spec-compliance-matrix.md +++ b/spec-compliance-matrix.md @@ -63,6 +63,7 @@ formats is required. Implementing more than one format is optional. | Double floating-point type | | + | + | + | + | + | + | - | + | + | + | + | | Signed int64 type | | + | + | + | + | + | + | - | + | + | + | + | | Array of primitives (homogeneous) | | + | + | + | + | + | + | + | + | + | + | + | +| Non-homogeneous arrays and maps (including nested) | | | | | | | | | | | | | | `null` values documented as invalid/undefined | | + | + | + | + | + | N/A | + | | + | | N/A | | Unicode support for keys and string values | | + | + | + | + | + | + | + | + | + | + | + | | [Span linking](specification/trace/api.md#specifying-links) | | | | | | | | | | | | | @@ -94,117 +95,118 @@ formats is required. Implementing more than one format is optional. ## Metrics -| Feature | Optional | Go | Java | JS | Python | Ruby | Erlang | PHP | Rust | C++ | .NET | Swift | -|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|----|------|----|--------|------|--------|-----|------|-----|------|-------| -| The API provides a way to set and get a global default `MeterProvider`. | X | + | + | + | + | | | | | + | - | | -| It is possible to create any number of `MeterProvider`s. | X | + | + | + | + | | | | | | + | | -| `MeterProvider` provides a way to get a `Meter`. | | + | + | + | + | | | | | + | - | | -| `get_meter` accepts name, `version` and `schema_url`. | | + | + | + | + | | | | | + | - | | -| `get_meter` accepts `attributes`. | | | | | | | | | | | | | -| When an invalid `name` is specified a working `Meter` implementation is returned as a fallback. | | + | + | + | + | | | | | + | - | | -| The fallback `Meter` `name` property keeps its original invalid value. | X | - | - | + | + | | | | | - | - | | -| Associate `Meter` with `InstrumentationScope`. | | | + | + | + | | | | | | | | -| The meter provides functions to create a new `Counter`. | | + | + | + | + | | | | | + | + | | -| The meter provides functions to create a new `AsynchronousCounter`. | | + | + | + | + | | | | | + | + | | -| The meter provides functions to create a new `Histogram`. | | + | + | + | + | | | | | + | + | | -| The meter provides functions to create a new `AsynchronousGauge`. | | + | + | + | + | | | | | + | + | | -| The meter provides functions to create a new `UpDownCounter`. | | + | + | + | + | | | | | + | - | | -| The meter provides functions to create a new `AsynchronousUpDownCounter`. | | + | + | + | + | | | | | + | - | | -| Instruments have `name` | | + | + | + | + | | | | | + | + | | -| Instruments have kind. | | + | + | + | + | | | | | | + | | -| Instruments have an optional unit of measure. | | + | + | + | + | | | | | + | + | | -| Instruments have an optional description. | | + | + | + | + | | | | | + | + | | -| A valid instrument MUST be created and warning SHOULD be emitted when multiple instruments are registered under the same `Meter` using the same `name`. | | | + | + | + | | | | | | | | -| It is possible to register two instruments with same `name` under different `Meter`s. | | + | + | + | + | | | | | | + | | -| Instrument names conform to the specified syntax. | | - | + | | + | | | | | | + | | -| Instrument units conform to the specified syntax. | | - | + | | + | | | | | | + | | -| Instrument descriptions conform to the specified syntax. | | - | + | | - | | | | | | + | | -| `create_counter` returns a `Counter`. | | + | + | + | + | | | | | + | + | | -| The API for `Counter` accepts the name, unit and description of the instrument. | | + | + | + | + | | | | | + | + | | -| `Counter` has an `add` method. | | + | + | + | + | | | | | + | + | | -| The `add` method returns no (or dummy) value. | X | + | + | + | + | | | | | + | + | | -| The `add` method accepts optional attributes. | | + | + | + | + | | | | | + | + | | -| The `add` method accepts the increment amount. | | + | + | + | + | | | | | + | + | | -| The `add` method of `Counter` accepts only positive amounts. | | + | + | + | + | | | | | | - | | -| `create_asynchronous_counter` creates an `AsynchronousCounter`. | | + | + | + | + | | | | | + | + | | -| The API for `AsynchronousCounter` accepts the name, unit and description of the instrument. | | + | + | + | + | | | | | + | + | | -| The API for `AsynchronousCounter` accepts a callback. | | + | + | + | + | | | | | + | + | | -| `create_up_down_counter` returns an `UpDownCounter`. | | + | + | + | + | | | | | + | - | | -| The API for `UpDownCounter` accepts the name, unit and description of the instrument. | | + | + | + | + | | | | | + | - | | -| `UpDownCounter` has an `add` method. | | + | + | + | + | | | | | + | - | | -| The `add` method returns no (or dummy) value. | X | + | + | + | + | | | | | + | - | | -| The `add` method accepts optional attributes. | | + | + | + | + | | | | | + | - | | -| The `add` method accepts the increment amount. | | + | + | + | + | | | | | + | - | | -| `create_asynchronous_up_down_counter` creates an `AsynchronousUpDownCounter`. | | + | + | + | + | | | | | + | - | | -| The API for `AsynchronousUpDownCounter` accepts the name, unit and description of the instrument. | | + | + | + | + | | | | | + | - | | -| The API for `AsynchronousUpDownCounter` accepts a callback. | | + | + | + | + | | | | | + | - | | -| `create_histogram` returns a `Histogram`. | | + | + | + | + | | | | | + | + | | -| The API for `Histogram` accepts the name, unit and description of the instrument. | | + | + | + | + | | | | | + | + | | -| `Histogram` has a `record` method. | | + | + | + | + | | | | | + | + | | -| The `record` method return no (or dummy) value. | X | + | + | + | + | | | | | + | + | | -| The `record` method accepts optional attributes. | | + | + | + | + | | | | | + | + | | -| The `record` method accepts a value. | | + | + | + | + | | | | | + | + | | -| The `record` method of `Histogram` accepts only positive amounts. | | - | + | + | + | | | | | | + | | -| `create_asynchronous_gauge` creates an `Asynchronous Gauge`. | | + | + | + | + | | | | | + | + | | -| The API for `AsynchronousGauge` accepts the name, unit and description of the instrument. | | + | + | + | + | | | | | + | + | | -| The API for `AsynchronousGauge` accepts a callback. | | + | + | + | + | | | | | + | + | | -| The callback function of an `Asynchronous` instrument does not block indefinitely. | X | - | - | + | - | | | | | | ? | | -| The callback function reports `Measurement`s. | | + | + | + | + | | | | | + | + | | -| There is a way to pass state to the callback. | X | + | + | | + | | | | | | + | | -| All methods of `MeterProvider` are safe to be called concurrently. | | + | + | + | - | | | | | + | + | | -| All methods of `Meter` are safe to be called concurrently. | | + | + | + | - | | | | | | + | | -| All methods of any instrument are safe to be called concurrently. | | + | + | + | - | | | | | | + | | -| `MeterProvider` allows a `Resource` to be specified. | | + | + | + | + | | | | | + | + | | -| A specified `Resource` can be associated with all the produced metrics from any `Meter` from the `MeterProvider`. | | + | + | + | + | | | | | + | + | | -| The supplied `name`, `version` and `schema_url` arguments passed to the `MeterProvider` are used to create an `InstrumentationLibrary` instance stored in the `Meter`. | | + | - | | + | | | | | + | - | | -| The supplied `name`, `version` and `schema_url` arguments passed to the `MeterProvider` are used to create an `InstrumentationScope` instance stored in the `Meter`. | | | + | + | | | | | | | | | -| Configuration is managed solely by the `MeterProvider`. | | + | + | + | + | | | | | + | + | | -| The `MeterProvider` provides methods to update the configuration | X | - | - | - | + | | | | | | + | | -| The updated configuration applies to all already returned `Meter`s. | if above | - | - | - | - | | | | | | + | | -| There is a way to register `View`s with a `MeterProvider`. | | - | + | + | + | | | | | + | + | | -| The `View` instrument selection criteria is as specified. | | | + | + | + | | | | | + | + | | -| The `View` instrument selection criteria supports wildcards. | X | | + | + | + | | | | | + | + | | -| The `View` instrument selection criteria supports the match-all wildcard. | | | + | + | + | | | | | + | + | | -| The name of the `View` can be specified. | | | + | + | + | | | | | + | + | | -| The `View` allows configuring the name description, attributes keys and aggregation of the resulting metric stream. | | | + | + | + | | | | | + | - | | -| The `View` allows configuring the exemplar reservoir of resulting metric stream. | X | | - | | - | | | | | | - | | -| The SDK allows more than one `View` to be specified per instrument. | X | | + | + | + | | | | | + | + | | -| The `Drop` aggregation is available. | | + | + | + | - | | | | | + | + | | -| The `Drop` aggregation drops all measurements and does not produce a metric stream. | | + | + | + | - | | | | | | + | | -| The `Default` aggregation is available. | | + | + | + | - | | | | | + | + | | -| The `Default` aggregation uses the specified aggregation by instrument. | | + | + | + | - | | | | | + | + | | -| The `Sum` aggregation is available. | | + | + | + | + | | | | | + | + | | -| The `Sum` aggregation performs as specified. | | + | + | + | + | | | | | + | + | | -| The `LastValue` aggregation is available. | | + | + | + | + | | | | | + | + | | -| The `LastValue` aggregation performs as specified. | | + | + | + | + | | | | | + | + | | -| The `Histogram` aggregation is available. | | + | + | + | + | | | | | + | + | | -| The `Histogram` aggregation performs as specified. | | + | + | | + | | | | | + | + | | -| The explicit bucket `Histogram` aggregation is available. | | - | + | + | + | | | | | | + | | -| The explicit bucket `Histogram` aggregation performs as specified. | | - | + | + | + | | | | | | + | | -| The metrics Reader implementation supports registering metric Exporters | | | + | + | + | | | | | | + | | -| The metrics Reader implementation supports configuring the default aggregation on the basis of instrument kind. | | | - | | + | | | | | | - | | -| The metrics Reader implementation supports configuring the default temporality on the basis of instrument kind. | | | + | + | + | | | | | | | | -| The metrics Exporter has access to the aggregated metrics data (aggregated points, not raw measurements). | | + | + | + | + | | | | | | + | | -| The metrics Exporter `export` function can not be called concurrently from the same Exporter instance. | | + | + | + | - | | | | | | + | | -| The metrics Exporter `export` function does not block indefinitely. | | + | + | + | - | | | | | + | + | | -| The metrics Exporter `export` function receives a batch of metrics. | | + | + | + | + | | | | | + | + | | -| The metrics Exporter `export` function returns `Success` or `Failure`. | | + | + | + | + | | | | | + | + | | -| The metrics Exporter provides a `ForceFlush` function. | | - | + | + | - | | | | | + | + | | -| The metrics Exporter `ForceFlush` can inform the caller whether it succeeded, failed or timed out. | | | + | + | - | | | | | + | + | | -| The metrics Exporter provides a `shutdown` function. | | + | + | + | + | | | | | + | + | | -| The metrics Exporter `shutdown` function do not block indefinitely. | | + | + | + | + | | | | | + | + | | -| The metrics SDK samples `Exemplar`s from measurements. | | | + | | - | | | | | | - | | -| Exemplar sampling can be disabled. | | | - | | - | | | | | | - | | -| The metrics SDK samples measurements in the context of a sampled trace by default. | | | + | | - | | | | | | - | | -| Exemplars retain any attributes available in the measurement that are not preserved by aggregation or view configuration. | | | + | | - | | | | | | - | | -| Exemplars contain the associated trace id and span id of the active span in the Context when the measurement was taken. | | | + | | - | | | | | | - | | -| Exemplars contain the timestamp when the measurement was taken. | | | + | | - | | | | | | - | | -| The metrics SDK provides an `ExemplarReservoir` interface or extension point. | X | | - | | - | | | | | | - | | -| An `ExemplarReservoir` has an `offer` method with access to the measurement value, attributes, `Context` and timestamp. | X | | - | | - | | | | | | - | | -| The metrics SDK provides a `SimpleFixedSizeExemplarReservoir` that is used by default for all aggregations except `ExplicitBucketHistogram`. | | | + | | - | | | | | | - | | -| The metrics SDK provides an `AlignedHistogramBucketExemplarReservoir` that is used by default for `ExplicitBucketHistogram` aggregation. | | | + | | - | | | | | | - | | -| The metrics SDK provides an `ExemplarFilter` interface or extension point. | X | | - | | - | | | | | | - | | -| An `ExemplarFilter` has access to the measurement value, attributes, `Context` and timestamp. | X | | - | | - | | | | | | - | | +| Feature | Optional | Go | Java | JS | Python | Ruby | Erlang | PHP | Rust | C++ | .NET | Swift | +|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|----|------|----|--------|------|--------|-----|------|-----|------|-------| +| The API provides a way to set and get a global default `MeterProvider`. | X | + | + | + | + | | | | | + | - | | +| It is possible to create any number of `MeterProvider`s. | X | + | + | + | + | | | | | | + | | +| `MeterProvider` provides a way to get a `Meter`. | | + | + | + | + | | | | | + | - | | +| `get_meter` accepts name, `version` and `schema_url`. | | + | + | + | + | | | | | + | - | | +| `get_meter` accepts `attributes`. | | | | | | | | | | | | | +| When an invalid `name` is specified a working `Meter` implementation is returned as a fallback. | | + | + | + | + | | | | | + | - | | +| The fallback `Meter` `name` property keeps its original invalid value. | X | - | - | + | + | | | | | - | - | | +| Associate `Meter` with `InstrumentationScope`. | | | + | + | + | | | | | | | | +| The meter provides functions to create a new `Counter`. | | + | + | + | + | | | | | + | + | | +| The meter provides functions to create a new `AsynchronousCounter`. | | + | + | + | + | | | | | + | + | | +| The meter provides functions to create a new `Histogram`. | | + | + | + | + | | | | | + | + | | +| The meter provides functions to create a new `AsynchronousGauge`. | | + | + | + | + | | | | | + | + | | +| The meter provides functions to create a new `UpDownCounter`. | | + | + | + | + | | | | | + | - | | +| The meter provides functions to create a new `AsynchronousUpDownCounter`. | | + | + | + | + | | | | | + | - | | +| Instruments have `name` | | + | + | + | + | | | | | + | + | | +| Instruments have kind. | | + | + | + | + | | | | | | + | | +| Instruments have an optional unit of measure. | | + | + | + | + | | | | | + | + | | +| Instruments have an optional description. | | + | + | + | + | | | | | + | + | | +| A valid instrument MUST be created and warning SHOULD be emitted when multiple instruments are registered under the same `Meter` using the same `name`. | | | + | + | + | | | | | | | | +| It is possible to register two instruments with same `name` under different `Meter`s. | | + | + | + | + | | | | | | + | | +| Instrument names conform to the specified syntax. | | - | + | | + | | | | | | + | | +| Instrument units conform to the specified syntax. | | - | + | | + | | | | | | + | | +| Instrument descriptions conform to the specified syntax. | | - | + | | - | | | | | | + | | +| `create_counter` returns a `Counter`. | | + | + | + | + | | | | | + | + | | +| The API for `Counter` accepts the name, unit and description of the instrument. | | + | + | + | + | | | | | + | + | | +| `Counter` has an `add` method. | | + | + | + | + | | | | | + | + | | +| The `add` method returns no (or dummy) value. | X | + | + | + | + | | | | | + | + | | +| The `add` method accepts optional attributes. | | + | + | + | + | | | | | + | + | | +| The `add` method accepts the increment amount. | | + | + | + | + | | | | | + | + | | +| The `add` method of `Counter` accepts only positive amounts. | | + | + | + | + | | | | | | - | | +| `create_asynchronous_counter` creates an `AsynchronousCounter`. | | + | + | + | + | | | | | + | + | | +| The API for `AsynchronousCounter` accepts the name, unit and description of the instrument. | | + | + | + | + | | | | | + | + | | +| The API for `AsynchronousCounter` accepts a callback. | | + | + | + | + | | | | | + | + | | +| `create_up_down_counter` returns an `UpDownCounter`. | | + | + | + | + | | | | | + | - | | +| The API for `UpDownCounter` accepts the name, unit and description of the instrument. | | + | + | + | + | | | | | + | - | | +| `UpDownCounter` has an `add` method. | | + | + | + | + | | | | | + | - | | +| The `add` method returns no (or dummy) value. | X | + | + | + | + | | | | | + | - | | +| The `add` method accepts optional attributes. | | + | + | + | + | | | | | + | - | | +| The `add` method accepts the increment amount. | | + | + | + | + | | | | | + | - | | +| `create_asynchronous_up_down_counter` creates an `AsynchronousUpDownCounter`. | | + | + | + | + | | | | | + | - | | +| The API for `AsynchronousUpDownCounter` accepts the name, unit and description of the instrument. | | + | + | + | + | | | | | + | - | | +| The API for `AsynchronousUpDownCounter` accepts a callback. | | + | + | + | + | | | | | + | - | | +| `create_histogram` returns a `Histogram`. | | + | + | + | + | | | | | + | + | | +| The API for `Histogram` accepts the name, unit and description of the instrument. | | + | + | + | + | | | | | + | + | | +| `Histogram` has a `record` method. | | + | + | + | + | | | | | + | + | | +| The `record` method return no (or dummy) value. | X | + | + | + | + | | | | | + | + | | +| The `record` method accepts optional attributes. | | + | + | + | + | | | | | + | + | | +| The `record` method accepts a value. | | + | + | + | + | | | | | + | + | | +| The `record` method of `Histogram` accepts only positive amounts. | | - | + | + | + | | | | | | + | | +| `create_asynchronous_gauge` creates an `Asynchronous Gauge`. | | + | + | + | + | | | | | + | + | | +| The API for `AsynchronousGauge` accepts the name, unit and description of the instrument. | | + | + | + | + | | | | | + | + | | +| The API for `AsynchronousGauge` accepts a callback. | | + | + | + | + | | | | | + | + | | +| The callback function of an `Asynchronous` instrument does not block indefinitely. | X | - | - | + | - | | | | | | ? | | +| The callback function reports `Measurement`s. | | + | + | + | + | | | | | + | + | | +| There is a way to pass state to the callback. | X | + | + | | + | | | | | | + | | +| All methods of `MeterProvider` are safe to be called concurrently. | | + | + | + | - | | | | | + | + | | +| All methods of `Meter` are safe to be called concurrently. | | + | + | + | - | | | | | | + | | +| All methods of any instrument are safe to be called concurrently. | | + | + | + | - | | | | | | + | | +| `MeterProvider` allows a `Resource` to be specified. | | + | + | + | + | | | | | + | + | | +| A specified `Resource` can be associated with all the produced metrics from any `Meter` from the `MeterProvider`. | | + | + | + | + | | | | | + | + | | +| The supplied `name`, `version` and `schema_url` arguments passed to the `MeterProvider` are used to create an `InstrumentationLibrary` instance stored in the `Meter`. | | + | - | | + | | | | | + | - | | +| The supplied `name`, `version` and `schema_url` arguments passed to the `MeterProvider` are used to create an `InstrumentationScope` instance stored in the `Meter`. | | | + | + | | | | | | | | | +| Configuration is managed solely by the `MeterProvider`. | | + | + | + | + | | | | | + | + | | +| The `MeterProvider` provides methods to update the configuration | X | - | - | - | + | | | | | | + | | +| The updated configuration applies to all already returned `Meter`s. | if above | - | - | - | - | | | | | | + | | +| There is a way to register `View`s with a `MeterProvider`. | | - | + | + | + | | | | | + | + | | +| The `View` instrument selection criteria is as specified. | | | + | + | + | | | | | + | + | | +| The `View` instrument selection criteria supports wildcards. | X | | + | + | + | | | | | + | + | | +| The `View` instrument selection criteria supports the match-all wildcard. | | | + | + | + | | | | | + | + | | +| The name of the `View` can be specified. | | | + | + | + | | | | | + | + | | +| The `View` allows configuring the name description, attributes keys and aggregation of the resulting metric stream. | | | + | + | + | | | | | + | - | | +| The `View` allows configuring the exemplar reservoir of resulting metric stream. | X | | - | | - | | | | | | - | | +| The SDK allows more than one `View` to be specified per instrument. | X | | + | + | + | | | | | + | + | | +| The `Drop` aggregation is available. | | + | + | + | - | | | | | + | + | | +| The `Drop` aggregation drops all measurements and does not produce a metric stream. | | + | + | + | - | | | | | | + | | +| The `Default` aggregation is available. | | + | + | + | - | | | | | + | + | | +| The `Default` aggregation uses the specified aggregation by instrument. | | + | + | + | - | | | | | + | + | | +| The `Sum` aggregation is available. | | + | + | + | + | | | | | + | + | | +| The `Sum` aggregation performs as specified. | | + | + | + | + | | | | | + | + | | +| The `LastValue` aggregation is available. | | + | + | + | + | | | | | + | + | | +| The `LastValue` aggregation performs as specified. | | + | + | + | + | | | | | + | + | | +| The `Histogram` aggregation is available. | | + | + | + | + | | | | | + | + | | +| The `Histogram` aggregation performs as specified. | | + | + | | + | | | | | + | + | | +| The explicit bucket `Histogram` aggregation is available. | | - | + | + | + | | | | | | + | | +| The explicit bucket `Histogram` aggregation performs as specified. | | - | + | + | + | | | | | | + | | +| The metrics Reader implementation supports registering metric Exporters | | | + | + | + | | | | | | + | | +| The metrics Reader implementation supports configuring the default aggregation on the basis of instrument kind. | | | - | | + | | | | | | - | | +| The metrics Reader implementation supports configuring the default temporality on the basis of instrument kind. | | | + | + | + | | | | | | | | +| The metrics Exporter has access to the aggregated metrics data (aggregated points, not raw measurements). | | + | + | + | + | | | | | | + | | +| The metrics Exporter `export` function can not be called concurrently from the same Exporter instance. | | + | + | + | - | | | | | | + | | +| The metrics Exporter `export` function does not block indefinitely. | | + | + | + | - | | | | | + | + | | +| The metrics Exporter `export` function receives a batch of metrics. | | + | + | + | + | | | | | + | + | | +| The metrics Exporter `export` function returns `Success` or `Failure`. | | + | + | + | + | | | | | + | + | | +| The metrics Exporter provides a `ForceFlush` function. | | - | + | + | - | | | | | + | + | | +| The metrics Exporter `ForceFlush` can inform the caller whether it succeeded, failed or timed out. | | | + | + | - | | | | | + | + | | +| The metrics Exporter provides a `shutdown` function. | | + | + | + | + | | | | | + | + | | +| The metrics Exporter `shutdown` function do not block indefinitely. | | + | + | + | + | | | | | + | + | | +| The metrics SDK samples `Exemplar`s from measurements. | | | + | | - | | | | | | - | | +| Exemplar sampling can be disabled. | | | - | | - | | | | | | - | | +| The metrics SDK samples measurements in the context of a sampled trace by default. | | | + | | - | | | | | | - | | +| Exemplars retain any attributes available in the measurement that are not preserved by aggregation or view configuration. | | | + | | - | | | | | | - | | +| Exemplars contain the associated trace id and span id of the active span in the Context when the measurement was taken. | | | + | | - | | | | | | - | | +| Exemplars contain the timestamp when the measurement was taken. | | | + | | - | | | | | | - | | +| The metrics SDK provides an `ExemplarReservoir` interface or extension point. | X | | - | | - | | | | | | - | | +| An `ExemplarReservoir` has an `offer` method with access to the measurement value, attributes, `Context` and timestamp. | X | | - | | - | | | | | | - | | +| The metrics SDK provides a `SimpleFixedSizeExemplarReservoir` that is used by default for all aggregations except `ExplicitBucketHistogram`. | | | + | | - | | | | | | - | | +| The metrics SDK provides an `AlignedHistogramBucketExemplarReservoir` that is used by default for `ExplicitBucketHistogram` aggregation. | | | + | | - | | | | | | - | | +| The metrics SDK provides an `ExemplarFilter` interface or extension point. | X | | - | | - | | | | | | - | | +| An `ExemplarFilter` has access to the measurement value, attributes, `Context` and timestamp. | X | | - | | - | | | | | | - | | +| Non-homogeneous arrays and maps (including nested) | | | | | | | | | | | | | ## Logs @@ -233,6 +235,7 @@ Disclaimer: this list of features is still a work in progress, please refer to t | Feature | Optional | Go | Java | JS | Python | Ruby | Erlang | PHP | Rust | C++ | .NET | Swift | |---------------------------------------------------------------------------------------------------------------------------------------------|----------|----|------|----|--------|------|--------|-----|------|-----|------|-------| | Create from Attributes | | + | + | + | + | + | + | + | + | + | + | + | +| Non-homogeneous arrays and maps (including nested) for attribute values | | | | | | | | | | | | | | Create empty | | + | + | + | + | + | + | + | + | + | + | + | | [Merge (v2)](specification/resource/sdk.md#merge) | | + | + | | + | + | + | + | + | + | + | | | Retrieve attributes | | + | + | + | + | + | + | + | + | + | + | + | diff --git a/specification/common/README.md b/specification/common/README.md index 2b377a731cd..8f06f68f17e 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -29,10 +29,20 @@ 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. - 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. + - A homogeneous array of values of primitive type. + - An array of any attribute values [since 1.15.0]. + - A key/value map, where key is string and value is any attribute value [since 1.15.0]. -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 `[]`. +When exporting to protocols that do not natively support a particular non-string +value type the following conversion SHOULD be performed: + +| OpenTelemetry Value Type | Convert To String | +|-----------------------------------------|----------------------------| +| boolean, floating point, integer, array | JSON-encoding of the value | +| key/value map | TBD | + +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 diff --git a/specification/trace/sdk_exporters/jaeger.md b/specification/trace/sdk_exporters/jaeger.md index 629adbb011e..30112426444 100644 --- a/specification/trace/sdk_exporters/jaeger.md +++ b/specification/trace/sdk_exporters/jaeger.md @@ -133,8 +133,8 @@ OpenTelemetry Span `Attribute`(s) MUST be reported as `tags` to Jaeger. Primitive types MUST be represented by the corresponding types of Jaeger tags. -Array values MUST be serialized to string like a JSON list as mentioned in -[semantic conventions](../../overview.md#semantic-conventions). +Array and map values MUST be serialized to string like a JSON list as mentioned in +[attribute value definition](../../common/README.md#attribute). ### Links diff --git a/specification/trace/sdk_exporters/zipkin.md b/specification/trace/sdk_exporters/zipkin.md index b398c1efa31..cc9d44ba907 100644 --- a/specification/trace/sdk_exporters/zipkin.md +++ b/specification/trace/sdk_exporters/zipkin.md @@ -123,8 +123,8 @@ document maps to the strongly-typed fields of Zipkin spans. Primitive types MUST be converted to string using en-US culture settings. Boolean values MUST use lower case strings `"true"` and `"false"`. -Array values MUST be serialized to string like a JSON list as mentioned in -[semantic conventions](../../overview.md#semantic-conventions). +Array and map values MUST be serialized to string like a JSON list as mentioned in +[attribute value definition](../../common/README.md#attribute). TBD: add examples