Skip to content

Commit 807b1ee

Browse files
explicitly add +inf bucket in withExemplarsMetric (#1094)
* explicitly adding +inf bucket to withExemplarsMetric Signed-off-by: Arun Mahendra <[email protected]> * Update prometheus/metric_test.go Co-authored-by: Bartlomiej Plotka <[email protected]> * Update prometheus/metric.go Co-authored-by: Bartlomiej Plotka <[email protected]> * updated comment and removed unnecessary test Co-authored-by: Bartlomiej Plotka <[email protected]>
1 parent c6d4e40 commit 807b1ee

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

prometheus/metric.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ package prometheus
1515

1616
import (
1717
"errors"
18+
"math"
1819
"sort"
1920
"strings"
2021
"time"
@@ -184,8 +185,15 @@ func (m *withExemplarsMetric) Write(pb *dto.Metric) error {
184185
if i < len(pb.Histogram.Bucket) {
185186
pb.Histogram.Bucket[i].Exemplar = e
186187
} else {
187-
// This is not possible as last bucket is Inf.
188-
panic("no bucket was found for given exemplar value")
188+
// The +Inf bucket should be explicitly added if there is an exemplar for it, similar to non-const histogram logic in https://github.com/prometheus/client_golang/blob/main/prometheus/histogram.go#L357-L365.
189+
b := &dto.Bucket{
190+
CumulativeCount: proto.Uint64(pb.Histogram.Bucket[len(pb.Histogram.GetBucket())-1].GetCumulativeCount()),
191+
UpperBound: proto.Float64(math.Inf(1)),
192+
Exemplar: e,
193+
}
194+
pb.Histogram.Bucket = append(pb.Histogram.Bucket, b)
195+
break
196+
// Terminating the loop after creating the +Inf bucket and adding one exemplar, if there are other exemplars in the +Inf bucket range they will be ignored.
189197
}
190198
}
191199
default:

prometheus/metric_test.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package prometheus
1515

1616
import (
17+
"math"
1718
"testing"
1819

1920
//nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility.
@@ -56,16 +57,19 @@ func TestWithExemplarsMetric(t *testing.T) {
5657
{Value: proto.Float64(89.0)},
5758
{Value: proto.Float64(100.0)},
5859
{Value: proto.Float64(157.0)},
60+
{Value: proto.Float64(500.0)},
61+
{Value: proto.Float64(2000.0)},
5962
}}
6063
metric := dto.Metric{}
6164
if err := m.Write(&metric); err != nil {
6265
t.Fatal(err)
6366
}
64-
if want, got := 4, len(metric.GetHistogram().Bucket); want != got {
67+
if want, got := 5, len(metric.GetHistogram().Bucket); want != got {
6568
t.Errorf("want %v, got %v", want, got)
6669
}
6770

68-
expectedExemplarVals := []float64{24.0, 42.0, 100.0, 157.0}
71+
// When there are more exemplars than there are buckets, a +Inf bucket will be created and the last exemplar value will be added.
72+
expectedExemplarVals := []float64{24.0, 42.0, 100.0, 157.0, 500.0}
6973
for i, b := range metric.GetHistogram().Bucket {
7074
if b.Exemplar == nil {
7175
t.Errorf("Expected exemplar for bucket %v, got nil", i)
@@ -74,5 +78,11 @@ func TestWithExemplarsMetric(t *testing.T) {
7478
t.Errorf("%v: want %v, got %v", i, want, got)
7579
}
7680
}
81+
82+
infBucket := metric.GetHistogram().Bucket[len(metric.GetHistogram().Bucket)-1].GetUpperBound()
83+
84+
if infBucket != math.Inf(1) {
85+
t.Errorf("want %v, got %v", math.Inf(1), infBucket)
86+
}
7787
})
7888
}

0 commit comments

Comments
 (0)