prometheus.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /*
  2. Implements some additional prometheus metrics that we need for privacy preserving
  3. counts of users and proxies
  4. */
  5. package main
  6. import (
  7. "sync/atomic"
  8. "github.com/prometheus/client_golang/prometheus"
  9. dto "github.com/prometheus/client_model/go"
  10. "google.golang.org/protobuf/proto"
  11. )
  12. // New Prometheus counter type that produces rounded counts of metrics
  13. // for privacy preserving reasons
  14. type RoundedCounter interface {
  15. prometheus.Metric
  16. Inc()
  17. }
  18. type roundedCounter struct {
  19. total uint64 //reflects the true count
  20. value uint64 //reflects the rounded count
  21. desc *prometheus.Desc
  22. labelPairs []*dto.LabelPair
  23. }
  24. // Implements the RoundedCounter interface
  25. func (c *roundedCounter) Inc() {
  26. atomic.AddUint64(&c.total, 1)
  27. if c.total > c.value {
  28. atomic.AddUint64(&c.value, 8)
  29. }
  30. }
  31. // Implements the prometheus.Metric interface
  32. func (c *roundedCounter) Desc() *prometheus.Desc {
  33. return c.desc
  34. }
  35. // Implements the prometheus.Metric interface
  36. func (c *roundedCounter) Write(m *dto.Metric) error {
  37. m.Label = c.labelPairs
  38. m.Counter = &dto.Counter{Value: proto.Float64(float64(c.value))}
  39. return nil
  40. }
  41. // New prometheus vector type that will track RoundedCounter metrics
  42. // accross multiple labels
  43. type RoundedCounterVec struct {
  44. *prometheus.MetricVec
  45. }
  46. func NewRoundedCounterVec(opts prometheus.CounterOpts, labelNames []string) *RoundedCounterVec {
  47. desc := prometheus.NewDesc(
  48. prometheus.BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
  49. opts.Help,
  50. labelNames,
  51. opts.ConstLabels,
  52. )
  53. return &RoundedCounterVec{
  54. MetricVec: prometheus.NewMetricVec(desc, func(lvs ...string) prometheus.Metric {
  55. if len(lvs) != len(labelNames) {
  56. panic("inconsistent cardinality")
  57. }
  58. return &roundedCounter{desc: desc, labelPairs: prometheus.MakeLabelPairs(desc, lvs)}
  59. }),
  60. }
  61. }
  62. // Helper function to return the underlying RoundedCounter metric from MetricVec
  63. func (v *RoundedCounterVec) With(labels prometheus.Labels) RoundedCounter {
  64. metric, err := v.GetMetricWith(labels)
  65. if err != nil {
  66. panic(err)
  67. }
  68. return metric.(RoundedCounter)
  69. }