From 45eb59d29edb1e14d84f2b2d4b6ff78808a4d8ba Mon Sep 17 00:00:00 2001 From: "Guillaume E." <262623+quatre@users.noreply.github.com> Date: Mon, 19 May 2025 11:41:17 +0200 Subject: [PATCH] Fix ethtool returning 0 for sanitized metrics (#3335) The ethtool_linux looks for ethtool stats with their sanitized name which might be different from the name provisioned by ethtool. This caused node-exporter to return a 0-value for sanitized metrics. This patch works-around the missing key by copying ethtool stats to another map under their sanitized name. Signed-off-by: Guillaume Espanel Co-authored-by: Guillaume Espanel --- collector/ethtool_linux.go | 5 ++++- collector/ethtool_linux_test.go | 4 ++++ collector/fixtures/ethtool/eth0/statistics | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/collector/ethtool_linux.go b/collector/ethtool_linux.go index 01410d64..d9f66469 100644 --- a/collector/ethtool_linux.go +++ b/collector/ethtool_linux.go @@ -453,6 +453,7 @@ func (c *ethtoolCollector) Update(ch chan<- prometheus.Metric) error { // Sanitizing the metric names can lead to duplicate metric names. Therefore check for clashes beforehand. metricFQNames := make(map[string]string) + renamedStats := make(map[string]uint64, len(stats)) for metric := range stats { metricName := SanitizeMetricName(metric) if !c.metricsPattern.MatchString(metricName) { @@ -467,6 +468,8 @@ func (c *ethtoolCollector) Update(ch chan<- prometheus.Metric) error { metricFQNames[metricFQName] = "" } else { metricFQNames[metricFQName] = metricName + // Later we'll go look for the stat with the "sanitized" metric name, so we can copy it there already + renamedStats[metricName] = stats[metric] } } @@ -484,7 +487,7 @@ func (c *ethtoolCollector) Update(ch chan<- prometheus.Metric) error { continue } - val := stats[metric] + val := renamedStats[metric] // Check to see if this metric exists; if not then create it and store it in c.entries. entry := c.entryWithCreate(metric, metricFQName) diff --git a/collector/ethtool_linux_test.go b/collector/ethtool_linux_test.go index 98e66dbc..48babbc4 100644 --- a/collector/ethtool_linux_test.go +++ b/collector/ethtool_linux_test.go @@ -269,6 +269,7 @@ func NewEthtoolTestCollector(logger *slog.Logger) (Collector, error) { func TestBuildEthtoolFQName(t *testing.T) { testcases := map[string]string{ + "port.rx_errors": "node_ethtool_port_received_errors", "rx_errors": "node_ethtool_received_errors", "Queue[0] AllocFails": "node_ethtool_queue_0_allocfails", "Tx LPI entry count": "node_ethtool_transmitted_lpi_entry_count", @@ -292,6 +293,9 @@ node_ethtool_align_errors{device="eth0"} 0 # HELP node_ethtool_info A metric with a constant '1' value labeled by bus_info, device, driver, expansion_rom_version, firmware_version, version. # TYPE node_ethtool_info gauge node_ethtool_info{bus_info="0000:00:1f.6",device="eth0",driver="e1000e",expansion_rom_version="",firmware_version="0.5-4",version="5.11.0-22-generic"} 1 +# HELP node_ethtool_port_received_dropped Network interface port_rx_dropped +# TYPE node_ethtool_port_received_dropped untyped +node_ethtool_port_received_dropped{device="eth0"} 12028 # HELP node_ethtool_received_broadcast Network interface rx_broadcast # TYPE node_ethtool_received_broadcast untyped node_ethtool_received_broadcast{device="eth0"} 5792 diff --git a/collector/fixtures/ethtool/eth0/statistics b/collector/fixtures/ethtool/eth0/statistics index 80423bd6..81e511e7 100644 --- a/collector/fixtures/ethtool/eth0/statistics +++ b/collector/fixtures/ethtool/eth0/statistics @@ -4,6 +4,7 @@ NIC statistics: rx_packets: 1260062 tx_errors: 0 rx_errors: 0 + port.rx_dropped: 12028 rx_missed: 401 align_errors: 0 tx_single_collisions: 0