Add AggregateCounter

This commit is contained in:
Anton Tolchanov 2024-09-26 11:01:23 +02:00
parent 21e86013dd
commit d68ac0ebbd
4 changed files with 36 additions and 5 deletions
util/clientmetric
wgengine/magicsock

@ -9,6 +9,7 @@ import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"encoding/hex" "encoding/hex"
"expvar"
"fmt" "fmt"
"io" "io"
"sort" "sort"
@ -223,6 +224,33 @@ func NewGaugeFunc(name string, f func() int64) *Metric {
return m return m
} }
type AggregateCounter struct {
mu sync.RWMutex
counters []*expvar.Int
}
func (c *AggregateCounter) Value() int64 {
c.mu.RLock()
defer c.mu.RUnlock()
var sum int64
for _, c := range c.counters {
sum += c.Value()
}
return sum
}
func (c *AggregateCounter) Add(counter *expvar.Int) {
c.mu.Lock()
defer c.mu.Unlock()
c.counters = append(c.counters, counter)
}
func NewAggregateCounter(name string) *AggregateCounter {
c := &AggregateCounter{}
NewGaugeFunc(name, c.Value)
return c
}
// WritePrometheusExpositionFormat writes all client metrics to w in // WritePrometheusExpositionFormat writes all client metrics to w in
// the Prometheus text-based exposition format. // the Prometheus text-based exposition format.
// //

@ -690,7 +690,6 @@ func (c *connBind) receiveDERP(buffs [][]byte, sizes []int, eps []conn.Endpoint)
// No data read occurred. Wait for another packet. // No data read occurred. Wait for another packet.
continue continue
} }
metricRecvDataPacketsDERP.Add(1)
c.metrics.inboundPacketsDERPTotal.Add(1) c.metrics.inboundPacketsDERPTotal.Add(1)
c.metrics.inboundBytesDERPTotal.Add(int64(n)) c.metrics.inboundBytesDERPTotal.Add(int64(n))
sizes[0] = n sizes[0] = n

@ -623,6 +623,10 @@ func registerMetrics(reg *usermetric.Registry) *metrics {
outboundBytesDERPTotal: &expvar.Int{}, outboundBytesDERPTotal: &expvar.Int{},
} }
metricRecvDataPacketsDERP.Add(m.inboundPacketsDERPTotal)
metricSendUDP.Add(m.outboundPacketsIPv4Total)
metricSendUDP.Add(m.outboundPacketsIPv6Total)
inboundPacketsTotal.Set(pathDirectV4, m.inboundPacketsIPv4Total) inboundPacketsTotal.Set(pathDirectV4, m.inboundPacketsIPv4Total)
inboundPacketsTotal.Set(pathDirectV6, m.inboundPacketsIPv6Total) inboundPacketsTotal.Set(pathDirectV6, m.inboundPacketsIPv6Total)
inboundPacketsTotal.Set(pathDERP, m.inboundPacketsDERPTotal) inboundPacketsTotal.Set(pathDERP, m.inboundPacketsDERPTotal)
@ -1262,8 +1266,6 @@ func (c *Conn) sendUDP(ipp netip.AddrPort, b []byte) (sent bool, err error) {
_ = c.maybeRebindOnError(runtime.GOOS, err) _ = c.maybeRebindOnError(runtime.GOOS, err)
} else { } else {
if sent { if sent {
metricSendUDP.Add(1)
switch { switch {
case ipp.Addr().Is4(): case ipp.Addr().Is4():
c.metrics.outboundPacketsIPv4Total.Add(1) c.metrics.outboundPacketsIPv4Total.Add(1)
@ -3075,7 +3077,7 @@ var (
metricSendDERPErrorChan = clientmetric.NewCounter("magicsock_send_derp_error_chan") metricSendDERPErrorChan = clientmetric.NewCounter("magicsock_send_derp_error_chan")
metricSendDERPErrorClosed = clientmetric.NewCounter("magicsock_send_derp_error_closed") metricSendDERPErrorClosed = clientmetric.NewCounter("magicsock_send_derp_error_closed")
metricSendDERPErrorQueue = clientmetric.NewCounter("magicsock_send_derp_error_queue") metricSendDERPErrorQueue = clientmetric.NewCounter("magicsock_send_derp_error_queue")
metricSendUDP = clientmetric.NewCounter("magicsock_send_udp") metricSendUDP = clientmetric.NewAggregateCounter("magicsock_send_udp")
metricSendUDPError = clientmetric.NewCounter("magicsock_send_udp_error") metricSendUDPError = clientmetric.NewCounter("magicsock_send_udp_error")
metricSendDERP = clientmetric.NewCounter("magicsock_send_derp") metricSendDERP = clientmetric.NewCounter("magicsock_send_derp")
metricSendDERPError = clientmetric.NewCounter("magicsock_send_derp_error") metricSendDERPError = clientmetric.NewCounter("magicsock_send_derp_error")
@ -3083,7 +3085,7 @@ var (
// Data packets (non-disco) // Data packets (non-disco)
metricSendData = clientmetric.NewCounter("magicsock_send_data") metricSendData = clientmetric.NewCounter("magicsock_send_data")
metricSendDataNetworkDown = clientmetric.NewCounter("magicsock_send_data_network_down") metricSendDataNetworkDown = clientmetric.NewCounter("magicsock_send_data_network_down")
metricRecvDataPacketsDERP = clientmetric.NewCounter("magicsock_recv_data_derp") metricRecvDataPacketsDERP = clientmetric.NewAggregateCounter("magicsock_recv_data_derp")
metricRecvDataPacketsIPv4 = clientmetric.NewCounter("magicsock_recv_data_ipv4") metricRecvDataPacketsIPv4 = clientmetric.NewCounter("magicsock_recv_data_ipv4")
metricRecvDataPacketsIPv6 = clientmetric.NewCounter("magicsock_recv_data_ipv6") metricRecvDataPacketsIPv6 = clientmetric.NewCounter("magicsock_recv_data_ipv6")

@ -1264,6 +1264,8 @@ func assertConnStatsAndUserMetricsEqual(t *testing.T, ms *magicStack) {
assertEqual(t, "derp packets outbound", physDERPTxPackets, metricDERPTxPackets) assertEqual(t, "derp packets outbound", physDERPTxPackets, metricDERPTxPackets)
assertEqual(t, "ipv4 packets inbound", physIPv4RxPackets, metricIPv4RxPackets) assertEqual(t, "ipv4 packets inbound", physIPv4RxPackets, metricIPv4RxPackets)
assertEqual(t, "ipv4 packets outbound", physIPv4TxPackets, metricIPv4TxPackets) assertEqual(t, "ipv4 packets outbound", physIPv4TxPackets, metricIPv4TxPackets)
assertEqual(t, "outbound udp packets - compare with clientmetric", metricSendUDP.Value(), metricIPv4TxPackets*2)
} }
func assertEqual(t *testing.T, name string, a, b any) { func assertEqual(t *testing.T, name string, a, b any) {