From fb323ca8e1f6d07db4c0fcf0a9dab2b33af0f285 Mon Sep 17 00:00:00 2001 From: Steven Swartz Date: Tue, 11 Jun 2024 14:49:04 -0400 Subject: [PATCH] Allow creating constant histogram metrics with a created timestamp Closes #1535 Signed-off-by: Steven Swartz --- prometheus/examples_test.go | 28 +++++++++++++++++++++++++ prometheus/histogram.go | 41 +++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/prometheus/examples_test.go b/prometheus/examples_test.go index e4fed3e95..4b8eb5d2e 100644 --- a/prometheus/examples_test.go +++ b/prometheus/examples_test.go @@ -456,6 +456,34 @@ func ExampleNewConstHistogram() { // {"label":[{"name":"code","value":"200"},{"name":"method","value":"get"},{"name":"owner","value":"example"}],"histogram":{"sampleCount":"4711","sampleSum":403.34,"bucket":[{"cumulativeCount":"121","upperBound":25},{"cumulativeCount":"2403","upperBound":50},{"cumulativeCount":"3221","upperBound":100},{"cumulativeCount":"4233","upperBound":200}]}} } +func ExampleNewConstHistogramWithCreatedTimestamp() { + desc := prometheus.NewDesc( + "http_request_duration_seconds", + "A histogram of the HTTP request durations.", + []string{"code", "method"}, + prometheus.Labels{"owner": "example"}, + ) + + ct := time.Unix(0, 0).UTC() + h := prometheus.MustNewConstHistogramWithCreatedTimestamp( + desc, + 4711, 403.34, + map[float64]uint64{25: 121, 50: 2403, 100: 3221, 200: 4233}, + ct, + "200", "get", + ) + + // Just for demonstration, let's check the state of the histogram by + // (ab)using its Write method (which is usually only used by Prometheus + // internally). + metric := &dto.Metric{} + h.Write(metric) + fmt.Println(toNormalizedJSON(metric)) + + // Output: + // {"label":[{"name":"code","value":"200"},{"name":"method","value":"get"},{"name":"owner","value":"example"}],"histogram":{"sampleCount":"4711","sampleSum":403.34,"bucket":[{"cumulativeCount":"121","upperBound":25},{"cumulativeCount":"2403","upperBound":50},{"cumulativeCount":"3221","upperBound":100},{"cumulativeCount":"4233","upperBound":200}],"createdTimestamp":"1970-01-01T00:00:00Z"}} +} + func ExampleNewConstHistogram_WithExemplar() { desc := prometheus.NewDesc( "http_request_duration_seconds", diff --git a/prometheus/histogram.go b/prometheus/histogram.go index b5c8bcb39..7110483fd 100644 --- a/prometheus/histogram.go +++ b/prometheus/histogram.go @@ -1336,6 +1336,47 @@ func MustNewConstHistogram( return m } +// NewConstHistogramWithCreatedTimestamp does the same thing as NewConstHistogram but sets the created timestamp +func NewConstHistogramWithCreatedTimestamp( + desc *Desc, + count uint64, + sum float64, + buckets map[float64]uint64, + ct time.Time, + labelValues ...string, +) (Metric, error) { + if desc.err != nil { + return nil, desc.err + } + if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil { + return nil, err + } + return &constHistogram{ + desc: desc, + count: count, + sum: sum, + buckets: buckets, + labelPairs: MakeLabelPairs(desc, labelValues), + createdTs: timestamppb.New(ct), + }, nil +} + +// MustNewConstHistogramWithCreatedTimestamp is a version of NewConstHistogramWithCreatedTimestamp that panics where +// NewConstHistogramWithCreatedTimestamp would have returned an error. +func MustNewConstHistogramWithCreatedTimestamp( + desc *Desc, + count uint64, + sum float64, + buckets map[float64]uint64, + ct time.Time, + labelValues ...string) Metric { + m, err := NewConstHistogramWithCreatedTimestamp(desc, count, sum, buckets, ct, labelValues...) + if err != nil { + panic(err) + } + return m +} + type buckSort []*dto.Bucket func (s buckSort) Len() int {