prober: add address family lable for udp metrics

Add a label which differentiates the address family
for STUN checks.

Also initialize the derpprobe_attempts_total and
derpprobe_seconds_total metrics by adding 0 for
the alternate fail/ok case.

Updates tailscale/corp#27249

Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
This commit is contained in:
Mike O'Driscoll 2025-03-24 14:05:19 -04:00
parent 156cd53e77
commit 6d33023d92
No known key found for this signature in database
3 changed files with 33 additions and 10 deletions

View File

@ -157,7 +157,7 @@ func DERP(p *Prober, derpMapURL string, opts ...DERPOpt) (*derpProber, error) {
} }
d.ProbeMap = ProbeClass{ d.ProbeMap = ProbeClass{
Probe: d.probeMapFn, Probe: d.probeMapFn,
Class: "derp_map", Class: ClassDERPMap,
} }
for _, o := range opts { for _, o := range opts {
o(d) o(d)
@ -286,7 +286,7 @@ func (d *derpProber) probeMesh(from, to string) ProbeClass {
dm := d.lastDERPMap dm := d.lastDERPMap
return derpProbeNodePair(ctx, dm, fromN, toN) return derpProbeNodePair(ctx, dm, fromN, toN)
}, },
Class: "derp_mesh", Class: ClassDERPMesh,
Labels: Labels{"derp_path": derpPath}, Labels: Labels{"derp_path": derpPath},
} }
} }
@ -310,7 +310,7 @@ func (d *derpProber) probeBandwidth(from, to string, size int64) ProbeClass {
} }
return derpProbeBandwidth(ctx, d.lastDERPMap, fromN, toN, size, &transferTimeSeconds, &totalBytesTransferred, d.bwTUNIPv4Prefix) return derpProbeBandwidth(ctx, d.lastDERPMap, fromN, toN, size, &transferTimeSeconds, &totalBytesTransferred, d.bwTUNIPv4Prefix)
}, },
Class: "derp_bw", Class: ClassBandwidth,
Labels: Labels{ Labels: Labels{
"derp_path": derpPath, "derp_path": derpPath,
"tcp_in_tcp": strconv.FormatBool(d.bwTUNIPv4Prefix != nil), "tcp_in_tcp": strconv.FormatBool(d.bwTUNIPv4Prefix != nil),
@ -351,7 +351,7 @@ func (d *derpProber) probeQueuingDelay(from, to string, packetsPerSecond int, pa
} }
return derpProbeQueuingDelay(ctx, d.lastDERPMap, fromN, toN, packetsPerSecond, packetTimeout, &packetsDropped, qdh) return derpProbeQueuingDelay(ctx, d.lastDERPMap, fromN, toN, packetsPerSecond, packetTimeout, &packetsDropped, qdh)
}, },
Class: "derp_qd", Class: ClassQueueDepth,
Labels: Labels{"derp_path": derpPath}, Labels: Labels{"derp_path": derpPath},
Metrics: func(l prometheus.Labels) []prometheus.Metric { Metrics: func(l prometheus.Labels) []prometheus.Metric {
qdh.mx.Lock() qdh.mx.Lock()
@ -600,7 +600,7 @@ func (d *derpProber) ProbeUDP(ipaddr string, port int) ProbeClass {
Probe: func(ctx context.Context) error { Probe: func(ctx context.Context) error {
return derpProbeUDP(ctx, ipaddr, port) return derpProbeUDP(ctx, ipaddr, port)
}, },
Class: "derp_udp", Class: ClassDERPUDP,
} }
} }

View File

