From 3b9613cfae0a662a666da03c8d038ec21dba512e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Knecht?= Date: Tue, 1 Aug 2023 15:58:53 +0200 Subject: [PATCH] collector/netdev_linux.go: Fallback to 32-bit stats (#2757) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On some platforms, `msg.Attributes.Stats64` is `nil` because the kernel doesn't expose 64-bit stats. In that case, return `msg.Attributes.Stats` instead, which are the 32-bit equivalent. Note that `RXOtherhostDropped` isn't available in that case, so we hardcode it to zero. Fixes #2756. Signed-off-by: BenoƮt Knecht --- collector/netdev_linux.go | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/collector/netdev_linux.go b/collector/netdev_linux.go index 3156d64a..f3348cda 100644 --- a/collector/netdev_linux.go +++ b/collector/netdev_linux.go @@ -56,14 +56,53 @@ func parseNetlinkStats(links []rtnetlink.LinkMessage, filter *deviceFilter, logg metrics := netDevStats{} for _, msg := range links { + if msg.Attributes == nil { + level.Debug(logger).Log("msg", "No netlink attributes, skipping") + continue + } name := msg.Attributes.Name stats := msg.Attributes.Stats64 + if stats32 := msg.Attributes.Stats; stats == nil && stats32 != nil { + stats = &rtnetlink.LinkStats64{ + RXPackets: uint64(stats32.RXPackets), + TXPackets: uint64(stats32.TXPackets), + RXBytes: uint64(stats32.RXBytes), + TXBytes: uint64(stats32.TXBytes), + RXErrors: uint64(stats32.RXErrors), + TXErrors: uint64(stats32.TXErrors), + RXDropped: uint64(stats32.RXDropped), + TXDropped: uint64(stats32.TXDropped), + Multicast: uint64(stats32.Multicast), + Collisions: uint64(stats32.Collisions), + RXLengthErrors: uint64(stats32.RXLengthErrors), + RXOverErrors: uint64(stats32.RXOverErrors), + RXCRCErrors: uint64(stats32.RXCRCErrors), + RXFrameErrors: uint64(stats32.RXFrameErrors), + RXFIFOErrors: uint64(stats32.RXFIFOErrors), + RXMissedErrors: uint64(stats32.RXMissedErrors), + TXAbortedErrors: uint64(stats32.TXAbortedErrors), + TXCarrierErrors: uint64(stats32.TXCarrierErrors), + TXFIFOErrors: uint64(stats32.TXFIFOErrors), + TXHeartbeatErrors: uint64(stats32.TXHeartbeatErrors), + TXWindowErrors: uint64(stats32.TXWindowErrors), + RXCompressed: uint64(stats32.RXCompressed), + TXCompressed: uint64(stats32.TXCompressed), + RXNoHandler: uint64(stats32.RXNoHandler), + RXOtherhostDropped: 0, + } + } if filter.ignored(name) { level.Debug(logger).Log("msg", "Ignoring device", "device", name) continue } + // Make sure we don't panic when accessing `stats` attributes below. + if stats == nil { + level.Debug(logger).Log("msg", "No netlink stats, skipping") + continue + } + // https://github.com/torvalds/linux/blob/master/include/uapi/linux/if_link.h#L42-L246 metrics[name] = map[string]uint64{ "receive_packets": stats.RXPackets,