From 3d82c94432a76bbab75ae4a1d27a6eaaf011196b Mon Sep 17 00:00:00 2001 From: beorn7 Date: Thu, 20 Jul 2023 16:37:00 +0200 Subject: [PATCH] histogram: Add a no-op span for an otherwise empty histogram Fixes #1127. If a native histogram has no observations and a zero threshold of zero, then it is indistinguishable from a classic histogram. To give scrapers a hint that it is indeed a native histogram, we add a no-op span. This needs follow-up PRs in prometheus/prometheus and prometheus/client_model. Signed-off-by: beorn7 --- prometheus/histogram.go | 10 ++++++++++ prometheus/histogram_test.go | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/prometheus/histogram.go b/prometheus/histogram.go index 997ea7b..a6ec4de 100644 --- a/prometheus/histogram.go +++ b/prometheus/histogram.go @@ -787,6 +787,16 @@ func (h *histogram) Write(out *dto.Metric) error { his.ZeroCount = proto.Uint64(zeroBucket) his.NegativeSpan, his.NegativeDelta = makeBuckets(&coldCounts.nativeHistogramBucketsNegative) his.PositiveSpan, his.PositiveDelta = makeBuckets(&coldCounts.nativeHistogramBucketsPositive) + + // Add a no-op span to a histogram without observations and with + // a zero threshold of zero. Otherwise, a native histogram would + // look like a classic histogram to scrapers. + if *his.ZeroThreshold == 0 && *his.ZeroCount == 0 && len(his.PositiveSpan) == 0 && len(his.NegativeSpan) == 0 { + his.PositiveSpan = []*dto.BucketSpan{{ + Offset: proto.Int32(0), + Length: proto.Uint32(0), + }} + } } addAndResetCounts(hotCounts, coldCounts) return nil diff --git a/prometheus/histogram_test.go b/prometheus/histogram_test.go index 6357c23..69ee883 100644 --- a/prometheus/histogram_test.go +++ b/prometheus/histogram_test.go @@ -485,6 +485,17 @@ func TestNativeHistogram(t *testing.T) { factor: 1, want: `sample_count:3 sample_sum:6 bucket: bucket: bucket: bucket: bucket: bucket: bucket: bucket: bucket: bucket: bucket: `, // Has conventional buckets because there are no sparse buckets. }, + { + name: "no observations", + factor: 1.1, + want: `sample_count:0 sample_sum:0 schema:3 zero_threshold:2.938735877055719e-39 zero_count:0 `, + }, + { + name: "no observations and zero threshold of zero resulting in no-op span", + factor: 1.1, + zeroThreshold: NativeHistogramZeroThresholdZero, + want: `sample_count:0 sample_sum:0 schema:3 zero_threshold:0 zero_count:0 positive_span: `, + }, { name: "factor 1.1 results in schema 3", observations: []float64{0, 1, 2, 3},