@ -17,6 +17,7 @@ import (
"maps" "maps"
"math/rand" "math/rand"
"net/http" "net/http"
"strings"
"sync" "sync"
"time" "time"
@ -29,6 +30,17 @@ import (
// in memory. // in memory.
const recentHistSize = 10 const recentHistSize = 10
type ClassType string
var (
ClassDERPUDP ClassType = "derp_udp"
ClassDERPMesh ClassType = "derp_mesh"
ClassDERPMap ClassType = "derp_map"
ClassTLS ClassType = "tls"
ClassQueueDepth ClassType = "derp_qd"
ClassBandwidth ClassType = "derp_bw"
)
// ProbeClass defines a probe of a specific type: a probing function that will // ProbeClass defines a probe of a specific type: a probing function that will
// be regularly ran, and metric labels that will be added automatically to all // be regularly ran, and metric labels that will be added automatically to all
// probes using this class. // probes using this class.
@ -40,7 +52,7 @@ type ProbeClass struct {
// Class defines a user-facing name of the probe class that will be used // Class defines a user-facing name of the probe class that will be used
// in the `class` metric label. // in the `class` metric label.
Class string Class ClassType
// Labels defines a set of metric labels that will be added to all metrics // Labels defines a set of metric labels that will be added to all metrics
// exposed by this probe class. // exposed by this probe class.
@ -117,7 +129,14 @@ func (p *Prober) Run(name string, interval time.Duration, labels Labels, pc Prob
l := prometheus.Labels{ l := prometheus.Labels{
"name": name, "name": name,
"class": pc.Class, "class": string(pc.Class),
}
if pc.Class == ClassDERPUDP {
if strings.Contains(name, "udp6") {
l["af"] = "udp6"
} else {
l["af"] = "udp"
}
} }
for k, v := range pc.Labels { for k, v := range pc.Labels {
l[k] = v l[k] = v
@ -404,10 +423,14 @@ func (p *Probe) recordEndLocked(err error) {
p.mSeconds.WithLabelValues("ok").Add(latency.Seconds()) p.mSeconds.WithLabelValues("ok").Add(latency.Seconds())
p.latencyHist.Value = latency p.latencyHist.Value = latency
p.latencyHist = p.latencyHist.Next() p.latencyHist = p.latencyHist.Next()
p.mAttempts.WithLabelValues("fail").Add(0)
p.mSeconds.WithLabelValues("fail").Add(0)
} else { } else {
p.latency = 0 p.latency = 0
p.mAttempts.WithLabelValues("fail").Inc() p.mAttempts.WithLabelValues("fail").Inc()
p.mSeconds.WithLabelValues("fail").Add(latency.Seconds()) p.mSeconds.WithLabelValues("fail").Add(latency.Seconds())
p.mAttempts.WithLabelValues("ok").Add(0)
p.mSeconds.WithLabelValues("ok").Add(0)
} }
p.successHist.Value = p.succeeded p.successHist.Value = p.succeeded
p.successHist = p.successHist.Next() p.successHist = p.successHist.Next()
@ -486,7 +509,7 @@ func (p *Prober) ProbeInfo() map[string]ProbeInfo {
func (probe *Probe) probeInfoLocked() ProbeInfo { func (probe *Probe) probeInfoLocked() ProbeInfo {
inf := ProbeInfo{ inf := ProbeInfo{
Name: probe.name, Name: probe.name,
Class: probe.probeClass.Class, Class: string(probe.probeClass.Class),
Interval: probe.interval, Interval: probe.interval,
Labels: probe.metricLabels, Labels: probe.metricLabels,
Start: probe.start, Start: probe.start,

View File

@ -36,7 +36,7 @@ func TLS(hostPort string) ProbeClass {
} }
return probeTLS(ctx, certDomain, hostPort) return probeTLS(ctx, certDomain, hostPort)
}, },
Class: "tls", Class: ClassTLS,
} }
} }
@ -48,7 +48,7 @@ func TLSWithIP(certDomain string, dialAddr netip.AddrPort) ProbeClass {
Probe: func(ctx context.Context) error { Probe: func(ctx context.Context) error {
return probeTLS(ctx, certDomain, dialAddr.String()) return probeTLS(ctx, certDomain, dialAddr.String())
}, },
Class: "tls", Class: ClassTLS,
} }
} }