mirror of
https://github.com/tailscale/tailscale.git
synced 2025-01-08 09:07:44 +00:00
wgengine/netstack: expose TCP forwarder drops via clientmetrics
- add a clientmetric with a counter of TCP forwarder drops due to the max attempts; - fix varz metric types, as they are all counters. Updates #8210 Signed-off-by: Anton Tolchanov <anton@tailscale.com>
This commit is contained in:
parent
50fb8b9123
commit
cd9cf93de6
@ -53,6 +53,7 @@
|
|||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/types/netmap"
|
"tailscale.com/types/netmap"
|
||||||
"tailscale.com/types/nettype"
|
"tailscale.com/types/nettype"
|
||||||
|
"tailscale.com/util/clientmetric"
|
||||||
"tailscale.com/version/distro"
|
"tailscale.com/version/distro"
|
||||||
"tailscale.com/wgengine"
|
"tailscale.com/wgengine"
|
||||||
"tailscale.com/wgengine/filter"
|
"tailscale.com/wgengine/filter"
|
||||||
@ -247,16 +248,41 @@ func Create(logf logger.Logf, tundev *tstun.Wrapper, e wgengine.Engine, mc *magi
|
|||||||
ns.atomicIsLocalIPFunc.Store(tsaddr.FalseContainsIPFunc())
|
ns.atomicIsLocalIPFunc.Store(tsaddr.FalseContainsIPFunc())
|
||||||
ns.tundev.PostFilterPacketInboundFromWireGaurd = ns.injectInbound
|
ns.tundev.PostFilterPacketInboundFromWireGaurd = ns.injectInbound
|
||||||
ns.tundev.PreFilterPacketOutboundToWireGuardNetstackIntercept = ns.handleLocalPackets
|
ns.tundev.PreFilterPacketOutboundToWireGuardNetstackIntercept = ns.handleLocalPackets
|
||||||
|
stacksForMetrics.Store(ns, struct{}{})
|
||||||
return ns, nil
|
return ns, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ns *Impl) Close() error {
|
func (ns *Impl) Close() error {
|
||||||
|
stacksForMetrics.Delete(ns)
|
||||||
ns.ctxCancel()
|
ns.ctxCancel()
|
||||||
ns.ipstack.Close()
|
ns.ipstack.Close()
|
||||||
ns.ipstack.Wait()
|
ns.ipstack.Wait()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A single process might have several netstacks running at the same time.
|
||||||
|
// Exported clientmetric counters will have a sum of counters of all of them.
|
||||||
|
var stacksForMetrics syncs.Map[*Impl, struct{}]
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// Please take care to avoid exporting clientmetrics with the same metric
|
||||||
|
// names as the ones used by Impl.ExpVar. Both get exposed via the same HTTP
|
||||||
|
// endpoint, and name collisions will result in Prometheus scraping errors.
|
||||||
|
clientmetric.NewCounterFunc("netstack_tcp_forward_dropped_attempts", func() int64 {
|
||||||
|
var total uint64
|
||||||
|
stacksForMetrics.Range(func(ns *Impl, _ struct{}) bool {
|
||||||
|
delta := ns.ipstack.Stats().TCP.ForwardMaxInFlightDrop.Value()
|
||||||
|
if total+delta > math.MaxInt64 {
|
||||||
|
total = math.MaxInt64
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
total += delta
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return int64(total)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// wrapProtoHandler returns protocol handler h wrapped in a version
|
// wrapProtoHandler returns protocol handler h wrapped in a version
|
||||||
// that dynamically reconfigures ns's subnet addresses as needed for
|
// that dynamically reconfigures ns's subnet addresses as needed for
|
||||||
// outbound traffic.
|
// outbound traffic.
|
||||||
@ -1295,7 +1321,7 @@ func (ns *Impl) ExpVar() expvar.Var {
|
|||||||
|
|
||||||
// Global metrics
|
// Global metrics
|
||||||
stats := ns.ipstack.Stats()
|
stats := ns.ipstack.Stats()
|
||||||
m.Set("gauge_dropped_packets", expvar.Func(func() any {
|
m.Set("counter_dropped_packets", expvar.Func(func() any {
|
||||||
return readStatCounter(stats.DroppedPackets)
|
return readStatCounter(stats.DroppedPackets)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@ -1327,7 +1353,7 @@ func (ns *Impl) ExpVar() expvar.Var {
|
|||||||
}
|
}
|
||||||
for _, metric := range ipMetrics {
|
for _, metric := range ipMetrics {
|
||||||
metric := metric
|
metric := metric
|
||||||
m.Set("gauge_ip_"+metric.name, expvar.Func(func() any {
|
m.Set("counter_ip_"+metric.name, expvar.Func(func() any {
|
||||||
return readStatCounter(metric.field)
|
return readStatCounter(metric.field)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -1354,7 +1380,7 @@ func (ns *Impl) ExpVar() expvar.Var {
|
|||||||
}
|
}
|
||||||
for _, metric := range fwdMetrics {
|
for _, metric := range fwdMetrics {
|
||||||
metric := metric
|
metric := metric
|
||||||
m.Set("gauge_ip_forward_"+metric.name, expvar.Func(func() any {
|
m.Set("counter_ip_forward_"+metric.name, expvar.Func(func() any {
|
||||||
return readStatCounter(metric.field)
|
return readStatCounter(metric.field)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -1367,8 +1393,6 @@ func (ns *Impl) ExpVar() expvar.Var {
|
|||||||
}{
|
}{
|
||||||
{"active_connection_openings", tcpStats.ActiveConnectionOpenings},
|
{"active_connection_openings", tcpStats.ActiveConnectionOpenings},
|
||||||
{"passive_connection_openings", tcpStats.PassiveConnectionOpenings},
|
{"passive_connection_openings", tcpStats.PassiveConnectionOpenings},
|
||||||
{"current_established", tcpStats.CurrentEstablished},
|
|
||||||
{"current_connected", tcpStats.CurrentConnected},
|
|
||||||
{"established_resets", tcpStats.EstablishedResets},
|
{"established_resets", tcpStats.EstablishedResets},
|
||||||
{"established_closed", tcpStats.EstablishedClosed},
|
{"established_closed", tcpStats.EstablishedClosed},
|
||||||
{"established_timeout", tcpStats.EstablishedTimedout},
|
{"established_timeout", tcpStats.EstablishedTimedout},
|
||||||
@ -1396,14 +1420,20 @@ func (ns *Impl) ExpVar() expvar.Var {
|
|||||||
{"segments_acked_with_dsack", tcpStats.SegmentsAckedWithDSACK},
|
{"segments_acked_with_dsack", tcpStats.SegmentsAckedWithDSACK},
|
||||||
{"spurious_recovery", tcpStats.SpuriousRecovery},
|
{"spurious_recovery", tcpStats.SpuriousRecovery},
|
||||||
{"spurious_rto_recovery", tcpStats.SpuriousRTORecovery},
|
{"spurious_rto_recovery", tcpStats.SpuriousRTORecovery},
|
||||||
{"gauge_tcp_forward_max_in_flight_drop", tcpStats.ForwardMaxInFlightDrop},
|
{"forward_max_in_flight_drop", tcpStats.ForwardMaxInFlightDrop},
|
||||||
}
|
}
|
||||||
for _, metric := range tcpMetrics {
|
for _, metric := range tcpMetrics {
|
||||||
metric := metric
|
metric := metric
|
||||||
m.Set("gauge_tcp_"+metric.name, expvar.Func(func() any {
|
m.Set("counter_tcp_"+metric.name, expvar.Func(func() any {
|
||||||
return readStatCounter(metric.field)
|
return readStatCounter(metric.field)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
m.Set("gauge_tcp_current_established", expvar.Func(func() any {
|
||||||
|
return readStatCounter(tcpStats.CurrentEstablished)
|
||||||
|
}))
|
||||||
|
m.Set("gauge_tcp_current_connected", expvar.Func(func() any {
|
||||||
|
return readStatCounter(tcpStats.CurrentConnected)
|
||||||
|
}))
|
||||||
|
|
||||||
// UDP metrics
|
// UDP metrics
|
||||||
udpStats := ns.ipstack.Stats().UDP
|
udpStats := ns.ipstack.Stats().UDP
|
||||||
@ -1421,7 +1451,7 @@ func (ns *Impl) ExpVar() expvar.Var {
|
|||||||
}
|
}
|
||||||
for _, metric := range udpMetrics {
|
for _, metric := range udpMetrics {
|
||||||
metric := metric
|
metric := metric
|
||||||
m.Set("gauge_udp_"+metric.name, expvar.Func(func() any {
|
m.Set("counter_udp_"+metric.name, expvar.Func(func() any {
|
||||||
return readStatCounter(metric.field)
|
return readStatCounter(metric.field)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user