diff --git a/CHANGELOG.md b/CHANGELOG.md index 64b4bbd65f2..b571ac8adda 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ release. ### Metrics +- Add in-development `Bind` API to synchronous instruments. + ([#5050](https://github.com/open-telemetry/opentelemetry-specification/pull/5050)) - Stabilize sections of Prometheus Metrics Exporter. - Stabilize temporality. ([#5024](https://github.com/open-telemetry/opentelemetry-specification/issues/5024)) diff --git a/spec-compliance-matrix.md b/spec-compliance-matrix.md index 532c53705a0..9ac5f58aad9 100644 --- a/spec-compliance-matrix.md +++ b/spec-compliance-matrix.md @@ -130,6 +130,7 @@ formats is required. Implementing more than one format is optional. | Instrument descriptions conform to the specified syntax. | | - | + | | - | + | + | | | - | + | | - | | Instrument supports the advisory ExplicitBucketBoundaries parameter. | | + | + | | | | + | | | | | | - | | Instrument supports the advisory Attributes parameter. | | - | + | | | | + | | | | | | - | +| Synchronous instruments support Bind to pre-associate attributes. | 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. | | + | + | + | - | | + | | | + | + | | - | diff --git a/spec-compliance-matrix/cpp.yaml b/spec-compliance-matrix/cpp.yaml index 81d935efb33..73b89390e79 100644 --- a/spec-compliance-matrix/cpp.yaml +++ b/spec-compliance-matrix/cpp.yaml @@ -223,6 +223,8 @@ sections: status: '?' - name: Instrument supports the advisory Attributes parameter. status: '?' + - name: Synchronous instruments support Bind to pre-associate attributes. + status: '-' - name: All methods of `MeterProvider` are safe to be called concurrently. status: '+' - name: All methods of `Meter` are safe to be called concurrently. diff --git a/spec-compliance-matrix/dotnet.yaml b/spec-compliance-matrix/dotnet.yaml index 87c7e13e0c0..b8716c6739a 100644 --- a/spec-compliance-matrix/dotnet.yaml +++ b/spec-compliance-matrix/dotnet.yaml @@ -223,6 +223,8 @@ sections: status: '?' - name: Instrument supports the advisory Attributes parameter. status: '?' + - name: Synchronous instruments support Bind to pre-associate attributes. + status: '-' - name: All methods of `MeterProvider` are safe to be called concurrently. status: '+' - name: All methods of `Meter` are safe to be called concurrently. diff --git a/spec-compliance-matrix/erlang.yaml b/spec-compliance-matrix/erlang.yaml index 63562233105..fb0618829a5 100644 --- a/spec-compliance-matrix/erlang.yaml +++ b/spec-compliance-matrix/erlang.yaml @@ -223,6 +223,8 @@ sections: status: '+' - name: Instrument supports the advisory Attributes parameter. status: '+' + - name: Synchronous instruments support Bind to pre-associate attributes. + status: '-' - name: All methods of `MeterProvider` are safe to be called concurrently. status: '+' - name: All methods of `Meter` are safe to be called concurrently. diff --git a/spec-compliance-matrix/go.yaml b/spec-compliance-matrix/go.yaml index f8226c23340..fe7ae165f7f 100644 --- a/spec-compliance-matrix/go.yaml +++ b/spec-compliance-matrix/go.yaml @@ -223,6 +223,8 @@ sections: status: '+' - name: Instrument supports the advisory Attributes parameter. status: '-' + - name: Synchronous instruments support Bind to pre-associate attributes. + status: '-' - name: All methods of `MeterProvider` are safe to be called concurrently. status: '+' - name: All methods of `Meter` are safe to be called concurrently. diff --git a/spec-compliance-matrix/java.yaml b/spec-compliance-matrix/java.yaml index 97d5f019df1..52f87f4f4ea 100644 --- a/spec-compliance-matrix/java.yaml +++ b/spec-compliance-matrix/java.yaml @@ -223,6 +223,8 @@ sections: status: '+' - name: Instrument supports the advisory Attributes parameter. status: '+' + - name: Synchronous instruments support Bind to pre-associate attributes. + status: '-' - name: All methods of `MeterProvider` are safe to be called concurrently. status: '+' - name: All methods of `Meter` are safe to be called concurrently. diff --git a/spec-compliance-matrix/js.yaml b/spec-compliance-matrix/js.yaml index e251573e343..5c8a3086bca 100644 --- a/spec-compliance-matrix/js.yaml +++ b/spec-compliance-matrix/js.yaml @@ -223,6 +223,8 @@ sections: status: '?' - name: Instrument supports the advisory Attributes parameter. status: '?' + - name: Synchronous instruments support Bind to pre-associate attributes. + status: '-' - name: All methods of `MeterProvider` are safe to be called concurrently. status: '+' - name: All methods of `Meter` are safe to be called concurrently. diff --git a/spec-compliance-matrix/kotlin.yaml b/spec-compliance-matrix/kotlin.yaml index 85497e43b36..e09b598731c 100644 --- a/spec-compliance-matrix/kotlin.yaml +++ b/spec-compliance-matrix/kotlin.yaml @@ -223,6 +223,8 @@ sections: status: '-' - name: Instrument supports the advisory Attributes parameter. status: '-' + - name: Synchronous instruments support Bind to pre-associate attributes. + status: '-' - name: All methods of `MeterProvider` are safe to be called concurrently. status: '-' - name: All methods of `Meter` are safe to be called concurrently. diff --git a/spec-compliance-matrix/php.yaml b/spec-compliance-matrix/php.yaml index b0a56fd4ab2..59082762795 100644 --- a/spec-compliance-matrix/php.yaml +++ b/spec-compliance-matrix/php.yaml @@ -223,6 +223,8 @@ sections: status: '?' - name: Instrument supports the advisory Attributes parameter. status: '?' + - name: Synchronous instruments support Bind to pre-associate attributes. + status: '-' - name: All methods of `MeterProvider` are safe to be called concurrently. status: '?' - name: All methods of `Meter` are safe to be called concurrently. diff --git a/spec-compliance-matrix/python.yaml b/spec-compliance-matrix/python.yaml index 4678fb92b36..80cc750d8d7 100644 --- a/spec-compliance-matrix/python.yaml +++ b/spec-compliance-matrix/python.yaml @@ -223,6 +223,8 @@ sections: status: '?' - name: Instrument supports the advisory Attributes parameter. status: '?' + - name: Synchronous instruments support Bind to pre-associate attributes. + status: '-' - name: All methods of `MeterProvider` are safe to be called concurrently. status: '-' - name: All methods of `Meter` are safe to be called concurrently. diff --git a/spec-compliance-matrix/ruby.yaml b/spec-compliance-matrix/ruby.yaml index bdd8f7148a3..739005a0a2f 100644 --- a/spec-compliance-matrix/ruby.yaml +++ b/spec-compliance-matrix/ruby.yaml @@ -223,6 +223,8 @@ sections: status: '?' - name: Instrument supports the advisory Attributes parameter. status: '?' + - name: Synchronous instruments support Bind to pre-associate attributes. + status: '-' - name: All methods of `MeterProvider` are safe to be called concurrently. status: '?' - name: All methods of `Meter` are safe to be called concurrently. diff --git a/spec-compliance-matrix/rust.yaml b/spec-compliance-matrix/rust.yaml index 9772047cd7e..e5657f4eea7 100644 --- a/spec-compliance-matrix/rust.yaml +++ b/spec-compliance-matrix/rust.yaml @@ -223,6 +223,8 @@ sections: status: '?' - name: Instrument supports the advisory Attributes parameter. status: '?' + - name: Synchronous instruments support Bind to pre-associate attributes. + status: '-' - name: All methods of `MeterProvider` are safe to be called concurrently. status: '?' - name: All methods of `Meter` are safe to be called concurrently. diff --git a/spec-compliance-matrix/swift.yaml b/spec-compliance-matrix/swift.yaml index 5bbc00b322a..d8177d29fb7 100644 --- a/spec-compliance-matrix/swift.yaml +++ b/spec-compliance-matrix/swift.yaml @@ -223,6 +223,8 @@ sections: status: '?' - name: Instrument supports the advisory Attributes parameter. status: '?' + - name: Synchronous instruments support Bind to pre-associate attributes. + status: '-' - name: All methods of `MeterProvider` are safe to be called concurrently. status: '?' - name: All methods of `Meter` are safe to be called concurrently. diff --git a/spec-compliance-matrix/template.yaml b/spec-compliance-matrix/template.yaml index cdd24a84326..8db2a6c7e4c 100644 --- a/spec-compliance-matrix/template.yaml +++ b/spec-compliance-matrix/template.yaml @@ -157,6 +157,8 @@ sections: - name: Instrument descriptions conform to the specified syntax. - name: Instrument supports the advisory ExplicitBucketBoundaries parameter. - name: Instrument supports the advisory Attributes parameter. + - name: Synchronous instruments support Bind to pre-associate attributes. + optional: true - name: All methods of `MeterProvider` are safe to be called concurrently. - name: All methods of `Meter` are safe to be called concurrently. - name: All methods of any instrument are safe to be called concurrently. diff --git a/specification/metrics/api.md b/specification/metrics/api.md index c37fccc944d..ba733a04c56 100644 --- a/specification/metrics/api.md +++ b/specification/metrics/api.md @@ -31,6 +31,7 @@ weight: 1 - [Asynchronous Instrument API](#asynchronous-instrument-api) * [General operations](#general-operations) + [Enabled](#enabled) + + [Bind](#bind) * [Counter](#counter) + [Counter creation](#counter-creation) + [Counter operations](#counter-operations) @@ -476,6 +477,10 @@ All [synchronous instruments](#synchronous-instrument-api) SHOULD provide functi * [Report if instrument is `Enabled`](#enabled) +All [synchronous instruments](#synchronous-instrument-api) MAY provide: + +* (**Development**) [Bind to a set of attributes](#bind) + #### Enabled To help users avoid performing computationally expensive operations when @@ -494,6 +499,61 @@ The returned value is not always static, it can change over time. The API SHOULD be documented that instrumentation authors needs to call this API each time they record a measurement to ensure they have the most up-to-date response. +#### Bind + +**Status**: [Development](../document-status.md) + +The `Bind` API associates a fixed set of [Attributes](../common/README.md#attribute) with every +measurement recorded on the returned bound instrument. Because attributes are resolved at bind +time rather than at each recording, implementations can avoid per-recording attribute processing +and lookup overhead. + +This API MUST accept the following parameter: + +* [Attributes](../common/README.md#attribute) to associate with every measurement recorded on + the returned bound instrument. + + Users can provide attributes to associate with the bound instrument, but it is up + to their discretion. Therefore, this API MUST be structured to accept a variable + number of attributes, including none. + +This API MUST return a language-idiomatic type representing the instrument bound to those +attributes. + +The returned bound instrument MUST support the instrument's core recording operation. +The instrument kind determines the recording operation on the bound instrument: + +* [Counter](#counter): [Add](#add) +* [Histogram](#histogram): [Record](#record) +* [Gauge](#gauge): [Record](#record-1) +* [UpDownCounter](#updowncounter): [Add](#add-1) + +This MAY be achieved by introducing a dedicated bound instrument type, or by reusing +the existing instrument interface. If the existing instrument interface is reused, the +`Bind` API MUST be documented to communicate to users that invoking attribute-bearing +recording operations on the returned bound instrument negates the performance benefits +of binding. + +Measurements recorded on the bound instrument can be associated with the +[Context](../context/README.md). + +Here are some examples that [OpenTelemetry API](../overview.md#api) authors might consider: + +```java +// Java + +LongCounter rolls = meter.counterBuilder("dice.rolls") + .setDescription("The number of times each side of the die was rolled") + .setUnit("{roll}") + .build(); + +var face1 = rolls.bind(Attributes.of(AttributeKey.longKey("roll.value"), 1L)); +var face6 = rolls.bind(Attributes.of(AttributeKey.longKey("roll.value"), 6L)); + +face1.add(1); +face6.add(1); +``` + ### Counter `Counter` is a [synchronous Instrument](#synchronous-instrument-api) which supports diff --git a/specification/metrics/sdk.md b/specification/metrics/sdk.md index 06211d1bfb3..5a82bb0cc02 100644 --- a/specification/metrics/sdk.md +++ b/specification/metrics/sdk.md @@ -54,6 +54,7 @@ weight: 3 + [Instrument advisory parameter: `ExplicitBucketBoundaries`](#instrument-advisory-parameter-explicitbucketboundaries) + [Instrument advisory parameter: `Attributes`](#instrument-advisory-parameter-attributes) * [Instrument enabled](#instrument-enabled) + * [Instrument bind](#instrument-bind) - [Attribute limits](#attribute-limits) - [Exemplar](#exemplar) * [ExemplarFilter](#exemplarfilter) @@ -1041,6 +1042,30 @@ Note: If a user makes no configuration changes, `Enabled` returns `true` since b default `MeterConfig.enabled=true` and instruments use the default aggregation when no matching views match the instrument. +### Instrument bind + +**Status**: [Development](../document-status.md) + +A bound instrument MUST behave identically to calling the equivalent unbound recording +operation with the pre-bound [Attributes](../common/README.md#attribute) on each +measurement. + +[Attribute processing](#measurement-processing) and [cardinality limit](#cardinality-limits) +evaluation MUST be performed at bind time. Each call to `Bind` MUST be independently +evaluated against the cardinality state at that moment. As a consequence, separate calls +to `Bind` with identical attributes may resolve to different aggregators (e.g. one to a +concrete series, another to the [overflow series](#overflow-attribute)) based on the +cardinality state at the time of each call. The resolved aggregator MUST be fixed and +not change across collection cycles. + +Measurements recorded on a bound instrument MUST be candidates for [Exemplar](#exemplar) +sampling. The [Context](../context/README.md) associated with each recording, whether +implicit or explicit, MUST be used for exemplar [TraceBased](#tracebased) filtering and +passed to the [ExemplarReservoir](#exemplarreservoir) offer method. + +The SDK MUST ensure attribute-free recordings on a bound instrument bypass per-recording +map lookup. + ## Attribute limits **Status**: [Stable](../document-status.md)