@@ -157,9 +157,13 @@ implementation.
157
157
### General structure
158
158
159
159
Similar to a classic histogram, a native histogram has a field for the _ count_
160
- of observations and a field for the _ sum_ of observations. In addition, it
161
- contains the following components, which are described in detail in dedicated
162
- sections below:
160
+ of observations and a field for the _ sum_ of observations. While the count of
161
+ observation is generally non-negative (with the only exception being
162
+ [ intermediate results in PromQL] ( #unary-minus-and-negative-histograms ) ), the
163
+ sum of observations might have any float64 value.
164
+
165
+ In addition, a native histogram contains the following components, which are
166
+ described in detail in dedicated sections below:
163
167
164
168
- A _ schema_ to identify the method of determining the boundaries of any given
165
169
bucket with an index _ i_ .
@@ -204,6 +208,13 @@ that the most common PromQL function applied to a counter histogram is `rate`,
204
208
which generally produces non-integer numbers, so that results of recording
205
209
rules will commonly be float histograms with non-integer values anyway.
206
210
211
+ PromQL expression may even create “negative” histograms (e.g. by multiplying a
212
+ histogram with -1). Those negative histograms are only allowed as intermediate
213
+ results and are otherwise considered invalid. They cannot be represented in any
214
+ of the exchange formats (exposition formats, remote-write, OTLP) and they
215
+ cannot be stored in the TSDB. Also see the [ detailed section about negative
216
+ histograms] ( #unary-minus-and-negative-histograms ) .
217
+
207
218
Treating native histograms explicitly as integer histograms vs. float histogram
208
219
is a notable deviation from the treatment of conventional simple numeric
209
220
samples, which are always treated as floats throughout the whole stack for the
@@ -351,13 +362,16 @@ positive bucket list is used, but repurposed for all buckets.
351
362
Any unpopulated buckets MAY be excluded from the lists. (Which is the reason
352
363
why the buckets are often called _ sparse buckets_ .)
353
364
354
- For float histograms, the elements of the lists are float64 and
355
- represent the bucket population directly.
365
+ For float histograms, the elements of the lists are float64 and represent the
366
+ bucket population directly. Bucket populations are generally non-negative, with
367
+ the only exception being [ intermediate results in
368
+ PromQL] ( #unary-minus-and-negative-histograms ) .
356
369
357
370
For integer histograms, the elements of the lists are signed 64-bit integers
358
371
(short: int64), and each element represents the bucket population as a delta to
359
372
the previous bucket in the list. The first bucket in each list contains an
360
- absolute population (which can also be seen as a delta relative to zero).
373
+ absolute population (which can also be seen as a delta relative to zero). The
374
+ deltas MUST NOT evalute to a negative absolute bucket population.
361
375
362
376
To map buckets in the lists to the indices as defined in the previous section,
363
377
there are two lists of so-called _ spans_ , one for the positive buckets and one
@@ -431,7 +445,8 @@ standard schemas above. They are counted in a dedicated bucket called the _zero
431
445
bucket_ .
432
446
433
447
The number of observations in the zero bucket is tracked by a single uint64
434
- (for integer histograms) or float64 (for float histograms).
448
+ (for integer histograms) or float64 (for float histograms). As for regular
449
+ buckets, this number is generally non-negative.
435
450
436
451
The zero bucket has an additional parameter called the _ zero threshold_ , which
437
452
is a float64 ≥ 0. If the threshold is set to zero, only observations of exactly
@@ -1775,8 +1790,10 @@ explicit counter reset detection will be thrown off by the inverted sign.
1775
1790
Generally, histograms with negative bucket populations or a negative count of
1776
1791
observations do not really make sense on their own and are only supposed to act
1777
1792
as intermediate results inside other expressions. They are always considered
1778
- gauge histograms within PromQL and when stored as the result of a recording
1779
- rule.
1793
+ gauge histograms within PromQL. They cannot be persisted as a result of a
1794
+ recording rule. (A rule evaluating to a negative histogram results in an
1795
+ error.) It is impossible to represent negative histograms in any of the
1796
+ exchange formats (exposition formats, remote-write, OTLP).
1780
1797
1781
1798
### Binary operators
1782
1799
@@ -2299,27 +2316,27 @@ Example for the text representation of a float histogram:
2299
2316
{count:3493.3, sum:2.349209324e+06, [-22.62741699796952,-16):1000, [-16,-11.31370849898476):123400, [-4,-2.82842712474619):3, [-2.82842712474619,-2):3.1, [-0.01,0.01]:5.5, (0.35355339059327373,0.5]:1, (1,1.414213562373095]:3.3, (1.414213562373095,2]:4.2, (2,2.82842712474619]:0.1}
2300
2317
```
2301
2318
2302
- ## Remote write & read
2319
+ ## Remote- write & remote- read
2303
2320
2304
- The [ protobuf specs for remote write &
2305
- read] ( https://github.com/prometheus/prometheus/blob/main/prompb ) were extended
2306
- for native histograms as an experimental feature. Receivers not capable of
2307
- processing native histograms will simply ignore the newly added fields.
2308
- Nevertheless, Prometheus has to be configured to send native histograms via
2309
- remote write (by setting the ` send_native_histograms ` remote write config
2321
+ The [ protobuf specs for remote- write &
2322
+ remote- read] ( https://github.com/prometheus/prometheus/blob/main/prompb ) were
2323
+ extended for native histograms as an experimental feature. Receivers not
2324
+ capable of processing native histograms will simply ignore the newly added
2325
+ fields. Nevertheless, Prometheus has to be configured to send native histograms
2326
+ via remote- write (by setting the ` send_native_histograms ` remote- write config
2310
2327
setting to true).
2311
2328
2312
- In [ remote write v2] ( https://prometheus.io/docs/specs/remote_write_spec_2_0/ ) ,
2329
+ In [ remote- write v2] ( https://prometheus.io/docs/specs/remote_write_spec_2_0/ ) ,
2313
2330
native histograms are a stable feature.
2314
2331
2315
2332
It might appear tempting to convert classic histograms to NHCBs while sending
2316
2333
or receiving them. However, this does not overcome the known consistency
2317
- problems classic histograms suffer from when transmitted via remote write.
2334
+ problems classic histograms suffer from when transmitted via remote- write.
2318
2335
Instead, classic histograms SHOULD be converted to NHCBs during scraping.
2319
2336
Similarly, explicit OTel histograms SHOULD be converted to NHCBs during [ OTLP
2320
2337
ingestion] ( #otlp ) already.
2321
2338
2322
- TODO: A remaining possible problem with remote write is what to do if multiple
2339
+ TODO: A remaining possible problem with remote- write is what to do if multiple
2323
2340
exemplars originally ingested for the same native histogram are sent in
2324
2341
different remote-write requests.
2325
2342
0 commit comments