From 4c3cf026f81064e8a74a211e927cc4c194760eb0 Mon Sep 17 00:00:00 2001 From: David Ashpole Date: Wed, 18 Mar 2026 20:35:12 +0000 Subject: [PATCH 01/12] Prometheus: Stabililze OpenTelemetry Exemplar to Prometheus Exemplar --- CHANGELOG.md | 2 + .../prometheus_and_openmetrics.md | 40 ++++++++++++------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f27c51511f..97775bfe2f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,8 @@ release. ([#4952](https://github.com/open-telemetry/opentelemetry-specification/pull/4952)) - Stabilize OpenTelemetry Attributes to Prometheus labels transformation. ([#4963](https://github.com/open-telemetry/opentelemetry-specification/pull/4963)) +- Stabilize OpenTelemetry Exemplar to Prometheus Exemplar transformation. + ([#4964](https://github.com/open-telemetry/opentelemetry-specification/pull/4964)) ### SDK Configuration diff --git a/specification/compatibility/prometheus_and_openmetrics.md b/specification/compatibility/prometheus_and_openmetrics.md index e36b38ef9fe..60ee177d66c 100644 --- a/specification/compatibility/prometheus_and_openmetrics.md +++ b/specification/compatibility/prometheus_and_openmetrics.md @@ -447,6 +447,10 @@ to a Prometheus Gauge. If the metric name for monotonic Sum metric points does not end in a suffix of `_total` a suffix of `_total` SHOULD be added by default, otherwise the name MUST remain unchanged. Exporters SHOULD provide a configuration option to disable the addition of `_total` suffixes. Monotonic Sum metric points with `StartTimeUnixNano` should export the `{name}_created` metric as well. +`Exemplars` are converted as described in the [Exemplars](#exemplars-1) section. +If the Prometheus protocol only supports a single exemplar on the Sum, a random +exemplar SHOULD be converted. + ### Histograms **Status**: [Development](../document-status.md) @@ -458,6 +462,12 @@ An [OpenTelemetry Histogram](../metrics/data-model.md#histogram) with a cumulati - A series of `{name}_bucket` metric points that contain all attributes of the histogram point recorded as labels. Additionally, a label, denoted as `le` is added denoting the bucket boundary. The label's value is the stringified floating point value of bucket boundaries, ordered from lowest to highest. The value of each point is the sum of the count of all histogram buckets up to the boundary reported in the `le` label. These points will include a single exemplar that falls within `le` label and no other `le` labelled point. The final bucket metric MUST have an `+Inf` threshold. - Histograms with `StartTimeUnixNano` set should export the `{name}_created` metric as well. +`Exemplars` are converted as described in the [Exemplars](#exemplars-1) section. +If the Prometheus protocol supports a single exemplar per-bucket: +- The largest exemplar that falls into each bucket MUST be converted. +- If no exemplars exist on a bucket, the highest exemplar from a lower bucket + MUST be used, even though it is duplicated. + OpenTelemetry Histograms with Delta aggregation temporality SHOULD be aggregated into a Cumulative aggregation temporality and follow the logic above, or MUST be dropped. ### Exponential Histograms @@ -493,6 +503,7 @@ Histogram as follows: result being that the Offset fields are different-by-one. - `Min` and `Max` are not used. - `StartTimeUnixNano` is not used. +- `Exemplars` are converted as described in the [Exemplars](#exemplars-1) section. [OpenTelemetry Exponential Histogram](../metrics/data-model.md#exponentialhistogram) metrics with the delta aggregation temporality are dropped. @@ -535,21 +546,22 @@ separated by `;`, and ordered by the lexicographical order of the original keys. ### Exemplars -**Status**: [Development](../document-status.md) +**Status**: [Stable](../document-status.md) -[Exemplars](../metrics/data-model.md#exemplars) on OpenTelemetry Histograms and Monotonic Sums SHOULD -be converted to Prometheus exemplars. Exemplars on other OpenTelemetry data -points MUST be dropped. For Prometheus Remote Write exporters, multiple exemplars are -able to be added to each bucket, so all exemplars SHOULD be converted. For -Prometheus pull endpoints, only a single exemplar is able to be added to each -bucket, so the largest exemplar from each bucket MUST be used, if attaching -exemplars. If no exemplars exist on a bucket, the highest exemplar from a lower -bucket MUST be used, even though it is a duplicate of another bucket's exemplar. -Prometheus Exemplars MUST use the `trace_id` and `span_id` keys for the trace -and span IDs, respectively. Timestamps MUST be added as timestamps on the -Prometheus exemplar, and `filtered_attributes` MUST be added as labels on the -Prometheus exemplar unless they would exceed the -[limit on characters](https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#exemplars). +[OpenTelemetry Exemplars](../metrics/data-model.md#exemplars) MUST be converted +to Prometheus exemplars if the Prometheus (push or pull) protocol being used +supports them as follows: + +* If present, the OpenTelemetry Exemplar's Trace ID and Span ID MUST be added as + Exemplar labels using the `trace_id` and `span_id` keys, respectively. These + labels MUST take precedence over labels from `filtered_attributes` in cases + where there is a key collision. `trace_id` and `span_id` SHOULD be preserved + over labels from `filtered_attributes` when exemplar label limits are exceeded. +* Timestamps MUST be added as timestamps on the Prometheus exemplar. +* `filtered_attributes` MUST be added as labels on the Prometheus exemplar, + unless they would exceed the Prometheus protocol's exemplar limits. For + example, OpenMetrics 1.0 imposes a + [128 character limit](https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#exemplar). ### Resource Attributes From 8da81b2e7fcd54b61c86bd83d8f08cd82dca94ea Mon Sep 17 00:00:00 2001 From: David Ashpole Date: Fri, 3 Apr 2026 19:50:29 +0000 Subject: [PATCH 02/12] omit exemplars from lower buckets, and remove language about key preservation --- .../compatibility/prometheus_and_openmetrics.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/specification/compatibility/prometheus_and_openmetrics.md b/specification/compatibility/prometheus_and_openmetrics.md index 60ee177d66c..79b372813f7 100644 --- a/specification/compatibility/prometheus_and_openmetrics.md +++ b/specification/compatibility/prometheus_and_openmetrics.md @@ -463,10 +463,8 @@ An [OpenTelemetry Histogram](../metrics/data-model.md#histogram) with a cumulati - Histograms with `StartTimeUnixNano` set should export the `{name}_created` metric as well. `Exemplars` are converted as described in the [Exemplars](#exemplars-1) section. -If the Prometheus protocol supports a single exemplar per-bucket: -- The largest exemplar that falls into each bucket MUST be converted. -- If no exemplars exist on a bucket, the highest exemplar from a lower bucket - MUST be used, even though it is duplicated. +If the Prometheus protocol supports a single exemplar per-bucket, the latest +exemplar that falls into each bucket MUST be converted. OpenTelemetry Histograms with Delta aggregation temporality SHOULD be aggregated into a Cumulative aggregation temporality and follow the logic above, or MUST be dropped. @@ -555,8 +553,7 @@ supports them as follows: * If present, the OpenTelemetry Exemplar's Trace ID and Span ID MUST be added as Exemplar labels using the `trace_id` and `span_id` keys, respectively. These labels MUST take precedence over labels from `filtered_attributes` in cases - where there is a key collision. `trace_id` and `span_id` SHOULD be preserved - over labels from `filtered_attributes` when exemplar label limits are exceeded. + where there is a key collision. * Timestamps MUST be added as timestamps on the Prometheus exemplar. * `filtered_attributes` MUST be added as labels on the Prometheus exemplar, unless they would exceed the Prometheus protocol's exemplar limits. For From fa888571b3b963cfb62d0ebd8f30a57f17e72143 Mon Sep 17 00:00:00 2001 From: David Ashpole Date: Mon, 6 Apr 2026 13:13:59 -0400 Subject: [PATCH 03/12] Apply suggestions from code review Co-authored-by: Arve Knudsen --- .../compatibility/prometheus_and_openmetrics.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/specification/compatibility/prometheus_and_openmetrics.md b/specification/compatibility/prometheus_and_openmetrics.md index 79b372813f7..1c83c215b91 100644 --- a/specification/compatibility/prometheus_and_openmetrics.md +++ b/specification/compatibility/prometheus_and_openmetrics.md @@ -447,7 +447,7 @@ to a Prometheus Gauge. If the metric name for monotonic Sum metric points does not end in a suffix of `_total` a suffix of `_total` SHOULD be added by default, otherwise the name MUST remain unchanged. Exporters SHOULD provide a configuration option to disable the addition of `_total` suffixes. Monotonic Sum metric points with `StartTimeUnixNano` should export the `{name}_created` metric as well. -`Exemplars` are converted as described in the [Exemplars](#exemplars-1) section. +`Exemplars` are converted as described in the [Exemplar Conversion](#exemplar-conversion) section. If the Prometheus protocol only supports a single exemplar on the Sum, a random exemplar SHOULD be converted. @@ -462,8 +462,8 @@ An [OpenTelemetry Histogram](../metrics/data-model.md#histogram) with a cumulati - A series of `{name}_bucket` metric points that contain all attributes of the histogram point recorded as labels. Additionally, a label, denoted as `le` is added denoting the bucket boundary. The label's value is the stringified floating point value of bucket boundaries, ordered from lowest to highest. The value of each point is the sum of the count of all histogram buckets up to the boundary reported in the `le` label. These points will include a single exemplar that falls within `le` label and no other `le` labelled point. The final bucket metric MUST have an `+Inf` threshold. - Histograms with `StartTimeUnixNano` set should export the `{name}_created` metric as well. -`Exemplars` are converted as described in the [Exemplars](#exemplars-1) section. -If the Prometheus protocol supports a single exemplar per-bucket, the latest +`Exemplars` are converted as described in the [Exemplar Conversion](#exemplar-conversion) section. +If the Prometheus protocol only supports a single exemplar per-bucket, the latest exemplar that falls into each bucket MUST be converted. OpenTelemetry Histograms with Delta aggregation temporality SHOULD be aggregated into a Cumulative aggregation temporality and follow the logic above, or MUST be dropped. @@ -501,7 +501,7 @@ Histogram as follows: result being that the Offset fields are different-by-one. - `Min` and `Max` are not used. - `StartTimeUnixNano` is not used. -- `Exemplars` are converted as described in the [Exemplars](#exemplars-1) section. +- `Exemplars` are converted as described in the [Exemplar Conversion](#exemplar-conversion) section. [OpenTelemetry Exponential Histogram](../metrics/data-model.md#exponentialhistogram) metrics with the delta aggregation temporality are dropped. @@ -542,7 +542,7 @@ added by this specification, may cause different OpenTelemetry keys to map to the same Prometheus key. In such cases, the values MUST be concatenated together, separated by `;`, and ordered by the lexicographical order of the original keys. -### Exemplars +### Exemplar Conversion **Status**: [Stable](../document-status.md) From ec9db372351e3dafaacb2b7c959b755ea3fae1a2 Mon Sep 17 00:00:00 2001 From: David Ashpole Date: Tue, 7 Apr 2026 14:29:47 -0400 Subject: [PATCH 04/12] Apply suggestion from @aknuds1 Co-authored-by: Arve Knudsen --- specification/compatibility/prometheus_and_openmetrics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/compatibility/prometheus_and_openmetrics.md b/specification/compatibility/prometheus_and_openmetrics.md index 1c83c215b91..56bc8690315 100644 --- a/specification/compatibility/prometheus_and_openmetrics.md +++ b/specification/compatibility/prometheus_and_openmetrics.md @@ -459,7 +459,7 @@ An [OpenTelemetry Histogram](../metrics/data-model.md#histogram) with a cumulati - A single `{name}_count` metric denoting the count field of the histogram. All attributes of the histogram point are converted to Prometheus labels. - `{name}_sum` metric denoting the sum field of the histogram, reported only if the sum is positive and monotonic. The sum is positive and monotonic when all buckets are positive. All attributes of the histogram point are converted to Prometheus labels. -- A series of `{name}_bucket` metric points that contain all attributes of the histogram point recorded as labels. Additionally, a label, denoted as `le` is added denoting the bucket boundary. The label's value is the stringified floating point value of bucket boundaries, ordered from lowest to highest. The value of each point is the sum of the count of all histogram buckets up to the boundary reported in the `le` label. These points will include a single exemplar that falls within `le` label and no other `le` labelled point. The final bucket metric MUST have an `+Inf` threshold. +- A series of `{name}_bucket` metric points that contain all attributes of the histogram point recorded as labels. Additionally, a label, denoted as `le` is added denoting the bucket boundary. The label's value is the stringified floating point value of bucket boundaries, ordered from lowest to highest. The value of each point is the sum of the count of all histogram buckets up to the boundary reported in the `le` label. The final bucket metric MUST have an `+Inf` threshold. - Histograms with `StartTimeUnixNano` set should export the `{name}_created` metric as well. `Exemplars` are converted as described in the [Exemplar Conversion](#exemplar-conversion) section. From 75ffe03b5a0aaeaed407aafc4834f0177ce069a1 Mon Sep 17 00:00:00 2001 From: David Ashpole Date: Tue, 7 Apr 2026 18:53:56 +0000 Subject: [PATCH 05/12] fix links --- spec-compliance-matrix.md | 2 +- specification/compatibility/prometheus_and_openmetrics.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec-compliance-matrix.md b/spec-compliance-matrix.md index a7eebd23540..1256c7ed7ce 100644 --- a/spec-compliance-matrix.md +++ b/spec-compliance-matrix.md @@ -372,7 +372,7 @@ Disclaimer: Declarative configuration is currently in Development status - work | [Delta Histograms become Cumulative Prometheus Histograms](specification/compatibility/prometheus_and_openmetrics.md#histograms-1) | X | - | - | - | - | - | - | - | - | - | - | - | - | | [Attributes Keys are Sanitized](specification/compatibility/prometheus_and_openmetrics.md#metric-attributes) | | + | + | + | + | - | - | - | + | + | + | + | - | | [Colliding sanitized attribute keys are merged](specification/compatibility/prometheus_and_openmetrics.md#metric-attributes) | | + | + | - | - | - | - | - | + | - | - | - | - | -| [Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplars-1) | X | + | - | - | - | - | - | - | - | - | - | - | - | +| [Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplar-conversion) | X | + | - | - | - | - | - | - | - | - | - | - | - | | [`target_info` metric from Resource](specification/compatibility/prometheus_and_openmetrics.md#resource-attributes-1) | X | + | + | + | + | - | - | - | + | - | - | - | - | ## OpenCensus Compatibility diff --git a/specification/compatibility/prometheus_and_openmetrics.md b/specification/compatibility/prometheus_and_openmetrics.md index 56bc8690315..c3c7a749bc6 100644 --- a/specification/compatibility/prometheus_and_openmetrics.md +++ b/specification/compatibility/prometheus_and_openmetrics.md @@ -39,7 +39,7 @@ aliases: * [Exponential Histograms](#exponential-histograms) * [Summaries](#summaries-1) * [Metric Attributes](#metric-attributes) - * [Exemplars](#exemplars-1) + * [Exemplar Conversion](#exemplar-conversion) * [Resource Attributes](#resource-attributes-1) From 1ce111950b236b465c4e75f082d0da6089958474 Mon Sep 17 00:00:00 2001 From: David Ashpole Date: Tue, 7 Apr 2026 19:01:11 +0000 Subject: [PATCH 06/12] clarify when exemplars are dropped --- .../compatibility/prometheus_and_openmetrics.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/specification/compatibility/prometheus_and_openmetrics.md b/specification/compatibility/prometheus_and_openmetrics.md index c3c7a749bc6..d599e3c33eb 100644 --- a/specification/compatibility/prometheus_and_openmetrics.md +++ b/specification/compatibility/prometheus_and_openmetrics.md @@ -427,6 +427,8 @@ a Prometheus Unknown-typed metric if the `prometheus.type` key of [metric.metadata][metricMetadata] is `unknown`. Otherwise, it MUST be converted to a Prometheus Gauge. +Exemplars on OpenTelemetry Gauges SHOULD be dropped. + ### Sums **Status**: [Development](../document-status.md) @@ -447,9 +449,11 @@ to a Prometheus Gauge. If the metric name for monotonic Sum metric points does not end in a suffix of `_total` a suffix of `_total` SHOULD be added by default, otherwise the name MUST remain unchanged. Exporters SHOULD provide a configuration option to disable the addition of `_total` suffixes. Monotonic Sum metric points with `StartTimeUnixNano` should export the `{name}_created` metric as well. -`Exemplars` are converted as described in the [Exemplar Conversion](#exemplar-conversion) section. -If the Prometheus protocol only supports a single exemplar on the Sum, a random -exemplar SHOULD be converted. +If Sum is converted to a Prometheus Counter, then `Exemplars` MUST be converted +as described in the [Exemplar Conversion](#exemplar-conversion) section. +Otherwise, `Exemplars` SHOULD be dropped. If the Prometheus protocol only +supports a single exemplar on the Counter sample, a random exemplar SHOULD be +converted. ### Histograms @@ -525,6 +529,8 @@ An [OpenTelemetry Summary](../metrics/data-model.md#summary-legacy) MUST be conv each point is the computed value of the quantile point. - Summaries with `StartTimeUnixNano` set should export the `{name}_created` metric as well. +Exemplars on OpenTelemetry Summaries SHOULD be dropped. + ### Metric Attributes **Status**: [Stable](../document-status.md) From 19515b06544d9aef3992a9f47575e9e855b09105 Mon Sep 17 00:00:00 2001 From: David Ashpole Date: Wed, 8 Apr 2026 16:25:32 +0000 Subject: [PATCH 07/12] fix links --- spec-compliance-matrix/cpp.yaml | 2 +- spec-compliance-matrix/dotnet.yaml | 2 +- spec-compliance-matrix/erlang.yaml | 2 +- spec-compliance-matrix/go.yaml | 2 +- spec-compliance-matrix/java.yaml | 2 +- spec-compliance-matrix/js.yaml | 2 +- spec-compliance-matrix/kotlin.yaml | 2 +- spec-compliance-matrix/php.yaml | 2 +- spec-compliance-matrix/python.yaml | 2 +- spec-compliance-matrix/ruby.yaml | 2 +- spec-compliance-matrix/rust.yaml | 2 +- spec-compliance-matrix/swift.yaml | 2 +- spec-compliance-matrix/template.yaml | 2 +- specification/compatibility/prometheus_and_openmetrics.md | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/spec-compliance-matrix/cpp.yaml b/spec-compliance-matrix/cpp.yaml index a468cb9c87c..20808ee4576 100644 --- a/spec-compliance-matrix/cpp.yaml +++ b/spec-compliance-matrix/cpp.yaml @@ -655,7 +655,7 @@ sections: status: '+' - name: '[Colliding sanitized attribute keys are merged](specification/compatibility/prometheus_and_openmetrics.md#metric-attributes)' status: '-' - - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplars-1)' + - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplar-conversion)' status: '-' - name: '[`target_info` metric from Resource](specification/compatibility/prometheus_and_openmetrics.md#resource-attributes-1)' status: '-' diff --git a/spec-compliance-matrix/dotnet.yaml b/spec-compliance-matrix/dotnet.yaml index 1da19bc2c17..69c691a1369 100644 --- a/spec-compliance-matrix/dotnet.yaml +++ b/spec-compliance-matrix/dotnet.yaml @@ -655,7 +655,7 @@ sections: status: '+' - name: '[Colliding sanitized attribute keys are merged](specification/compatibility/prometheus_and_openmetrics.md#metric-attributes)' status: '-' - - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplars-1)' + - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplar-conversion)' status: '-' - name: '[`target_info` metric from Resource](specification/compatibility/prometheus_and_openmetrics.md#resource-attributes-1)' status: '-' diff --git a/spec-compliance-matrix/erlang.yaml b/spec-compliance-matrix/erlang.yaml index 44ea8d19c42..05345966b7c 100644 --- a/spec-compliance-matrix/erlang.yaml +++ b/spec-compliance-matrix/erlang.yaml @@ -655,7 +655,7 @@ sections: status: '-' - name: '[Colliding sanitized attribute keys are merged](specification/compatibility/prometheus_and_openmetrics.md#metric-attributes)' status: '-' - - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplars-1)' + - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplar-conversion)' status: '-' - name: '[`target_info` metric from Resource](specification/compatibility/prometheus_and_openmetrics.md#resource-attributes-1)' status: '-' diff --git a/spec-compliance-matrix/go.yaml b/spec-compliance-matrix/go.yaml index 5b2ba48f343..fbc414a43c9 100644 --- a/spec-compliance-matrix/go.yaml +++ b/spec-compliance-matrix/go.yaml @@ -655,7 +655,7 @@ sections: status: '+' - name: '[Colliding sanitized attribute keys are merged](specification/compatibility/prometheus_and_openmetrics.md#metric-attributes)' status: '+' - - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplars-1)' + - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplar-conversion)' status: '+' - name: '[`target_info` metric from Resource](specification/compatibility/prometheus_and_openmetrics.md#resource-attributes-1)' status: '+' diff --git a/spec-compliance-matrix/java.yaml b/spec-compliance-matrix/java.yaml index d82904aa7ba..90016ef9020 100644 --- a/spec-compliance-matrix/java.yaml +++ b/spec-compliance-matrix/java.yaml @@ -655,7 +655,7 @@ sections: status: '+' - name: '[Colliding sanitized attribute keys are merged](specification/compatibility/prometheus_and_openmetrics.md#metric-attributes)' status: '+' - - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplars-1)' + - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplar-conversion)' status: '-' - name: '[`target_info` metric from Resource](specification/compatibility/prometheus_and_openmetrics.md#resource-attributes-1)' status: '+' diff --git a/spec-compliance-matrix/js.yaml b/spec-compliance-matrix/js.yaml index 70850b3f12b..ced63d7f181 100644 --- a/spec-compliance-matrix/js.yaml +++ b/spec-compliance-matrix/js.yaml @@ -655,7 +655,7 @@ sections: status: '+' - name: '[Colliding sanitized attribute keys are merged](specification/compatibility/prometheus_and_openmetrics.md#metric-attributes)' status: '-' - - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplars-1)' + - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplar-conversion)' status: '-' - name: '[`target_info` metric from Resource](specification/compatibility/prometheus_and_openmetrics.md#resource-attributes-1)' status: '+' diff --git a/spec-compliance-matrix/kotlin.yaml b/spec-compliance-matrix/kotlin.yaml index 6ba4ebec682..3bc72be8bde 100644 --- a/spec-compliance-matrix/kotlin.yaml +++ b/spec-compliance-matrix/kotlin.yaml @@ -655,7 +655,7 @@ sections: status: '-' - name: '[Colliding sanitized attribute keys are merged](specification/compatibility/prometheus_and_openmetrics.md#metric-attributes)' status: '-' - - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplars-1)' + - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplar-conversion)' status: '-' - name: '[`target_info` metric from Resource](specification/compatibility/prometheus_and_openmetrics.md#resource-attributes-1)' status: '-' diff --git a/spec-compliance-matrix/php.yaml b/spec-compliance-matrix/php.yaml index 31df84ceb71..ecb87bcb088 100644 --- a/spec-compliance-matrix/php.yaml +++ b/spec-compliance-matrix/php.yaml @@ -655,7 +655,7 @@ sections: status: '-' - name: '[Colliding sanitized attribute keys are merged](specification/compatibility/prometheus_and_openmetrics.md#metric-attributes)' status: '-' - - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplars-1)' + - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplar-conversion)' status: '-' - name: '[`target_info` metric from Resource](specification/compatibility/prometheus_and_openmetrics.md#resource-attributes-1)' status: '-' diff --git a/spec-compliance-matrix/python.yaml b/spec-compliance-matrix/python.yaml index 78b1348a83d..443e480dc56 100644 --- a/spec-compliance-matrix/python.yaml +++ b/spec-compliance-matrix/python.yaml @@ -655,7 +655,7 @@ sections: status: '+' - name: '[Colliding sanitized attribute keys are merged](specification/compatibility/prometheus_and_openmetrics.md#metric-attributes)' status: '-' - - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplars-1)' + - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplar-conversion)' status: '-' - name: '[`target_info` metric from Resource](specification/compatibility/prometheus_and_openmetrics.md#resource-attributes-1)' status: '+' diff --git a/spec-compliance-matrix/ruby.yaml b/spec-compliance-matrix/ruby.yaml index 3b9616b2755..0cc92480e5e 100644 --- a/spec-compliance-matrix/ruby.yaml +++ b/spec-compliance-matrix/ruby.yaml @@ -655,7 +655,7 @@ sections: status: '-' - name: '[Colliding sanitized attribute keys are merged](specification/compatibility/prometheus_and_openmetrics.md#metric-attributes)' status: '-' - - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplars-1)' + - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplar-conversion)' status: '-' - name: '[`target_info` metric from Resource](specification/compatibility/prometheus_and_openmetrics.md#resource-attributes-1)' status: '-' diff --git a/spec-compliance-matrix/rust.yaml b/spec-compliance-matrix/rust.yaml index f987489ce78..d493f22d96e 100644 --- a/spec-compliance-matrix/rust.yaml +++ b/spec-compliance-matrix/rust.yaml @@ -655,7 +655,7 @@ sections: status: '+' - name: '[Colliding sanitized attribute keys are merged](specification/compatibility/prometheus_and_openmetrics.md#metric-attributes)' status: '+' - - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplars-1)' + - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplar-conversion)' status: '-' - name: '[`target_info` metric from Resource](specification/compatibility/prometheus_and_openmetrics.md#resource-attributes-1)' status: '+' diff --git a/spec-compliance-matrix/swift.yaml b/spec-compliance-matrix/swift.yaml index e1a0596503a..bdd8ac6d62d 100644 --- a/spec-compliance-matrix/swift.yaml +++ b/spec-compliance-matrix/swift.yaml @@ -655,7 +655,7 @@ sections: status: '+' - name: '[Colliding sanitized attribute keys are merged](specification/compatibility/prometheus_and_openmetrics.md#metric-attributes)' status: '-' - - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplars-1)' + - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplar-conversion)' status: '-' - name: '[`target_info` metric from Resource](specification/compatibility/prometheus_and_openmetrics.md#resource-attributes-1)' status: '-' diff --git a/spec-compliance-matrix/template.yaml b/spec-compliance-matrix/template.yaml index 18aa739c52d..9c5cd9fb97d 100644 --- a/spec-compliance-matrix/template.yaml +++ b/spec-compliance-matrix/template.yaml @@ -427,7 +427,7 @@ sections: optional: true - name: '[Attributes Keys are Sanitized](specification/compatibility/prometheus_and_openmetrics.md#metric-attributes)' - name: '[Colliding sanitized attribute keys are merged](specification/compatibility/prometheus_and_openmetrics.md#metric-attributes)' - - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplars-1)' + - name: '[Exemplars for Histograms and Monotonic sums](specification/compatibility/prometheus_and_openmetrics.md#exemplar-conversion)' optional: true - name: '[`target_info` metric from Resource](specification/compatibility/prometheus_and_openmetrics.md#resource-attributes-1)' optional: true diff --git a/specification/compatibility/prometheus_and_openmetrics.md b/specification/compatibility/prometheus_and_openmetrics.md index d599e3c33eb..9baba1e4045 100644 --- a/specification/compatibility/prometheus_and_openmetrics.md +++ b/specification/compatibility/prometheus_and_openmetrics.md @@ -564,7 +564,7 @@ supports them as follows: * `filtered_attributes` MUST be added as labels on the Prometheus exemplar, unless they would exceed the Prometheus protocol's exemplar limits. For example, OpenMetrics 1.0 imposes a - [128 character limit](https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#exemplar). + [128 character limit](https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#exemplars). ### Resource Attributes From 364d61a599d1f333de42c69bc898bef15c6d7bfb Mon Sep 17 00:00:00 2001 From: David Ashpole Date: Fri, 10 Apr 2026 11:28:03 -0400 Subject: [PATCH 08/12] Apply suggestion from @dashpole --- specification/compatibility/prometheus_and_openmetrics.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/specification/compatibility/prometheus_and_openmetrics.md b/specification/compatibility/prometheus_and_openmetrics.md index da3baacdd28..2af5ae317a8 100644 --- a/specification/compatibility/prometheus_and_openmetrics.md +++ b/specification/compatibility/prometheus_and_openmetrics.md @@ -491,7 +491,8 @@ If Sum is converted to a Prometheus Counter, then `Exemplars` MUST be converted as described in the [Exemplar Conversion](#exemplar-conversion) section. Otherwise, `Exemplars` SHOULD be dropped. If the Prometheus protocol only supports a single exemplar on the Counter sample, a random exemplar SHOULD be -converted. +converted. This matches the behavior of prometheus client libraries, which is to keep the +latest exemplar for counter instruments. ### Histograms From 66be926e5653f1560c897e47833a958a7f10038e Mon Sep 17 00:00:00 2001 From: David Ashpole Date: Fri, 10 Apr 2026 11:28:35 -0400 Subject: [PATCH 09/12] Apply suggestion from @dashpole --- specification/compatibility/prometheus_and_openmetrics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/compatibility/prometheus_and_openmetrics.md b/specification/compatibility/prometheus_and_openmetrics.md index 2af5ae317a8..e820afb581a 100644 --- a/specification/compatibility/prometheus_and_openmetrics.md +++ b/specification/compatibility/prometheus_and_openmetrics.md @@ -490,7 +490,7 @@ Monotonic Sum metric points with `StartTimeUnixNano` should export the `{name}_c If Sum is converted to a Prometheus Counter, then `Exemplars` MUST be converted as described in the [Exemplar Conversion](#exemplar-conversion) section. Otherwise, `Exemplars` SHOULD be dropped. If the Prometheus protocol only -supports a single exemplar on the Counter sample, a random exemplar SHOULD be +supports a single exemplar on the Counter sample, the latest exemplar SHOULD be converted. This matches the behavior of prometheus client libraries, which is to keep the latest exemplar for counter instruments. From 132d80dc4c11c5e1b839f506131574c81b53745e Mon Sep 17 00:00:00 2001 From: David Ashpole Date: Fri, 10 Apr 2026 13:18:06 -0400 Subject: [PATCH 10/12] Apply suggestion from @dashpole --- specification/compatibility/prometheus_and_openmetrics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/compatibility/prometheus_and_openmetrics.md b/specification/compatibility/prometheus_and_openmetrics.md index d3d5eef9c49..81455e79b5c 100644 --- a/specification/compatibility/prometheus_and_openmetrics.md +++ b/specification/compatibility/prometheus_and_openmetrics.md @@ -497,7 +497,7 @@ If Sum is converted to a Prometheus Counter, then `Exemplars` MUST be converted as described in the [Exemplar Conversion](#exemplar-conversion) section. Otherwise, `Exemplars` SHOULD be dropped. If the Prometheus protocol only supports a single exemplar on the Counter sample, the latest exemplar SHOULD be -converted. This matches the behavior of prometheus client libraries, which is to keep the +converted. This matches the behavior of Prometheus client libraries, which is to keep the latest exemplar for counter instruments. ### Histograms From c9f29c6e399aa83630a4de14488024da7aba2141 Mon Sep 17 00:00:00 2001 From: David Ashpole Date: Thu, 16 Apr 2026 10:16:45 -0400 Subject: [PATCH 11/12] Apply suggestions from code review Co-authored-by: Arve Knudsen Co-authored-by: David Ashpole --- specification/compatibility/prometheus_and_openmetrics.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/specification/compatibility/prometheus_and_openmetrics.md b/specification/compatibility/prometheus_and_openmetrics.md index 81455e79b5c..bdbca287433 100644 --- a/specification/compatibility/prometheus_and_openmetrics.md +++ b/specification/compatibility/prometheus_and_openmetrics.md @@ -513,7 +513,7 @@ An [OpenTelemetry Histogram](../metrics/data-model.md#histogram) with a cumulati `Exemplars` are converted as described in the [Exemplar Conversion](#exemplar-conversion) section. If the Prometheus protocol only supports a single exemplar per-bucket, the latest -exemplar that falls into each bucket MUST be converted. +exemplar that falls into each bucket SHOULD be converted. OpenTelemetry Histograms with Delta aggregation temporality SHOULD be aggregated into a Cumulative aggregation temporality and follow the logic above, or MUST be dropped. @@ -597,8 +597,9 @@ separated by `;`, and ordered by the lexicographical order of the original keys. **Status**: [Stable](../document-status.md) -[OpenTelemetry Exemplars](../metrics/data-model.md#exemplars) MUST be converted -to Prometheus exemplars if the Prometheus (push or pull) protocol being used +When an exemplar is converted per the metric-type-specific sections above, +the [OpenTelemetry Exemplar](../metrics/data-model.md#exemplars) MUST be converted +to a Prometheus exemplar if the Prometheus (push or pull) protocol being used supports them as follows: * If present, the OpenTelemetry Exemplar's Trace ID and Span ID MUST be added as From 5f730699d0fc1f4f1f351fe20068c9588194d2e4 Mon Sep 17 00:00:00 2001 From: David Ashpole Date: Thu, 16 Apr 2026 11:00:49 -0400 Subject: [PATCH 12/12] Update specification/compatibility/prometheus_and_openmetrics.md Co-authored-by: Arve Knudsen --- specification/compatibility/prometheus_and_openmetrics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/compatibility/prometheus_and_openmetrics.md b/specification/compatibility/prometheus_and_openmetrics.md index dc9162b95d0..4ef57debd27 100644 --- a/specification/compatibility/prometheus_and_openmetrics.md +++ b/specification/compatibility/prometheus_and_openmetrics.md @@ -602,7 +602,7 @@ separated by `;`, and ordered by the lexicographical order of the original keys. When an exemplar is converted per the metric-type-specific sections above, the [OpenTelemetry Exemplar](../metrics/data-model.md#exemplars) MUST be converted to a Prometheus exemplar if the Prometheus (push or pull) protocol being used -supports them as follows: +supports them, as follows: * If present, the OpenTelemetry Exemplar's Trace ID and Span ID MUST be added as Exemplar labels using the `trace_id` and `span_id` keys, respectively. These