Skip to content

Commit 06d7406

Browse files
arun-shopifywperron
andcommitted
Add support for exemplars on constHistogram
Co-authored-by: William Perron <william.perron@shopify.com> Signed-off-by: William Perron <william.perron@shopify.com>
1 parent 5ac1e92 commit 06d7406

File tree

2 files changed

+116
-2
lines changed

2 files changed

+116
-2
lines changed

prometheus/examples_test.go

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package prometheus_test
1616
import (
1717
"bytes"
1818
"fmt"
19+
"google.golang.org/protobuf/types/known/timestamppb"
1920
"math"
2021
"net/http"
2122
"runtime"
@@ -549,11 +550,27 @@ func ExampleNewConstHistogram() {
549550
prometheus.Labels{"owner": "example"},
550551
)
551552

553+
var exemplars []*dto.Exemplar
554+
n := "testName"
555+
v := "testVal"
556+
lp := dto.LabelPair{Name: &n, Value: &v}
557+
var labelPairs []*dto.LabelPair
558+
labelPairs = append(labelPairs, &lp)
559+
val := float64(42)
560+
t, _ := time.Parse("unix", "Mon Jan _2 15:04:05 MST 2006")
561+
ts := timestamppb.New(t)
562+
563+
for i := 0; i < 4; i++ {
564+
e := dto.Exemplar{Label: labelPairs, Value: &val, Timestamp: ts}
565+
exemplars = append(exemplars, &e)
566+
}
567+
552568
// Create a constant histogram from values we got from a 3rd party telemetry system.
553-
h := prometheus.MustNewConstHistogram(
569+
h := prometheus.MustNewConstHistogramWithExemplar(
554570
desc,
555571
4711, 403.34,
556572
map[float64]uint64{25: 121, 50: 2403, 100: 3221, 200: 4233},
573+
exemplars,
557574
"200", "get",
558575
)
559576

@@ -583,18 +600,58 @@ func ExampleNewConstHistogram() {
583600
// bucket: <
584601
// cumulative_count: 121
585602
// upper_bound: 25
603+
// exemplar: <
604+
// label: <
605+
// name: "testName"
606+
// value: "testVal"
607+
// >
608+
// value: 42
609+
// timestamp: <
610+
// seconds: -62135596800
611+
// >
612+
// >
586613
// >
587614
// bucket: <
588615
// cumulative_count: 2403
589616
// upper_bound: 50
617+
// exemplar: <
618+
// label: <
619+
// name: "testName"
620+
// value: "testVal"
621+
// >
622+
// value: 42
623+
// timestamp: <
624+
// seconds: -62135596800
625+
// >
626+
// >
590627
// >
591628
// bucket: <
592629
// cumulative_count: 3221
593630
// upper_bound: 100
631+
// exemplar: <
632+
// label: <
633+
// name: "testName"
634+
// value: "testVal"
635+
// >
636+
// value: 42
637+
// timestamp: <
638+
// seconds: -62135596800
639+
// >
640+
// >
594641
// >
595642
// bucket: <
596643
// cumulative_count: 4233
597644
// upper_bound: 200
645+
// exemplar: <
646+
// label: <
647+
// name: "testName"
648+
// value: "testVal"
649+
// >
650+
// value: 42
651+
// timestamp: <
652+
// seconds: -62135596800
653+
// >
654+
// >
598655
// >
599656
// >
600657
}

prometheus/histogram.go

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,7 @@ type constHistogram struct {
573573
sum float64
574574
buckets map[float64]uint64
575575
labelPairs []*dto.LabelPair
576+
exemplars []*dto.Exemplar
576577
}
577578

578579
func (h *constHistogram) Desc() *Desc {
@@ -585,7 +586,6 @@ func (h *constHistogram) Write(out *dto.Metric) error {
585586

586587
his.SampleCount = proto.Uint64(h.count)
587588
his.SampleSum = proto.Float64(h.sum)
588-
589589
for upperBound, count := range h.buckets {
590590
buckets = append(buckets, &dto.Bucket{
591591
CumulativeCount: proto.Uint64(count),
@@ -596,6 +596,13 @@ func (h *constHistogram) Write(out *dto.Metric) error {
596596
if len(buckets) > 0 {
597597
sort.Sort(buckSort(buckets))
598598
}
599+
600+
if len(h.exemplars) > 0 {
601+
for i := 0; i < len(buckets); i++ {
602+
buckets[i].Exemplar = h.exemplars[i]
603+
}
604+
}
605+
599606
his.Bucket = buckets
600607

601608
out.Histogram = his
@@ -604,6 +611,13 @@ func (h *constHistogram) Write(out *dto.Metric) error {
604611
return nil
605612
}
606613

614+
func (h *constHistogram) GetExemplars() []*dto.Exemplar {
615+
if h != nil {
616+
return h.exemplars
617+
}
618+
return nil
619+
}
620+
607621
// NewConstHistogram returns a metric representing a Prometheus histogram with
608622
// fixed values for the count, sum, and bucket counts. As those parameters
609623
// cannot be changed, the returned value does not implement the Histogram
@@ -617,6 +631,7 @@ func (h *constHistogram) Write(out *dto.Metric) error {
617631
//
618632
// NewConstHistogram returns an error if the length of labelValues is not
619633
// consistent with the variable labels in Desc or if Desc is invalid.
634+
620635
func NewConstHistogram(
621636
desc *Desc,
622637
count uint64,
@@ -655,6 +670,48 @@ func MustNewConstHistogram(
655670
return m
656671
}
657672

673+
func NewConstHistogramWithExemplar(
674+
desc *Desc,
675+
count uint64,
676+
sum float64,
677+
buckets map[float64]uint64,
678+
exemplars []*dto.Exemplar,
679+
labelValues ...string,
680+
681+
) (Metric, error) {
682+
if desc.err != nil {
683+
return nil, desc.err
684+
}
685+
if err := validateLabelValues(labelValues, len(desc.variableLabels)); err != nil {
686+
return nil, err
687+
}
688+
return &constHistogram{
689+
desc: desc,
690+
count: count,
691+
sum: sum,
692+
buckets: buckets,
693+
exemplars: exemplars,
694+
labelPairs: MakeLabelPairs(desc, labelValues),
695+
}, nil
696+
}
697+
698+
// MustNewConstHistogram is a version of NewConstHistogram that panics where
699+
// NewConstHistogram would have returned an error.
700+
func MustNewConstHistogramWithExemplar(
701+
desc *Desc,
702+
count uint64,
703+
sum float64,
704+
buckets map[float64]uint64,
705+
exemplars []*dto.Exemplar,
706+
labelValues ...string,
707+
) Metric {
708+
m, err := NewConstHistogramWithExemplar(desc, count, sum, buckets, exemplars, labelValues...)
709+
if err != nil {
710+
panic(err)
711+
}
712+
return m
713+
}
714+
658715
type buckSort []*dto.Bucket
659716

660717
func (s buckSort) Len() int {

0 commit comments

Comments
 (0)