diff --git a/CHANGELOG.md b/CHANGELOG.md index fc3ecfd0d91..0f0f49bf90f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,15 @@ release. ([#2379](https://github.com/open-telemetry/opentelemetry-specification/pull/2379)). - Clarify that MetricReader has one-to-one mapping to MeterProvider. ([#2406](https://github.com/open-telemetry/opentelemetry-specification/pull/2406)). +- Clarify the manner in which aggregation and temporality preferences + are encoded via MetricReader parameters "on the basis of instrument + kind". Rename the environment variable + `OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE` used to set the + preference to be used when auto-configuring an OTLP Exporter, + defaults to CUMULATIVE, with DELTA an option that makes Counter, + Asynchronous Counter, and Histogram instruments choose Delta + temporality by default. + ([#2404](https://github.com/open-telemetry/opentelemetry-specification/pull/2404)). ### Logs diff --git a/spec-compliance-matrix.md b/spec-compliance-matrix.md index 6f0ae8c43dc..0a85be1af1c 100644 --- a/spec-compliance-matrix.md +++ b/spec-compliance-matrix.md @@ -181,15 +181,18 @@ Disclaimer: this list of features is still a work in progress, please refer to t | The `Histogram` aggregation performs as specified. | | + | + | | - | | | | | | + | | | The explicit bucket `Histogram` aggregation is available. | | - | + | | + | | | | | | + | | | The explicit bucket `Histogram` aggregation performs as specified. | | - | + | | - | | | | | | + | | -| 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 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. | | | | | - | | | | | | - | | @@ -240,30 +243,31 @@ Disclaimer: this list of features is still a work in progress, please refer to t Note: Support for environment variables is optional. -|Feature |Go |Java|JS |Python|Ruby|Erlang|PHP|Rust|C++|.NET|Swift| -|----------------------------------------------|---|----|---|------|----|------|---|----|---|----|-----| -|OTEL_RESOURCE_ATTRIBUTES | + | + | + | + | + | + | - | + | + | + | - | -|OTEL_SERVICE_NAME | + | | | | | + | | | | + | | -|OTEL_LOG_LEVEL | - | - | + | [-][py1059] | + | - | - | | - | - | - | -|OTEL_PROPAGATORS | - | + | | + | + | + | - | - | - | - | - | -|OTEL_BSP_* | - | + | | + | + | + | - | + | - | - | - | -|OTEL_EXPORTER_OTLP_* | + | + | | + | + | + | - | + | + | + | - | -|OTEL_EXPORTER_JAEGER_* | + | | | | | - | - | | - | + | - | -|OTEL_EXPORTER_ZIPKIN_* | - | | | | | - | - | - | - | + | - | -|OTEL_TRACES_EXPORTER | - | + | | + | + | + | | - | - | - | | -|OTEL_METRICS_EXPORTER | - | + | | + | - | - | | - | - | - | - | -|OTEL_LOGS_EXPORTER | | | | | | | | | | - | | -|OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT | - | + | | + | + | + | | + | - | - | | -|OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT | | | | | | + | | | | - | | -|OTEL_SPAN_EVENT_COUNT_LIMIT | - | + | | + | + | + | | + | - | - | | -|OTEL_SPAN_LINK_COUNT_LIMIT | - | + | | + | + | + | | + | - | - | | -|OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT | | | | | | + | | | | - | | -|OTEL_LINK_ATTRIBUTE_COUNT_LIMIT | | | | | | + | | | | - | | -|OTEL_TRACES_SAMPLER | - | + | | + | + | + | | - | - | - | | -|OTEL_TRACES_SAMPLER_ARG | - | + | | + | + | + | | - | - | - | | -|OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT | | | | | | - | | | | - | | -|OTEL_ATTRIBUTE_COUNT_LIMIT | | | | | | - | | | | - | | -|OTEL_METRICS_EXEMPLAR_FILTER | | | | | | | | | | - | | +|Feature |Go |Java|JS |Python|Ruby|Erlang|PHP|Rust|C++|.NET|Swift| +|--------------------------------------------------|---|----|---|------|----|------|---|----|---|----|-----| +|OTEL_RESOURCE_ATTRIBUTES | + | + | + | + | + | + | - | + | + | + | - | +|OTEL_SERVICE_NAME | + | | | | | + | | | | + | | +|OTEL_LOG_LEVEL | - | - | + | [-][py1059] | + | - | - | | - | - | - | +|OTEL_PROPAGATORS | - | + | | + | + | + | - | - | - | - | - | +|OTEL_BSP_* | - | + | | + | + | + | - | + | - | - | - | +|OTEL_EXPORTER_OTLP_* | + | + | | + | + | + | - | + | + | + | - | +|OTEL_EXPORTER_JAEGER_* | + | | | | | - | - | | - | + | - | +|OTEL_EXPORTER_ZIPKIN_* | - | | | | | - | - | - | - | + | - | +|OTEL_TRACES_EXPORTER | - | + | | + | + | + | | - | - | - | | +|OTEL_METRICS_EXPORTER | - | + | | + | - | - | | - | - | - | - | +|OTEL_LOGS_EXPORTER | | | | | | | | | | - | | +|OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT | - | + | | + | + | + | | + | - | - | | +|OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT | | | | | | + | | | | - | | +|OTEL_SPAN_EVENT_COUNT_LIMIT | - | + | | + | + | + | | + | - | - | | +|OTEL_SPAN_LINK_COUNT_LIMIT | - | + | | + | + | + | | + | - | - | | +|OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT | | | | | | + | | | | - | | +|OTEL_LINK_ATTRIBUTE_COUNT_LIMIT | | | | | | + | | | | - | | +|OTEL_TRACES_SAMPLER | - | + | | + | + | + | | - | - | - | | +|OTEL_TRACES_SAMPLER_ARG | - | + | | + | + | + | | - | - | - | | +|OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT | | | | | | - | | | | - | | +|OTEL_ATTRIBUTE_COUNT_LIMIT | | | | | | - | | | | - | | +|OTEL_METRICS_EXEMPLAR_FILTER | | | | | | | | | | - | | +|OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE | | | | | | | | | | | | ## Exporters diff --git a/specification/metrics/sdk.md b/specification/metrics/sdk.md index cd9746c43a8..ad15f0050d6 100644 --- a/specification/metrics/sdk.md +++ b/specification/metrics/sdk.md @@ -180,10 +180,9 @@ are the inputs: will be used by default (TODO: once the Hint API is available, the default behavior should respect the Hint if it is available). * The `aggregation` (optional) to be used. If not provided, the SDK MUST - apply a [default aggregation](#default-aggregation). If the aggregation - outputs metric points that use aggregation temporality (e.g. Histogram, - Sum), the SDK SHOULD handle the aggregation temporality based on the - temporality of each [MetricReader](#metricreader) instance. + apply a [default aggregation](#default-aggregation) configurable on the + basis of instrument kind according to the [MetricReader](#metricreader) + instance. * The `exemplar_reservoir` (optional) to use for storing exemplars. This should be a factory or callback similar to aggregation which allows different reservoirs to be chosen by the aggregation. @@ -199,8 +198,10 @@ The SDK SHOULD use the following logic to determine how to process Measurements made with an Instrument: * Determine the `MeterProvider` which "owns" the Instrument. -* If the `MeterProvider` has no `View` registered, take the Instrument and apply - the default configuration. +* If the `MeterProvider` has no `View` registered, take the Instrument + and apply the default Aggregation on the basis of instrument kind + according to the [MetricReader](#metricreader) instance's + `aggregation` property. * If the `MeterProvider` has one or more `View`(s) registered: * For each View, if the Instrument could match the instrument selection criteria: @@ -215,7 +216,6 @@ made with an Instrument: Instrument will be ignored when there is no match). Individual implementations can decide what the default behavior is, and how to turn the default behavior off. -* END. Here are some examples: @@ -259,7 +259,7 @@ meter_provider # Counter X will be exported as cumulative sum meter_provider .add_view("X", aggregation=SumAggregation()) - .add_metric_reader(PeriodicExportingMetricReader(AggregationTemporality.CUMULATIVE, ConsoleExporter())) + .add_metric_reader(PeriodicExportingMetricReader(ConsoleExporter())) ``` ```python @@ -268,7 +268,8 @@ meter_provider meter_provider .add_view("X", aggregation=SumAggregation()) .add_view("*", attribute_keys=["a", "b"]) - .add_metric_reader(PeriodicExportingMetricReader(AggregationTemporality.DELTA, ConsoleExporter())) + .add_metric_reader(PeriodicExportingMetricReader(ConsoleExporter()), + temporality=lambda kind: Delta if kind in [Counter, AsyncCounter, Histogram] else Cumulative) ``` ### Aggregation @@ -634,12 +635,36 @@ measurements using the equivalent of the following naive algorithm: ## MetricReader -`MetricReader` is an interface which provides the following capabilities: +`MetricReader` is an SDK implementation object that provides the +common configurable aspects of the OpenTelemetry Metrics SDK and +determines the following capabilities: -* Collecting metrics from the SDK. +* Collecting metrics from the SDK on demand. * Handling the [ForceFlush](#forceflush) and [Shutdown](#shutdown) signals from the SDK. +To construct a `MetricReader` when setting up an SDK, the caller +SHOULD provide at least the following: + +* The `exporter` to use, which is a `MetricExporter` instance. +* The default output `aggregation` (optional), a function of instrument kind. If not configured, the [default aggregation](#default-aggregation) SHOULD be used. +* The default output `temporality` (optional), a function of instrument kind. If not configured, the Cumulative temporality SHOULD be used. + +The [MetricReader.Collect](#collect) method allows general-purpose +`MetricExporter` instances to explicitly initiate collection, commonly +used with pull-based metrics collection. A common sub-class of +`MetricReader`, the periodic exporting `MetricReader` SHOULD be provided +to be used typically with push-based metrics collection. + +The `MetricReader` MUST ensure that data points are output in the +configured aggregation temporality for each instrument kind. For +synchronous instruments being output with Cumulative temporality, this +means converting [Delta to Cumulative](supplementary-guidelines.md#synchronous-example-cumulative-aggregation-temporality) +aggregation temporality. For asynchronous instruments being output +with Delta temporality, this means converting [Cumulative to +Delta](supplementary-guidelines.md#asynchronous-example-delta-temporality) aggregation +temporality. + The SDK MUST support multiple `MetricReader` instances to be registered on the same `MeterProvider`, and the [MetricReader.Collect](#collect) invocation on one `MetricReader` instance SHOULD NOT introduce side-effects to other `MetricReader` @@ -672,26 +697,6 @@ The SDK SHOULD provide a way to allow `MetricReader` to respond to idiomatic approach, for example, as `OnForceFlush` and `OnShutdown` callback functions. -The SDK SHOULD provide a way to allow the preferred [Aggregation -Temporality](./datamodel.md#temporality) to be specified for a `MetricReader` -instance during the setup (e.g. initialization, registration, etc.) time. If the -preferred temporality is explicitly specified then the SDK SHOULD respect that, -otherwise use Cumulative. - -[OpenTelemetry SDK](../overview.md#sdk) -authors MAY choose the best idiomatic design for their language: - -* Whether to treat the temporality settings as recommendation or enforcement. - For example, if the temporality is set to Delta, would the SDK want to perform - Cumulative->Delta conversion for an [Asynchronous - Counter](./api.md#asynchronous-counter), or downgrade it to a - [Gauge](./datamodel.md#gauge), or keep consuming it as Cumulative due to the - consideration of [memory - efficiency](./supplementary-guidelines.md#memory-management)? -* Refer to the [supplementary - guidelines](./supplementary-guidelines.md#aggregation-temporality), which have - more context and suggestions. - ### MetricReader operations #### Collect @@ -736,7 +741,6 @@ a user-configurable time interval, and passes the metrics to the configured Configurable parameters: -* `exporter` - the push exporter where the metrics are sent to. * `exportIntervalMillis` - the time interval in milliseconds between two consecutive exports. The default value is 60000 (milliseconds). * `exportTimeoutMillis` - how long the export can run before it is cancelled. @@ -763,12 +767,22 @@ from `MetricReader` and start a background task which calls the inherited implement so that they can be plugged into OpenTelemetry SDK and support sending of telemetry data. +Metric Exporters always have an _associated_ MetricReader. The +`aggregation` and `temporality` properties used by the +OpenTelemetry Metric SDK are determined when registering Metric +Exporters through their associated MetricReader. OpenTelemetry +language implementations MAY support automatically configuring the +[MetricReader](#metricreader) to use for an Exporter. + The goal of the interface is to minimize burden of implementation for protocol-dependent telemetry exporters. The protocol exporter is expected to be primarily a simple telemetry data encoder and transmitter. Metric Exporter has access to the [aggregated metrics -data](./datamodel.md#timeseries-model). +data](./datamodel.md#timeseries-model). Metric Exporters SHOULD +report an error condition for data output by the `MetricReader` with +unsupported Aggregation or Aggregation Temporality, as this condition +can be corrected by a change of `MetricReader` configuration. There could be multiple [Push Metric Exporters](#push-metric-exporter) or [Pull Metric Exporters](#pull-metric-exporter) or even a mixture of both configured at @@ -781,9 +795,6 @@ can run at different schedule, for example: * Exporter D is a pull exporter which reacts to another scraper over a named pipe. -`MetricExporter` SHOULD provide a way to allow `MetricReader` to retrieve its -preferred temporality. - ### Push Metric Exporter Push Metric Exporter sends metric data it receives from a paired diff --git a/specification/metrics/sdk_exporters/in-memory.md b/specification/metrics/sdk_exporters/in-memory.md index f430429a48a..79baef7ab1e 100644 --- a/specification/metrics/sdk_exporters/in-memory.md +++ b/specification/metrics/sdk_exporters/in-memory.md @@ -6,16 +6,12 @@ In-memory Metrics Exporter is a [Push Metric Exporter](../sdk.md#push-metric-exporter) which accumulates metrics data in the local memory and allows to inspect it (useful for e.g. unit tests). -If a language provides a mechanism to automatically configure a -[MetricReader](../sdk.md#metricreader) to pair with the exporter (e.g., using -the -[`OTEL_METRICS_EXPORTER` environment variable](../../sdk-environment-variables.md#exporter-selection)), -by default the exporter MUST be paired with a -[periodic exporting MetricReader](../sdk.md#periodic-exporting-metricreader). - In-memory Metrics Exporter MUST support both Cumulative and Delta [Temporality](../datamodel.md#temporality). -In-memory Metrics Exporter MUST allow [Aggregation -Temporality](../datamodel.md#temporality) to be specified, as described in -[MetricExporter](../sdk.md#metricexporter). +If a language provides a mechanism to automatically configure a +[MetricReader](../sdk.md#metricreader) to pair with the associated +exporter (e.g., using the [`OTEL_METRICS_EXPORTER` environment +variable](../../sdk-environment-variables.md#exporter-selection)), by +default the exporter MUST be paired with a [periodic exporting +MetricReader](../sdk.md#periodic-exporting-metricreader). diff --git a/specification/metrics/sdk_exporters/otlp.md b/specification/metrics/sdk_exporters/otlp.md index 68dab51e3a1..0f6682ab8dc 100644 --- a/specification/metrics/sdk_exporters/otlp.md +++ b/specification/metrics/sdk_exporters/otlp.md @@ -6,31 +6,31 @@ OTLP Metrics Exporter is a [Push Metric Exporter](../sdk.md#push-metric-exporter) which sends metrics via the [OpenTelemetry Protocol](../../protocol/README.md). -If a language provides a mechanism to automatically configure a -[MetricReader](../sdk.md#metricreader) to pair with the exporter (e.g., using -the -[`OTEL_METRICS_EXPORTER` environment variable](../../sdk-environment-variables.md#exporter-selection)), -by default the exporter MUST be paired with a -[periodic exporting MetricReader](../sdk.md#periodic-exporting-metricreader). - OTLP Metrics Exporter MUST support both Cumulative and Delta -[Temporality](../datamodel.md#temporality). - -OTLP Metrics Exporter MUST allow [Aggregation -Temporality](../datamodel.md#temporality) to be specified, as described in -[MetricExporter](../sdk.md#metricexporter). - -If the temporality is not specified, OTLP Metrics Exporter SHOULD use Cumulative -as the default temporality. +[Aggregation Temporality](../datamodel.md#temporality). The exporter MUST provide configuration according to the [OpenTelemetry Protocol Exporter](../../protocol/exporter.md) specification. -In addition, the exporter MUST provide the following configuration (note: this -section will be merged to the [OpenTelemetry Protocol -Exporter](../../protocol/exporter.md) specification once it reaches -[Stable](../../document-status.md)): - -| Description | Default | Env variable | -| ----------- | ------- | ------------ | -| The preferred output [Aggregation Temporality](../datamodel.md#temporality), either `CUMULATIVE` or `DELTA` (case insensitive) | `CUMULATIVE` | `OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY` +If a language provides a mechanism to automatically configure a +[MetricReader](../sdk.md#metricreader) to pair with the associated +Exporter (e.g., using the [`OTEL_METRICS_EXPORTER` environment +variable](../../sdk-environment-variables.md#exporter-selection)), +then by default: + +* The exporter MUST be paired with a [periodic exporting +MetricReader](../sdk.md#periodic-exporting-metricreader). +* The exporter MUST configure the default aggregation temporality on the + basis of instrument kind using the + `OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE` variable as described + below, otherwise the exporter MUST use Cumulative as the default + aggregation temporality for all instrument kinds. + +The `OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE` environment variable +defines the default aggregation temporality policy +to use on the basis of instrument kind. The recognized (case-insensitive) values are: + +| Value | Definition | +|------------|---------------------------------------------------------------------------------------------------------------| +| CUMULATIVE | Choose Cumulative aggregation temporality for all instrument kinds. | +| DELTA | Choose Delta aggregation temporality for Counter, Asynchronous Counter and Histogram instrument kinds, choose Cumulative aggregation temporality for UpDownCounter and Asynchronous UpDownCounter instrument kinds. | diff --git a/specification/metrics/sdk_exporters/stdout.md b/specification/metrics/sdk_exporters/stdout.md index 6a41145de4f..1dc187cb18a 100644 --- a/specification/metrics/sdk_exporters/stdout.md +++ b/specification/metrics/sdk_exporters/stdout.md @@ -6,13 +6,6 @@ Exporter](../sdk.md#push-metric-exporter) which outputs the metrics to stdout/console. -If a language provides a mechanism to automatically configure a -[MetricReader](../sdk.md#metricreader) to pair with the exporter (e.g., using -the -[`OTEL_METRICS_EXPORTER` environment variable](../../sdk-environment-variables.md#exporter-selection)), -by default the exporter MUST be paired with a -[periodic exporting MetricReader](../sdk.md#periodic-exporting-metricreader). - [OpenTelemetry SDK](../../overview.md#sdk) authors MAY choose the best idiomatic name for their language. For example, ConsoleExporter, StdoutExporter, StreamExporter, etc. @@ -20,6 +13,9 @@ StreamExporter, etc. "Standard output" Metrics Exporter MUST support both Cumulative and Delta [Temporality](../datamodel.md#temporality). -"Standard output" Metrics Exporter MUST allow [Aggregation -Temporality](../datamodel.md#temporality) to be specified, as described in -[MetricExporter](../sdk.md#metricexporter). +If a language provides a mechanism to automatically configure a +[MetricReader](../sdk.md#metricreader) to pair with the associated +exporter (e.g., using the [`OTEL_METRICS_EXPORTER` environment +variable](../../sdk-environment-variables.md#exporter-selection)), by +default the exporter MUST be paired with a [periodic exporting +MetricReader](../sdk.md#periodic-exporting-metricreader). diff --git a/specification/metrics/supplementary-guidelines.md b/specification/metrics/supplementary-guidelines.md index c7e08f5287e..f2e876d0047 100644 --- a/specification/metrics/supplementary-guidelines.md +++ b/specification/metrics/supplementary-guidelines.md @@ -406,8 +406,6 @@ temporality. For example: So here are some suggestions that we encourage SDK implementers to consider: -* You probably don't want to encourage your users to do Cumulative->Delta - conversion. Actually, you might want to discourage them from doing this. * If you have to do Cumulative->Delta conversion, and you encountered min/max, rather than drop the data on the floor, you might want to convert them to something useful - e.g. [Gauge](./datamodel.md#gauge).