Skip to content

Commit 1a5f005

Browse files
authored
Allow creating constant histogram and summary metrics with a created timestamp (#1537)
1 parent 34e02e2 commit 1a5f005

File tree

5 files changed

+191
-0
lines changed

5 files changed

+191
-0
lines changed

prometheus/examples_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,35 @@ func ExampleNewConstSummary() {
405405
// {"label":[{"name":"code","value":"200"},{"name":"method","value":"get"},{"name":"owner","value":"example"}],"summary":{"sampleCount":"4711","sampleSum":403.34,"quantile":[{"quantile":0.5,"value":42.3},{"quantile":0.9,"value":323.3}]}}
406406
}
407407

408+
func ExampleNewConstSummaryWithCreatedTimestamp() {
409+
desc := prometheus.NewDesc(
410+
"http_request_duration_seconds",
411+
"A summary of the HTTP request durations.",
412+
[]string{"code", "method"},
413+
prometheus.Labels{"owner": "example"},
414+
)
415+
416+
// Create a constant summary with created timestamp set
417+
createdTs := time.Unix(1719670764, 123)
418+
s := prometheus.MustNewConstSummaryWithCreatedTimestamp(
419+
desc,
420+
4711, 403.34,
421+
map[float64]float64{0.5: 42.3, 0.9: 323.3},
422+
createdTs,
423+
"200", "get",
424+
)
425+
426+
// Just for demonstration, let's check the state of the summary by
427+
// (ab)using its Write method (which is usually only used by Prometheus
428+
// internally).
429+
metric := &dto.Metric{}
430+
s.Write(metric)
431+
fmt.Println(toNormalizedJSON(metric))
432+
433+
// Output:
434+
// {"label":[{"name":"code","value":"200"},{"name":"method","value":"get"},{"name":"owner","value":"example"}],"summary":{"sampleCount":"4711","sampleSum":403.34,"quantile":[{"quantile":0.5,"value":42.3},{"quantile":0.9,"value":323.3}],"createdTimestamp":"2024-06-29T14:19:24.000000123Z"}}
435+
}
436+
408437
func ExampleHistogram() {
409438
temps := prometheus.NewHistogram(prometheus.HistogramOpts{
410439
Name: "pond_temperature_celsius",
@@ -456,6 +485,34 @@ func ExampleNewConstHistogram() {
456485
// {"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}]}}
457486
}
458487

488+
func ExampleNewConstHistogramWithCreatedTimestamp() {
489+
desc := prometheus.NewDesc(
490+
"http_request_duration_seconds",
491+
"A histogram of the HTTP request durations.",
492+
[]string{"code", "method"},
493+
prometheus.Labels{"owner": "example"},
494+
)
495+
496+
createdTs := time.Unix(1719670764, 123)
497+
h := prometheus.MustNewConstHistogramWithCreatedTimestamp(
498+
desc,
499+
4711, 403.34,
500+
map[float64]uint64{25: 121, 50: 2403, 100: 3221, 200: 4233},
501+
createdTs,
502+
"200", "get",
503+
)
504+
505+
// Just for demonstration, let's check the state of the histogram by
506+
// (ab)using its Write method (which is usually only used by Prometheus
507+
// internally).
508+
metric := &dto.Metric{}
509+
h.Write(metric)
510+
fmt.Println(toNormalizedJSON(metric))
511+
512+
// Output:
513+
// {"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":"2024-06-29T14:19:24.000000123Z"}}
514+
}
515+
459516
func ExampleNewConstHistogram_WithExemplar() {
460517
desc := prometheus.NewDesc(
461518
"http_request_duration_seconds",

prometheus/histogram.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,6 +1373,48 @@ func MustNewConstHistogram(
13731373
return m
13741374
}
13751375

1376+
// NewConstHistogramWithCreatedTimestamp does the same thing as NewConstHistogram but sets the created timestamp.
1377+
func NewConstHistogramWithCreatedTimestamp(
1378+
desc *Desc,
1379+
count uint64,
1380+
sum float64,
1381+
buckets map[float64]uint64,
1382+
ct time.Time,
1383+
labelValues ...string,
1384+
) (Metric, error) {
1385+
if desc.err != nil {
1386+
return nil, desc.err
1387+
}
1388+
if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil {
1389+
return nil, err
1390+
}
1391+
return &constHistogram{
1392+
desc: desc,
1393+
count: count,
1394+
sum: sum,
1395+
buckets: buckets,
1396+
labelPairs: MakeLabelPairs(desc, labelValues),
1397+
createdTs: timestamppb.New(ct),
1398+
}, nil
1399+
}
1400+
1401+
// MustNewConstHistogramWithCreatedTimestamp is a version of NewConstHistogramWithCreatedTimestamp that panics where
1402+
// NewConstHistogramWithCreatedTimestamp would have returned an error.
1403+
func MustNewConstHistogramWithCreatedTimestamp(
1404+
desc *Desc,
1405+
count uint64,
1406+
sum float64,
1407+
buckets map[float64]uint64,
1408+
ct time.Time,
1409+
labelValues ...string,
1410+
) Metric {
1411+
m, err := NewConstHistogramWithCreatedTimestamp(desc, count, sum, buckets, ct, labelValues...)
1412+
if err != nil {
1413+
panic(err)
1414+
}
1415+
return m
1416+
}
1417+
13761418
type buckSort []*dto.Bucket
13771419

13781420
func (s buckSort) Len() int {

prometheus/histogram_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,6 +1272,31 @@ func TestHistogramVecCreatedTimestampWithDeletes(t *testing.T) {
12721272
expectCTsForMetricVecValues(t, histogramVec.MetricVec, dto.MetricType_HISTOGRAM, expected)
12731273
}
12741274

1275+
func TestNewConstHistogramWithCreatedTimestamp(t *testing.T) {
1276+
metricDesc := NewDesc(
1277+
"sample_value",
1278+
"sample value",
1279+
nil,
1280+
nil,
1281+
)
1282+
buckets := map[float64]uint64{25: 100, 50: 200}
1283+
createdTs := time.Unix(1719670764, 123)
1284+
1285+
h, err := NewConstHistogramWithCreatedTimestamp(metricDesc, 100, 200, buckets, createdTs)
1286+
if err != nil {
1287+
t.Fatal(err)
1288+
}
1289+
1290+
var metric dto.Metric
1291+
if err := h.Write(&metric); err != nil {
1292+
t.Fatal(err)
1293+
}
1294+
1295+
if metric.Histogram.CreatedTimestamp.AsTime().UnixMicro() != createdTs.UnixMicro() {
1296+
t.Errorf("Expected created timestamp %v, got %v", createdTs, &metric.Histogram.CreatedTimestamp)
1297+
}
1298+
}
1299+
12751300
func TestNativeHistogramExemplar(t *testing.T) {
12761301
// Test the histogram with positive NativeHistogramExemplarTTL and NativeHistogramMaxExemplars
12771302
h := NewHistogram(HistogramOpts{

prometheus/summary.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,3 +783,45 @@ func MustNewConstSummary(
783783
}
784784
return m
785785
}
786+
787+
// NewConstSummaryWithCreatedTimestamp does the same thing as NewConstSummary but sets the created timestamp.
788+
func NewConstSummaryWithCreatedTimestamp(
789+
desc *Desc,
790+
count uint64,
791+
sum float64,
792+
quantiles map[float64]float64,
793+
ct time.Time,
794+
labelValues ...string,
795+
) (Metric, error) {
796+
if desc.err != nil {
797+
return nil, desc.err
798+
}
799+
if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil {
800+
return nil, err
801+
}
802+
return &constSummary{
803+
desc: desc,
804+
count: count,
805+
sum: sum,
806+
quantiles: quantiles,
807+
labelPairs: MakeLabelPairs(desc, labelValues),
808+
createdTs: timestamppb.New(ct),
809+
}, nil
810+
}
811+
812+
// MustNewConstSummaryWithCreatedTimestamp is a version of NewConstSummaryWithCreatedTimestamp that panics where
813+
// NewConstSummaryWithCreatedTimestamp would have returned an error.
814+
func MustNewConstSummaryWithCreatedTimestamp(
815+
desc *Desc,
816+
count uint64,
817+
sum float64,
818+
quantiles map[float64]float64,
819+
ct time.Time,
820+
labelValues ...string,
821+
) Metric {
822+
m, err := NewConstSummaryWithCreatedTimestamp(desc, count, sum, quantiles, ct, labelValues...)
823+
if err != nil {
824+
panic(err)
825+
}
826+
return m
827+
}

prometheus/summary_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,3 +474,28 @@ func TestSummaryVecCreatedTimestampWithDeletes(t *testing.T) {
474474
})
475475
}
476476
}
477+
478+
func TestNewConstSummaryWithCreatedTimestamp(t *testing.T) {
479+
metricDesc := NewDesc(
480+
"sample_value",
481+
"sample value",
482+
nil,
483+
nil,
484+
)
485+
quantiles := map[float64]float64{50: 200.12, 99: 500.342}
486+
createdTs := time.Unix(1719670764, 123)
487+
488+
s, err := NewConstSummaryWithCreatedTimestamp(metricDesc, 100, 200, quantiles, createdTs)
489+
if err != nil {
490+
t.Fatal(err)
491+
}
492+
493+
var metric dto.Metric
494+
if err := s.Write(&metric); err != nil {
495+
t.Fatal(err)
496+
}
497+
498+
if metric.Summary.CreatedTimestamp.AsTime().UnixMicro() != createdTs.UnixMicro() {
499+
t.Errorf("Expected created timestamp %v, got %v", createdTs, &metric.Summary.CreatedTimestamp)
500+
}
501+
}

0 commit comments

Comments
 (0)