Skip to content

Commit 3d82c94

Browse files
committed
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 <[email protected]>
1 parent f9db382 commit 3d82c94

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

prometheus/histogram.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,16 @@ func (h *histogram) Write(out *dto.Metric) error {
787787
his.ZeroCount = proto.Uint64(zeroBucket)
788788
his.NegativeSpan, his.NegativeDelta = makeBuckets(&coldCounts.nativeHistogramBucketsNegative)
789789
his.PositiveSpan, his.PositiveDelta = makeBuckets(&coldCounts.nativeHistogramBucketsPositive)
790+
791+
// Add a no-op span to a histogram without observations and with
792+
// a zero threshold of zero. Otherwise, a native histogram would
793+
// look like a classic histogram to scrapers.
794+
if *his.ZeroThreshold == 0 && *his.ZeroCount == 0 && len(his.PositiveSpan) == 0 && len(his.NegativeSpan) == 0 {
795+
his.PositiveSpan = []*dto.BucketSpan{{
796+
Offset: proto.Int32(0),
797+
Length: proto.Uint32(0),
798+
}}
799+
}
790800
}
791801
addAndResetCounts(hotCounts, coldCounts)
792802
return nil

prometheus/histogram_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,17 @@ func TestNativeHistogram(t *testing.T) {
485485
factor: 1,
486486
want: `sample_count:3 sample_sum:6 bucket:<cumulative_count:0 upper_bound:0.005 > bucket:<cumulative_count:0 upper_bound:0.01 > bucket:<cumulative_count:0 upper_bound:0.025 > bucket:<cumulative_count:0 upper_bound:0.05 > bucket:<cumulative_count:0 upper_bound:0.1 > bucket:<cumulative_count:0 upper_bound:0.25 > bucket:<cumulative_count:0 upper_bound:0.5 > bucket:<cumulative_count:1 upper_bound:1 > bucket:<cumulative_count:2 upper_bound:2.5 > bucket:<cumulative_count:3 upper_bound:5 > bucket:<cumulative_count:3 upper_bound:10 > `, // Has conventional buckets because there are no sparse buckets.
487487
},
488+
{
489+
name: "no observations",
490+
factor: 1.1,
491+
want: `sample_count:0 sample_sum:0 schema:3 zero_threshold:2.938735877055719e-39 zero_count:0 `,
492+
},
493+
{
494+
name: "no observations and zero threshold of zero resulting in no-op span",
495+
factor: 1.1,
496+
zeroThreshold: NativeHistogramZeroThresholdZero,
497+
want: `sample_count:0 sample_sum:0 schema:3 zero_threshold:0 zero_count:0 positive_span:<offset:0 length:0 > `,
498+
},
488499
{
489500
name: "factor 1.1 results in schema 3",
490501
observations: []float64{0, 1, 2, 3},

0 commit comments

Comments
 (0)