net/sockstat: fix per-interface statistics not always being available
withSockStats may be called before setLinkMonitor, in which case we don't have a populated knownInterfaces map. Since we pre-populate the per-interface counters at creation time, we would end up with an empty map. To mitigate this, we do an on-demand request for the list of interfaces. This would most often happen with the logtail instrumentation, since we initialize it very early on. Updates tailscale/corp#9230 Signed-off-by: Mihai Parparita <mihai@tailscale.com>pull/7518/head
parent
e69682678f
commit
4c2f67a1d0
|
@ -53,9 +53,22 @@ func withSockStats(ctx context.Context, label Label) context.Context {
|
|||
rxBytesByInterface: make(map[int]*atomic.Uint64),
|
||||
txBytesByInterface: make(map[int]*atomic.Uint64),
|
||||
}
|
||||
for iface := range sockStats.knownInterfaces {
|
||||
counters.rxBytesByInterface[iface] = &atomic.Uint64{}
|
||||
counters.txBytesByInterface[iface] = &atomic.Uint64{}
|
||||
|
||||
// We might be called before setLinkMonitor has been called (and we've
|
||||
// had a chance to populate knownInterfaces). In that case, we'll have
|
||||
// to get the list of interfaces ourselves.
|
||||
if len(sockStats.knownInterfaces) == 0 {
|
||||
if ifaces, err := interfaces.GetList(); err == nil {
|
||||
for _, iface := range ifaces {
|
||||
counters.rxBytesByInterface[iface.Index] = &atomic.Uint64{}
|
||||
counters.txBytesByInterface[iface.Index] = &atomic.Uint64{}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for iface := range sockStats.knownInterfaces {
|
||||
counters.rxBytesByInterface[iface] = &atomic.Uint64{}
|
||||
counters.txBytesByInterface[iface] = &atomic.Uint64{}
|
||||
}
|
||||
}
|
||||
sockStats.countersByLabel[label] = counters
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue