prometheus-node-exporter-lua: add modemmanager exporter

Add a Prometheus collector for ModemManager that exports cellular modem
signal metrics via mmcli. Supports multiple modems (labeled by D-Bus
object path), exports overall signal quality and detailed per-technology
signal parameters (LTE, NR5G, UMTS, GSM, CDMA, ...).

Requires signal refresh to be enabled on the modem:
  mmcli -m <id> --signal-setup=<interval_seconds>

Tested on: ath79/generic, GL.inet GL-X300B, OpenWrt 23.05.5

Co-authored-by: Claude <noreply@anthropic.com>
Signed-off-by: Jean-Laurent Girod <jeanlaurent.girod@icloud.com>
This commit is contained in:
Jean-Laurent Girod
2026-05-06 16:32:17 +00:00
committed by Etienne Champetier
parent c5af5e02fb
commit 1b18489df8
2 changed files with 61 additions and 1 deletions
+13 -1
View File
@@ -4,7 +4,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=prometheus-node-exporter-lua
PKG_VERSION:=2025.11.22
PKG_VERSION:=2026.05.06
PKG_RELEASE:=1
PKG_MAINTAINER:=Etienne CHAMPETIER <champetier.etienne@gmail.com>
@@ -279,6 +279,17 @@ define Package/prometheus-node-exporter-lua-nft-counters/install
$(INSTALL_DATA) ./files/usr/lib/lua/prometheus-collectors/nft_counters.lua $(1)/usr/lib/lua/prometheus-collectors/
endef
define Package/prometheus-node-exporter-lua-modemmanager
$(call Package/prometheus-node-exporter-lua/Default)
TITLE+= (modemmanager collector)
DEPENDS:=prometheus-node-exporter-lua +modemmanager +lua-cjson
endef
define Package/prometheus-node-exporter-lua-modemmanager/install
$(INSTALL_DIR) $(1)/usr/lib/lua/prometheus-collectors
$(INSTALL_DATA) ./files/usr/lib/lua/prometheus-collectors/modemmanager.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))
@@ -300,3 +311,4 @@ $(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))
$(eval $(call BuildPackage,prometheus-node-exporter-lua-nft-counters))
$(eval $(call BuildPackage,prometheus-node-exporter-lua-modemmanager))
@@ -0,0 +1,48 @@
local cjson = require "cjson"
local function scrape()
local file, output, data
file = io.popen("mmcli -L -J", 'r')
if not file then return end
output = file:read('*all')
file:close()
local ok, modem_list = pcall(cjson.decode, output)
if not ok or not modem_list["modem-list"] then return end
for _, modem in ipairs(modem_list["modem-list"]) do
file = io.popen("mmcli -m " .. modem .. " -J", 'r')
if file then
output = file:read('*all')
file:close()
ok, data = pcall(cjson.decode, output)
if ok and data["modem"] then
local quality = data["modem"]["generic"]["signal-quality"]["value"]
metric("modemmanager_signal_quality", "gauge", {modem=modem}, tonumber(quality))
end
end
file = io.popen("mmcli -m " .. modem .. " --signal-get -J", 'r')
if file then
output = file:read('*all')
file:close()
ok, data = pcall(cjson.decode, output)
if ok and data["modem"] and data["modem"]["signal"] then
for tech, values in pairs(data["modem"]["signal"]) do
for metric_name, value in pairs(values) do
local num = tonumber(value)
if num then
metric("modemmanager_signal_" .. tech .. "_" .. metric_name, "gauge", {modem=modem}, num)
end
end
end
end
end
end
end
return { scrape = scrape }