tailscale/prober/histogram.go
Percy Wegmann 00a4504cf1 cmd/derpprobe,prober: add ability to perform continuous queuing delay measurements against DERP servers
This new type of probe sends DERP packets sized similarly to CallMeMaybe packets
at a rate of 10 packets per second. It records the round-trip times in a Prometheus
histogram. It also keeps track of how many packets are dropped. Packets that fail to
arrive within 5 seconds are considered dropped.

Updates tailscale/corp#24522

Signed-off-by: Percy Wegmann <percy@tailscale.com>
2024-12-19 10:45:56 -06:00

51 lines
1.2 KiB
Go

// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
package prober
import (
"slices"
"sync"
)
// histogram serves as an adapter to the Prometheus histogram datatype.
// The prober framework passes labels at custom metric collection time that
// it expects to be coupled with the returned metrics. See ProbeClass.Metrics
// and its call sites. Native prometheus histograms cannot be collected while
// injecting more labels. Instead we use this type and pass observations +
// collection labels to prometheus.MustNewConstHistogram() at prometheus
// metric collection time.
type histogram struct {
count uint64
sum float64
buckets []float64
bucketedCounts map[float64]uint64
mx sync.Mutex
}
// newHistogram constructs a histogram that buckets data based on the given
// slice of upper bounds.
func newHistogram(buckets []float64) *histogram {
slices.Sort(buckets)
return &histogram{
buckets: buckets,
bucketedCounts: make(map[float64]uint64, len(buckets)),
}
}
func (h *histogram) add(v float64) {
h.mx.Lock()
defer h.mx.Unlock()
h.count++
h.sum += v
for _, b := range h.buckets {
if v > b {
continue
}
h.bucketedCounts[b] += 1
break
}
}