Skip to content

Commit 9c4fec0

Browse files
committed
Implement constSummary and constHistogram.
1 parent 066ab78 commit 9c4fec0

File tree

2 files changed

+185
-0
lines changed

2 files changed

+185
-0
lines changed

prometheus/histogram.go

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,3 +342,102 @@ func (m *HistogramVec) WithLabelValues(lvs ...string) Histogram {
342342
func (m *HistogramVec) With(labels Labels) Histogram {
343343
return m.MetricVec.With(labels).(Histogram)
344344
}
345+
346+
type constHistogram struct {
347+
desc *Desc
348+
count uint64
349+
sum float64
350+
buckets map[float64]uint64
351+
labelPairs []*dto.LabelPair
352+
}
353+
354+
func (h *constHistogram) Desc() *Desc {
355+
return h.desc
356+
}
357+
358+
func (h *constHistogram) Write(out *dto.Metric) error {
359+
his := &dto.Histogram{}
360+
buckets := make([]*dto.Bucket, 0, len(h.buckets))
361+
362+
his.SampleCount = proto.Uint64(h.count)
363+
his.SampleSum = proto.Float64(h.sum)
364+
365+
for upperBound, count := range h.buckets {
366+
buckets = append(buckets, &dto.Bucket{
367+
CumulativeCount: proto.Uint64(count),
368+
UpperBound: proto.Float64(upperBound),
369+
})
370+
}
371+
372+
if len(buckets) > 0 {
373+
sort.Sort(buckSort(buckets))
374+
}
375+
his.Bucket = buckets
376+
377+
out.Histogram = his
378+
out.Label = h.labelPairs
379+
380+
return nil
381+
}
382+
383+
// NewConstHistogram returns a metric representing a Prometheus histogram with fixed
384+
// values for the count, sum, and quantiles. As those parameters cannot be
385+
// changed, the returned value does not implement the Histogram interface (but
386+
// only the Metric interface). Users of this package will not have much use for
387+
// it in regular operations. However, when implementing custom Collectors, it is
388+
// useful as a throw-away metric that is generated on the fly to send it to
389+
// Prometheus in the Collect method.
390+
//
391+
// buckets is a map of upper bounds to cumulative counts, excluding the +Inf
392+
// bucket.
393+
//
394+
// NewConstHistogram returns an error if the length of labelValues is not
395+
// consistent with the variable labels in Desc.
396+
func NewConstHistogram(
397+
desc *Desc,
398+
count uint64,
399+
sum float64,
400+
buckets map[float64]uint64,
401+
labelValues ...string,
402+
) (Metric, error) {
403+
if len(desc.variableLabels) != len(labelValues) {
404+
return nil, errInconsistentCardinality
405+
}
406+
return &constHistogram{
407+
desc: desc,
408+
count: count,
409+
sum: sum,
410+
buckets: buckets,
411+
labelPairs: makeLabelPairs(desc, labelValues),
412+
}, nil
413+
}
414+
415+
// MustNewConstHistogram is a version of NewConstHistogram that panics where
416+
// NewConstMetric would have returned an error.
417+
func MustNewConstHistogram(
418+
desc *Desc,
419+
count uint64,
420+
sum float64,
421+
buckets map[float64]uint64,
422+
labelValues ...string,
423+
) Metric {
424+
m, err := NewConstHistogram(desc, count, sum, buckets, labelValues...)
425+
if err != nil {
426+
panic(err)
427+
}
428+
return m
429+
}
430+
431+
type buckSort []*dto.Bucket
432+
433+
func (s buckSort) Len() int {
434+
return len(s)
435+
}
436+
437+
func (s buckSort) Swap(i, j int) {
438+
s[i], s[j] = s[j], s[i]
439+
}
440+
441+
func (s buckSort) Less(i, j int) bool {
442+
return s[i].GetUpperBound() < s[j].GetUpperBound()
443+
}

prometheus/summary.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,3 +448,89 @@ func (m *SummaryVec) WithLabelValues(lvs ...string) Summary {
448448
func (m *SummaryVec) With(labels Labels) Summary {
449449
return m.MetricVec.With(labels).(Summary)
450450
}
451+
452+
type constSummary struct {
453+
desc *Desc
454+
count uint64
455+
sum float64
456+
quantiles map[float64]float64
457+
labelPairs []*dto.LabelPair
458+
}
459+
460+
func (s *constSummary) Desc() *Desc {
461+
return s.desc
462+
}
463+
464+
func (s *constSummary) Write(out *dto.Metric) error {
465+
sum := &dto.Summary{}
466+
qs := make([]*dto.Quantile, 0, len(s.quantiles))
467+
468+
sum.SampleCount = proto.Uint64(s.count)
469+
sum.SampleSum = proto.Float64(s.sum)
470+
471+
for rank, q := range s.quantiles {
472+
qs = append(qs, &dto.Quantile{
473+
Quantile: proto.Float64(rank),
474+
Value: proto.Float64(q),
475+
})
476+
}
477+
478+
if len(qs) > 0 {
479+
sort.Sort(quantSort(qs))
480+
}
481+
sum.Quantile = qs
482+
483+
out.Summary = sum
484+
out.Label = s.labelPairs
485+
486+
return nil
487+
}
488+
489+
// NewConstSummary returns a metric representing a Prometheus summary with fixed
490+
// values for the count, sum, and quantiles. As those parameters cannot be
491+
// changed, the returned value does not implement the Summary interface (but
492+
// only the Metric interface). Users of this package will not have much use for
493+
// it in regular operations. However, when implementing custom Collectors, it is
494+
// useful as a throw-away metric that is generated on the fly to send it to
495+
// Prometheus in the Collect method.
496+
//
497+
// quantiles maps ranks to quantile values. For example, a median latency of
498+
// 0.23s and a 99th percentile latency of 0.56s would be expressed as:
499+
// map[float64]float64{0.5: 0.23, 0.99: 0.56}
500+
//
501+
// NewConstSummary returns an error if the length of labelValues is not
502+
// consistent with the variable labels in Desc.
503+
func NewConstSummary(
504+
desc *Desc,
505+
count uint64,
506+
sum float64,
507+
quantiles map[float64]float64,
508+
labelValues ...string,
509+
) (Metric, error) {
510+
if len(desc.variableLabels) != len(labelValues) {
511+
return nil, errInconsistentCardinality
512+
}
513+
return &constSummary{
514+
desc: desc,
515+
count: count,
516+
sum: sum,
517+
quantiles: quantiles,
518+
labelPairs: makeLabelPairs(desc, labelValues),
519+
}, nil
520+
}
521+
522+
// MustNewConstSummary is a version of NewConstSummary that panics where
523+
// NewConstMetric would have returned an error.
524+
func MustNewConstSummary(
525+
desc *Desc,
526+
count uint64,
527+
sum float64,
528+
quantiles map[float64]float64,
529+
labelValues ...string,
530+
) Metric {
531+
m, err := NewConstSummary(desc, count, sum, quantiles, labelValues...)
532+
if err != nil {
533+
panic(err)
534+
}
535+
return m
536+
}

0 commit comments

Comments
 (0)