mirror of
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake.git
synced 2025-10-13 20:11:19 -04:00
83 lines
2 KiB
Go
83 lines
2 KiB
Go
/*
|
|
Implements some additional prometheus metrics that we need for privacy preserving
|
|
counts of users and proxies
|
|
*/
|
|
|
|
package main
|
|
|
|
import (
|
|
"sync/atomic"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
dto "github.com/prometheus/client_model/go"
|
|
"google.golang.org/protobuf/proto"
|
|
)
|
|
|
|
// New Prometheus counter type that produces rounded counts of metrics
|
|
// for privacy preserving reasons
|
|
type RoundedCounter interface {
|
|
prometheus.Metric
|
|
|
|
Inc()
|
|
}
|
|
|
|
type roundedCounter struct {
|
|
total uint64 //reflects the true count
|
|
value uint64 //reflects the rounded count
|
|
|
|
desc *prometheus.Desc
|
|
labelPairs []*dto.LabelPair
|
|
}
|
|
|
|
// Implements the RoundedCounter interface
|
|
func (c *roundedCounter) Inc() {
|
|
atomic.AddUint64(&c.total, 1)
|
|
if c.total > c.value {
|
|
atomic.AddUint64(&c.value, 8)
|
|
}
|
|
}
|
|
|
|
// Implements the prometheus.Metric interface
|
|
func (c *roundedCounter) Desc() *prometheus.Desc {
|
|
return c.desc
|
|
}
|
|
|
|
// Implements the prometheus.Metric interface
|
|
func (c *roundedCounter) Write(m *dto.Metric) error {
|
|
m.Label = c.labelPairs
|
|
|
|
m.Counter = &dto.Counter{Value: proto.Float64(float64(c.value))}
|
|
return nil
|
|
}
|
|
|
|
// New prometheus vector type that will track RoundedCounter metrics
|
|
// accross multiple labels
|
|
type RoundedCounterVec struct {
|
|
*prometheus.MetricVec
|
|
}
|
|
|
|
func NewRoundedCounterVec(opts prometheus.CounterOpts, labelNames []string) *RoundedCounterVec {
|
|
desc := prometheus.NewDesc(
|
|
prometheus.BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
|
|
opts.Help,
|
|
labelNames,
|
|
opts.ConstLabels,
|
|
)
|
|
return &RoundedCounterVec{
|
|
MetricVec: prometheus.NewMetricVec(desc, func(lvs ...string) prometheus.Metric {
|
|
if len(lvs) != len(labelNames) {
|
|
panic("inconsistent cardinality")
|
|
}
|
|
return &roundedCounter{desc: desc, labelPairs: prometheus.MakeLabelPairs(desc, lvs)}
|
|
}),
|
|
}
|
|
}
|
|
|
|
// Helper function to return the underlying RoundedCounter metric from MetricVec
|
|
func (v *RoundedCounterVec) With(labels prometheus.Labels) RoundedCounter {
|
|
metric, err := v.GetMetricWith(labels)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return metric.(RoundedCounter)
|
|
}
|