@@ -217,18 +217,22 @@ var sparseBounds = [][]float64{
217
217
// }
218
218
219
219
// A Histogram counts individual observations from an event or sample stream in
220
- // configurable buckets. Similar to a summary , it also provides a sum of
220
+ // configurable buckets. Similar to a Summary , it also provides a sum of
221
221
// observations and an observation count.
222
222
//
223
223
// On the Prometheus server, quantiles can be calculated from a Histogram using
224
- // the histogram_quantile function in the query language .
224
+ // the histogram_quantile PromQL function .
225
225
//
226
- // Note that Histograms, in contrast to Summaries, can be aggregated with the
227
- // Prometheus query language (see the documentation for detailed
228
- // procedures). However, Histograms require the user to pre-define suitable
229
- // buckets, and they are in general less accurate. The Observe method of a
230
- // Histogram has a very low performance overhead in comparison with the Observe
231
- // method of a Summary.
226
+ // Note that Histograms, in contrast to Summaries, can be aggregated in PromQL
227
+ // (see the documentation for detailed procedures). However, Histograms require
228
+ // the user to pre-define suitable buckets, and they are in general less
229
+ // accurate. (Both problems are addressed by the experimental Native
230
+ // Histograms. To use them, configure so-called sparse buckets in the
231
+ // HistogramOpts. They also require a Prometheus server v2.40+ with the
232
+ // corresponding feature flag enabled.)
233
+ //
234
+ // The Observe method of a Histogram has a very low performance overhead in
235
+ // comparison with the Observe method of a Summary.
232
236
//
233
237
// To create Histogram instances, use NewHistogram.
234
238
type Histogram interface {
@@ -238,7 +242,8 @@ type Histogram interface {
238
242
// Observe adds a single observation to the histogram. Observations are
239
243
// usually positive or zero. Negative observations are accepted but
240
244
// prevent current versions of Prometheus from properly detecting
241
- // counter resets in the sum of observations. See
245
+ // counter resets in the sum of observations. (The experimental Native
246
+ // Histograms handle negative observations properly.) See
242
247
// https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations
243
248
// for details.
244
249
Observe (float64 )
@@ -261,14 +266,19 @@ var DefBuckets = []float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10}
261
266
// which is a bucket boundary at all possible resolutions.
262
267
const DefSparseBucketsZeroThreshold = 2.938735877055719e-39
263
268
269
+ // SparseBucketsZeroThresholdZero can be used as SparseBucketsZeroThreshold in
270
+ // the HistogramOpts to create a zero bucket of width zero, i.e. a zero bucket
271
+ // that only receives observations of precisely zero.
272
+ const SparseBucketsZeroThresholdZero = - 1
273
+
264
274
var errBucketLabelNotAllowed = fmt .Errorf (
265
275
"%q is not allowed as label name in histograms" , bucketLabel ,
266
276
)
267
277
268
- // LinearBuckets creates 'count' buckets, each 'width' wide, where the lowest
269
- // bucket has an upper bound of 'start'. The final +Inf bucket is not counted
270
- // and not included in the returned slice. The returned slice is meant to be
271
- // used for the Buckets field of HistogramOpts.
278
+ // LinearBuckets creates 'count' regular buckets, each 'width' wide, where the
279
+ // lowest bucket has an upper bound of 'start'. The final +Inf bucket is not
280
+ // counted and not included in the returned slice. The returned slice is meant
281
+ // to be used for the Buckets field of HistogramOpts.
272
282
//
273
283
// The function panics if 'count' is zero or negative.
274
284
func LinearBuckets (start , width float64 , count int ) []float64 {
@@ -283,11 +293,11 @@ func LinearBuckets(start, width float64, count int) []float64 {
283
293
return buckets
284
294
}
285
295
286
- // ExponentialBuckets creates 'count' buckets, where the lowest bucket has an
287
- // upper bound of 'start' and each following bucket's upper bound is 'factor'
288
- // times the previous bucket's upper bound. The final +Inf bucket is not counted
289
- // and not included in the returned slice. The returned slice is meant to be
290
- // used for the Buckets field of HistogramOpts.
296
+ // ExponentialBuckets creates 'count' regular buckets, where the lowest bucket
297
+ // has an upper bound of 'start' and each following bucket's upper bound is
298
+ // 'factor' times the previous bucket's upper bound. The final +Inf bucket is
299
+ // not counted and not included in the returned slice. The returned slice is
300
+ // meant to be used for the Buckets field of HistogramOpts.
291
301
//
292
302
// The function panics if 'count' is 0 or negative, if 'start' is 0 or negative,
293
303
// or if 'factor' is less than or equal 1.
@@ -382,20 +392,21 @@ type HistogramOpts struct {
382
392
Buckets []float64
383
393
384
394
// If SparseBucketsFactor is greater than one, sparse buckets are used
385
- // (in addition to the regular buckets, if defined above). A histogram
386
- // with sparse buckets will be ingested as a native histogram by a
387
- // Prometheus server with that feature enable. Sparse buckets are
388
- // exponential buckets covering the whole float64 range (with the
389
- // exception of the “zero” bucket, see SparseBucketsZeroThreshold
390
- // below). From any one bucket to the next, the width of the bucket
391
- // grows by a constant factor. SparseBucketsFactor provides an upper
392
- // bound for this factor (exception see below). The smaller
393
- // SparseBucketsFactor, the more buckets will be used and thus the more
394
- // costly the histogram will become. A generally good trade-off between
395
- // cost and accuracy is a value of 1.1 (each bucket is at most 10% wider
396
- // than the previous one), which will result in each power of two
397
- // divided into 8 buckets (e.g. there will be 8 buckets between 1 and 2,
398
- // same as between 2 and 4, and 4 and 8, etc.).
395
+ // (in addition to the regular buckets, if defined above). A Histogram
396
+ // with sparse buckets will be ingested as a Native Histogram by a
397
+ // Prometheus server with that feature enabled (requires Prometheus
398
+ // v2.40+). Sparse buckets are exponential buckets covering the whole
399
+ // float64 range (with the exception of the “zero” bucket, see
400
+ // SparseBucketsZeroThreshold below). From any one bucket to the next,
401
+ // the width of the bucket grows by a constant
402
+ // factor. SparseBucketsFactor provides an upper bound for this factor
403
+ // (exception see below). The smaller SparseBucketsFactor, the more
404
+ // buckets will be used and thus the more costly the histogram will
405
+ // become. A generally good trade-off between cost and accuracy is a
406
+ // value of 1.1 (each bucket is at most 10% wider than the previous
407
+ // one), which will result in each power of two divided into 8 buckets
408
+ // (e.g. there will be 8 buckets between 1 and 2, same as between 2 and
409
+ // 4, and 4 and 8, etc.).
399
410
//
400
411
// Details about the actually used factor: The factor is calculated as
401
412
// 2^(2^n), where n is an integer number between (and including) -8 and
@@ -405,28 +416,38 @@ type HistogramOpts struct {
405
416
// SparseBucketsFactor is greater than 1 but smaller than 2^(2^-8), then
406
417
// the actually used factor is still 2^(2^-8) even though it is larger
407
418
// than the provided SparseBucketsFactor.
419
+ //
420
+ // NOTE: Native Histograms are still an experimental feature. Their
421
+ // behavior might still change without a major version
422
+ // bump. Subsequently, all SparseBucket... options here might still
423
+ // change their behavior or name (or might completely disappear) without
424
+ // a major version bump.
408
425
SparseBucketsFactor float64
409
426
// All observations with an absolute value of less or equal
410
427
// SparseBucketsZeroThreshold are accumulated into a “zero” bucket. For
411
428
// best results, this should be close to a bucket boundary. This is
412
429
// usually the case if picking a power of two. If
413
430
// SparseBucketsZeroThreshold is left at zero,
414
- // DefSparseBucketsZeroThreshold is used as the threshold. If it is set
415
- // to a negative value, a threshold of zero is used, i.e. only
416
- // observations of precisely zero will go into the zero
417
- // bucket. (TODO(beorn7): That's obviously weird and just a consequence
418
- // of making the zero value of HistogramOpts meaningful. Has to be
419
- // solved more elegantly in the final version.)
431
+ // DefSparseBucketsZeroThreshold is used as the threshold. To configure
432
+ // a zero bucket with an actual threshold of zero (i.e. only
433
+ // observations of precisely zero will go into the zero bucket), set
434
+ // SparseBucketsZeroThreshold to the SparseBucketsZeroThresholdZero
435
+ // constant (or any negative float value).
420
436
SparseBucketsZeroThreshold float64
421
437
422
438
// The remaining fields define a strategy to limit the number of
423
439
// populated sparse buckets. If SparseBucketsMaxNumber is left at zero,
424
- // the number of buckets is not limited. Otherwise, once the provided
425
- // number is exceeded, the following strategy is enacted: First, if the
426
- // last reset (or the creation) of the histogram is at least
427
- // SparseBucketsMinResetDuration ago, then the whole histogram is reset
428
- // to its initial state (including regular buckets). If less time has
429
- // passed, or if SparseBucketsMinResetDuration is zero, no reset is
440
+ // the number of buckets is not limited. (Note that this might lead to
441
+ // unbounded memory consumption if the values observed by the Histogram
442
+ // are sufficiently wide-spread. In particular, this could be used as a
443
+ // DoS attack vector. Where the observed values depend on external
444
+ // inputs, it is highly recommended to set a SparseBucketsMaxNumber.)
445
+ // Once the set SparseBucketsMaxNumber is exceeded, the following
446
+ // strategy is enacted: First, if the last reset (or the creation) of
447
+ // the histogram is at least SparseBucketsMinResetDuration ago, then the
448
+ // whole histogram is reset to its initial state (including regular
449
+ // buckets). If less time has passed, or if
450
+ // SparseBucketsMinResetDuration is zero, no reset is
430
451
// performed. Instead, the zero threshold is increased sufficiently to
431
452
// reduce the number of buckets to or below SparseBucketsMaxNumber, but
432
453
// not to more than SparseBucketsMaxZeroThreshold. Thus, if
0 commit comments