Skip to content

Commit

Permalink
histogram: Add a no-op span for an otherwise empty histogram
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
beorn7 committed Jul 20, 2023
1 parent f9db382 commit 3d82c94
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 0 deletions.
10 changes: 10 additions & 0 deletions prometheus/histogram.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 11 additions & 0 deletions prometheus/histogram_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,17 @@ func TestNativeHistogram(t *testing.T) {
factor: 1,
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.
},
{
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:<offset:0 length:0 > `,
},
{
name: "factor 1.1 results in schema 3",
observations: []float64{0, 1, 2, 3},
Expand Down

0 comments on commit 3d82c94

Please sign in to comment.