From 909a15a64b01eec6b5cc4e68bf49de426677599d Mon Sep 17 00:00:00 2001 From: Kevin Jilissen Date: Thu, 9 May 2024 01:51:32 +0200 Subject: [PATCH] prometheus-node-exporter-lua: Add ethtool exporter Based on ethtool-lua library, add interface statistics to the prometheus-node-exporter. As closely as possible, the behaviour of the implementation at https://github.com/prometheus/node_exporter/blob/400c3979931613db930ea035f39ce7b377cdbb5b/collector/ethtool_linux.go#L208 is replicated. Signed-off-by: Kevin Jilissen [squash commits, bump version, fix permission, use untyped, rename to ethtool] Signed-off-by: Etienne Champetier (cherry picked from commit 9f94448b71f03caf9d2bd3ab228055317ad7ebc4) --- utils/prometheus-node-exporter-lua/Makefile | 16 +++- .../lib/lua/prometheus-collectors/ethtool.lua | 83 +++++++++++++++++++ 2 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/ethtool.lua diff --git a/utils/prometheus-node-exporter-lua/Makefile b/utils/prometheus-node-exporter-lua/Makefile index 9d68c20bc7..5d5bbf802e 100644 --- a/utils/prometheus-node-exporter-lua/Makefile +++ b/utils/prometheus-node-exporter-lua/Makefile @@ -4,8 +4,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=prometheus-node-exporter-lua -PKG_VERSION:=2024.06.16 -PKG_RELEASE:=2 +PKG_VERSION:=2025.06.08 +PKG_RELEASE:=1 PKG_MAINTAINER:=Etienne CHAMPETIER PKG_LICENSE:=Apache-2.0 @@ -257,6 +257,17 @@ define Package/prometheus-node-exporter-lua-mwan3/install $(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/mwan3.lua $(1)/usr/lib/lua/prometheus-collectors/ endef +define Package/prometheus-node-exporter-lua-ethtool + $(call Package/prometheus-node-exporter-lua/Default) + TITLE+= (ethtool collector) + DEPENDS:=prometheus-node-exporter-lua +ethtool-lua +endef + +define Package/prometheus-node-exporter-lua-ethtool/install + $(INSTALL_DIR) $(1)/usr/lib/lua/prometheus-collectors + $(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/ethtool.lua $(1)/usr/lib/lua/prometheus-collectors/ +endef + $(eval $(call BuildPackage,prometheus-node-exporter-lua)) $(eval $(call BuildPackage,prometheus-node-exporter-lua-bmx7)) $(eval $(call BuildPackage,prometheus-node-exporter-lua-dawn)) @@ -276,3 +287,4 @@ $(eval $(call BuildPackage,prometheus-node-exporter-lua-wifi_stations)) $(eval $(call BuildPackage,prometheus-node-exporter-lua-snmp6)) $(eval $(call BuildPackage,prometheus-node-exporter-lua-realtek-poe)) $(eval $(call BuildPackage,prometheus-node-exporter-lua-mwan3)) +$(eval $(call BuildPackage,prometheus-node-exporter-lua-ethtool)) diff --git a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/ethtool.lua b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/ethtool.lua new file mode 100644 index 0000000000..5080728f99 --- /dev/null +++ b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/ethtool.lua @@ -0,0 +1,83 @@ +local ethtool = require "ethtool" + +local pattern_device = "^%s*([^%s:]+):" +local pattern_metric = "_*[^0-9A-Za-z_]+_*" + +local metric_fqnames = { + rx_bytes = "node_ethtool_received_bytes_total", + rx_dropped = "node_ethtool_received_dropped_total", + rx_errors = "node_ethtool_received_errors_total", + rx_packets = "node_ethtool_received_packets_total", + tx_bytes = "node_ethtool_transmitted_bytes_total", + tx_errors = "node_ethtool_transmitted_errors_total", + tx_packets = "node_ethtool_transmitted_packets_total", + -- link info + supported_port = "node_network_supported_port_info", + supported_speed = "node_network_supported_speed_bytes", + supported_autonegotiate = "node_network_autonegotiate_supported", + supported_pause = "node_network_pause_supported", + supported_asymmetricpause = "node_network_asymmetricpause_supported", + advertised_speed = "node_network_advertised_speed_bytes", + advertised_autonegotiate = "node_network_autonegotiate_advertised", + advertised_pause = "node_network_pause_advertised", + advertised_asymmetricpause = "node_network_asymmetricpause_advertised", + autonegotiate = "node_network_autonegotiate", +} +local metric_replacement_words = { + rx = "received", + tx = "transmitted", +} + +local function get_devices() + local devices = {} + for line in io.lines("/proc/net/dev") do + local dev = string.match(line, pattern_device) + if dev then + table.insert(devices, dev) + end + end + return devices +end + +local function replace_words(metric) + return string.gsub(metric, "(%a+)", function(word) + local replacement = metric_replacement_words[word] + if replacement then + return replacement + end + return word + end) +end + +local function build_ethtool_fqname(metric) + local metricName = metric:gsub(pattern_metric, "_") + metricName = metricName:lower():gsub("^[%s_]+", "") + metricName = replace_words(metricName) + return "node_ethtool_" .. metricName +end + +local function scrape() + local eth = ethtool.open() + local metrics = {} + for _, dev in ipairs(get_devices()) do + local stats = eth:statistics(dev) + if stats then + for m_name, m_value in pairs(stats) do + fqname = metric_fqnames[m_name] + if fqname == nil then + fqname = build_ethtool_fqname(m_name) + metric_fqnames[m_name] = fqname + end + local m = metrics[fqname] + if m == nil then + m = metric(fqname, "untyped") + metrics[fqname] = m + end + m({ device = dev }, m_value) + end + end + end + eth:close() +end + +return { scrape = scrape }