Skip to content

Commit 3f7b3be

Browse files
authored
Stabilize Prometheus Native Histogram -> OTLP (Exponential) Histogram (#4898)
Fixes #4748 ## Changes Enacted from #4748 (comment) - [x] The counter reset header is not mentioned -added - [x] Stale NaN is not defined in the document - added link to code where the bit representation can be found - [x] Conversion of spans and counts is a bit hand-wavy, I understand why you'd want to link to something - added precise wording and link - [x] Off by one of the offset is mentioned, but it doesn't say if it's -1 or +1 - precise now with explanation - [x] NHCB (-53) schema is missing indeed - added - [x] Prometheus has renamed the Created timestamp to Start timestamp to be more aligned - [x] I'm not sure if the overflow buckets of native histograms are handled or how they work in OTel. Where do you count - values equal to +-Inf or values outside float64 ? - these were indeed not handled, specified now Additionally added notes on `Count` and `Sum` for special value cases. Note that the OTel metric data model does not have "MUST" requirements on the special values or if the overall `Count` must be equal to the sum of all buckets. For non-trivial changes, follow the [change proposal process](https://github.com/open-telemetry/opentelemetry-specification/blob/main/CONTRIBUTING.md#proposing-a-change). * [ ] Related issues # * [ ] Related [OTEP(s)](https://github.com/open-telemetry/oteps) # * [ ] Links to the prototypes (when adding or changing features) * [ ] [`CHANGELOG.md`](https://github.com/open-telemetry/opentelemetry-specification/blob/main/CHANGELOG.md) file updated for non-trivial changes * For trivial changes, include `[chore]` in the PR title to skip the changelog check * [ ] [Spec compliance matrix](https://github.com/open-telemetry/opentelemetry-specification/blob/main/spec-compliance-matrix/template.yaml) updated if necessary --------- Signed-off-by: György Krajcsovits <gyorgy.krajcsovits@grafana.com>
1 parent bf7ed2f commit 3f7b3be

3 files changed

Lines changed: 81 additions & 12 deletions

File tree

.cspell.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ dictionaries:
8989
- google
9090
- people-names
9191
words:
92+
- NHCB
9293
- BLRP
9394
- Kubecon
9495
- OpAMP

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ release.
4141

4242
- Stabilize Prometheus Classic Histogram to OTLP Explicit Histogram transformation.
4343
([#4874](https://github.com/open-telemetry/opentelemetry-specification/pull/4874))
44+
- Clarify Prometheus Native Histogram to OTLP Exponential Histogram conversion,
45+
add conversion rules for Native Histograms with Custom Buckets (NHCB) to OTLP
46+
Histogram.
47+
([#4898](https://github.com/open-telemetry/opentelemetry-specification/pull/4898))
4448

4549
### SDK Configuration
4650

specification/compatibility/prometheus_and_openmetrics.md

Lines changed: 76 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -150,35 +150,99 @@ In the text format, Prometheus histograms buckets, count and sum are sent as sep
150150

151151
### Native Histograms
152152

153-
**Status**: [Development](../document-status.md)
153+
**Status**: [Stable](../document-status.md)
154154

155155
A [Prometheus Native Histogram](https://prometheus.io/docs/specs/native_histograms/)
156156
with standard (exponential) schema (i.e. schemas -4 to 8) and which are
157157
of the integer and counter [flavor](https://prometheus.io/docs/specs/native_histograms/#flavors)
158158
MUST be converted to an OTLP Exponential Histogram as follows:
159159

160+
- If the Native Histogram `ResetHint` (or `CounterResetHint`) indicates gauge
161+
type, the native histogram is dropped. Otherwise this field is ignored.
160162
- `Schema` is converted to the Exponential Histogram `Scale`.
161163
- The `NoRecordedValue` flag is set to `true` if the `Sum` is equal to the
162-
Stale NaN value. Otherwise,
163-
- `Count` is converted to Exponential Histogram `Count`.
164-
- `Sum` is converted to the Exponential Histogram `Sum`.
164+
[Stale NaN value](https://github.com/prometheus/prometheus/blob/main/model/value/value.go).
165+
Otherwise,
166+
- `Count` is made equal to the sum of all valid bucket counts by adding up
167+
- the `ZeroCount`,
168+
- the bucket counts from the sparse bucket layout described below, except
169+
for overflow buckets.
170+
- `Sum` is converted to the Exponential Histogram `Sum`. Note that the `Sum`
171+
may be `NaN` in case the Native Histogram observed the value `NaN` or both
172+
`-Inf` and `+Inf`. The `Sum` may also be `-Inf` or `+Inf`.
165173
- `Timestamp` is converted to the Exponential Histogram `TimeUnixNano` after
166174
converting milliseconds to nanoseconds.
167175
- `ZeroCount` is converted directly to the Exponential Histogram `ZeroCount`.
168176
- `ZeroThreshold`, is converted to the Exponential Histogram `ZeroThreshold`.
169-
- The sparse bucket layout represented by `PositiveSpans` and `PositiveDeltas` is
170-
converted to the Exponential Histogram dense layout represented by `Positive`
171-
bucket counts and `Offset`. The same holds for `NegativeSpans` and
172-
`NegativeDeltas`. Note that Prometheus Native Histograms buckets are indexed by
173-
upper boundary while Exponential Histograms are indexed by lower boundary, the
174-
result being that the Offset fields are different-by-one.
177+
- The [sparse bucket layout](https://prometheus.io/docs/specs/native_histograms/#buckets)
178+
represented by `PositiveSpans` and `PositiveDeltas` is converted to the
179+
Exponential Histogram dense layout represented by `Positive` bucket counts and
180+
`Offset`.
181+
182+
- The `PositiveDeltas` are delta encoded bucket counts, where the first value
183+
is an absolute bucket count and each subsequent value is a delta to the
184+
previous value.
185+
- The Exponential Histogram `Positive` `Offset` is set to the first
186+
`PositiveSpan`'s `Offset` minus 1 (`PositiveSpans[0].Offset-1`) if there
187+
are spans, otherwise left at 0. The minus one is because Prometheus Native
188+
histogram buckets are indexed by their upper boundary while Exponential
189+
Histograms are indexed by their lower boundary.
190+
- The `PositiveSpans` encode the index into the `Positive` bucket counts for
191+
each value in the `PositiveDeltas`. The index starts from 0 for the first
192+
span, for subsequent spans the span's `Offset` is added to the previous
193+
index. The span's `Length` indicates the number of continuous indexes to
194+
use.
195+
- The Native Histogram may contain overflow buckets. If converted to
196+
an Exponential Histogram bucket, the overflow bucket would map to values
197+
outside the IEEE float range. Overflow buckets MUST be dropped and not
198+
counted in the overall `Count`.
199+
200+
- The `NegativeSpans` and `NegativeDeltas` are converted the same way as the
201+
positive buckets.
202+
- `Min` and `Max` are not set.
203+
- `StartTimeUnixNano` is set to the `Start Timestamp` timestamp, if available.
204+
- `AggregationTemporality` is set to `cumulative`.
205+
206+
A Native histogram with custom buckets (NHCB) schema (i.e. schema -53) and which
207+
are of the integer and counter [flavor](https://prometheus.io/docs/specs/native_histograms/#flavors)
208+
MUST be converted to an OTLP Histogram as follows:
209+
210+
- If the Native Histogram `ResetHint` (or `CounterResetHint`) indicates gauge
211+
type, the native histogram is dropped. Otherwise this field is ignored.
212+
- The `NoRecordedValue` flag is set to `true` if the `Sum` is equal to the
213+
[Stale NaN value](https://github.com/prometheus/prometheus/blob/main/model/value/value.go).
214+
Otherwise,
215+
- `Count` is converted to Histogram `Count`. Note that the `Count`
216+
is equal to the sum of all bucket counts.
217+
- `Sum` is converted to the Histogram `Sum`. Note that the `Sum`
218+
may be `NaN` in case the Native Histogram observed the value `NaN` or both
219+
`-Inf` and `+Inf`. The `Sum` may also be `-Inf` or `+Inf`.
220+
- `Timestamp` is converted to the Histogram `TimeUnixNano` after
221+
converting milliseconds to nanoseconds.
175222
- `Min` and `Max` are not set.
176-
- `StartTimeUnixNano` is set to the `Created` timestamp, if available.
223+
- [`CustomValues`](https://prometheus.io/docs/specs/native_histograms/#custom-values)
224+
is converted to bucket boundaries. The `+Inf` bucket is implicit, therefore
225+
`N` `CustomValues` represent `N+1` Histogram bucket counts.
226+
- The [sparse bucket layout](https://prometheus.io/docs/specs/native_histograms/#buckets)
227+
represented by `PositiveSpans` and `PositiveDeltas` is converted to
228+
Histogram bucket counts.
229+
230+
- The `PositiveDeltas` are delta encoded bucket counts, where the first value
231+
is an absolute bucket count and each subsequent value is a delta to the
232+
previous value.
233+
- The `PositiveSpans` encode the index into the bucket counts for each value
234+
in the `PositiveDeltas`. The index starts from the `Offset` in the first
235+
span and for subsequent spans the span's `Offset` is added to the previous
236+
index. The span's `Length` indicates the number of continuous indexes to
237+
use.
238+
239+
- `StartTimeUnixNano` is set to the `Start Timestamp`, if available.
177240
- `AggregationTemporality` is set to `cumulative`.
178241

179242
Native histograms of the float or gauge flavors MUST be dropped.
180243

181-
Native Histograms with `Schema` outside of the range [-4, 8] MUST be dropped.
244+
Native Histograms with `Schema` outside of the range [-4, 8] and not equal to
245+
-53 MUST be dropped.
182246

183247
### Summaries
184248

0 commit comments

Comments
 (0)