Add prometheus exporter

This commit is contained in:
2025-09-03 22:46:13 +02:00
parent 50f530889b
commit 99b0ca4fcc
2 changed files with 162 additions and 0 deletions

View File

@@ -1,4 +1,5 @@
from . import Mu5001Tool
from .prometheus_exporter import prometheus_exporter
import argparse
from pprint import pprint
@@ -27,6 +28,12 @@ def run_status(m):
sp_status = subparsers.add_parser("status", help="General modem status information")
sp_status.set_defaults(func=run_status)
def run_prometheus_exporter(m):
prometheus_exporter(m)
sp_prometheus_exporter = subparsers.add_parser("prometheus-exporter", help="Serve metrics as prometheus exporter")
sp_prometheus_exporter.set_defaults(func=run_prometheus_exporter)
def main():
args = parser.parse_args()

View File

@@ -0,0 +1,155 @@
from . import Mu5001Tool
from http.server import BaseHTTPRequestHandler, HTTPServer, HTTPStatus
import socket
import traceback
class HTTPServerV6(HTTPServer):
address_family = socket.AF_INET6
def make_prometheus_exporter_request_handler(m):
class PrometheusExporterRequestHandler(BaseHTTPRequestHandler):
def do_GET(self, head_only=False):
if self.path == "/":
self.make_response(
"Prometheus Exporter for MU5001",
head_only=head_only
)
elif self.path == "/metrics":
try:
self.make_response(
self.export(),
head_only=head_only
)
except Exception as e:
traceback.print_exc()
self.send_error(HTTPStatus.INTERNAL_SERVER_ERROR, "Failed to fetch metrics")
else:
self.send_error(HTTPStatus.NOT_FOUND, "File not found")
def do_HEAD(self):
self.do_GET(head_only=True)
def make_response(self, content, head_only=False):
encoded = content.encode("utf-8")
self.send_response(HTTPStatus.OK)
self.send_header("Content-Type", "text/plain; charset=utf-8")
self.send_header("Conten-Length", str(len(encoded)))
self.end_headers()
if not head_only:
self.wfile.write(encoded)
def export(self):
cmds_as_metric_value = [
"adjfsdfj",
"battery_charging",
"battery_pers",
"battery_temp",
"battery_value",
"battery_vol_percent",
"data_volume_alert_percent",
"data_volume_limit_size",
"data_volume_limit_switch",
"dhcp_wan_status",
"lte_ca_pcell_band",
"lte_ca_pcell_bandwidth",
"lte_ca_scell_band",
"lte_ca_scell_bandwidth",
"lte_rsrp",
"lte_rssi",
"lte_snr",
"mdm_mcc",
"monthly_rx_bytes",
"monthly_time",
"monthly_tx_bytes",
"nr5g_action_channel",
"pin_status",
"ppp_dial_conn_fail_counter",
"realtime_rx_bytes",
"realtime_rx_thrpt",
"realtime_time",
"realtime_tx_bytes",
"realtime_tx_thrpt",
"rmcc",
"rmnc",
"signalbar",
"sms_unread_num",
"wan_active_channel",
"wifi_5g_enable",
"wifi_access_sta_num",
"wifi_chip1_ssid1_access_sta_num",
"wifi_chip1_ssid2_access_sta_num",
"wifi_chip2_ssid1_access_sta_num",
"wifi_chip2_ssid2_access_sta_num",
"wifi_onoff_state",
]
cmds_as_metric_label = [
"battery_charg_type",
"data_volume_limit_unit",
"dial_mode",
"mode_main_state",
"modem_main_state",
"network_provider",
"network_type",
"opms_wan_auto_mode",
"opms_wan_mode",
"ppp_status",
"roam_setting_option",
"simcard_roam",
"spn_name_data",
"wan_connect_status",
"wan_lte_ca",
"wifi_chip1_ssid1_auth_mode",
"wifi_chip1_ssid1_ssid",
"wifi_chip2_ssid1_auth_mode",
"wifi_chip2_ssid1_ssid",
"cell_id",
"lte_pci",
"nr5g_action_band",
"nr5g_pci",
"wan_active_band",
]
data = m.get_cmd_process({
"multi_data": 1,
"cmd": ",".join(cmds_as_metric_value + cmds_as_metric_label),
})
out = []
for cmd in cmds_as_metric_value:
d = data.get(cmd)
if d is None:
continue
try:
v = int(d)
except ValueError as e:
try:
v = float(d)
except ValueError as e:
raise ValueError(f"cmd: {cmd}: {e}")
out.append(f"mu5001_{cmd} {v}")
for cmd in cmds_as_metric_label:
d = data.get(cmd)
if d is None or d == "":
continue
out.append(f"mu5001_{cmd}{{{cmd}=\"{d}\"}} 1")
out.sort()
return "\n".join(out)
return PrometheusExporterRequestHandler
def prometheus_exporter(m):
with HTTPServerV6(("::1", 9242), make_prometheus_exporter_request_handler(m)) as httpd:
print("Starting prometheus exporter on http://[{}]:{}".format(*httpd.socket.getsockname()[:2]))
httpd.serve_forever()