Skip to content

Instantly share code, notes, and snippets.

@mitchellrj
Last active April 2, 2020 16:37
Show Gist options
  • Save mitchellrj/e0538e33433a6cb1311623af54c1e5df to your computer and use it in GitHub Desktop.
Save mitchellrj/e0538e33433a6cb1311623af54c1e5df to your computer and use it in GitHub Desktop.
Prometheus exporter for Netgear LTE modems. Rough and ready.
FROM arm32v7/python:stretch
ENV MODEM_HOST=127.0.0.1
ENV MODEM_PASSWORD=password
EXPOSE 8000
RUN sh -c 'apk add --no-cache python3; python3 -m pip install eternalegypt prometheus_client'
COPY netgear_prometheus.py /netgear_prometheus.py
USER nobody
CMD python3 /netgear_prometheus.py
import asyncio
import aiohttp
import os
import sys
import eternalegypt
import prometheus_client
class ModemCollector:
def __init__(self, loop, namespace, modem):
self._loop = loop
self._modem = modem
self._metrics = []
if namespace:
self._prefix = namespace + '_'
else:
self._prefix = ''
self._error_counter = prometheus_client.Counter('collection_errors', 'Number of errors while collecting metrics')
self._scrape_duration = prometheus_client.Gauge('scrape_duration', 'Time spent scraping the modem')
self._create_metrics()
def _create_metrics(self):
self._sms_total = self._gauge('sms_total', 'Current number of SMS messages')
self._sms_unread = self._gauge('sms_unread', 'Current number of unread SMS messages')
self._roaming = self._gauge('roaming', '1 if roaming, 0 if not')
self._radio_quality = self._gauge('radio_quality', 'Radio quality')
self._rx_level = self._gauge('rx_level', 'RX level')
self._tx_level = self._gauge('tx_level', 'TX level')
self._data_transferred = self._gauge('data_transferred', 'Data transferred')
self._metrics = [
self._sms_total,
self._sms_unread,
self._roaming,
self._radio_quality,
self._rx_level,
self._tx_level,
self._data_transferred,
]
async def gather(self):
self._create_metrics()
try:
info = await self._modem.information()
except Exception:
self._error_counter.inc()
raise
else:
self._sms_total.add_metric([], len(info.sms))
self._sms_unread.add_metric([], len([s for s in info.sms if s.unread]))
self._roaming.add_metric([], int(info.roaming))
self._radio_quality.add_metric([], info.radio_quality)
self._rx_level.add_metric([], info.rx_level)
self._tx_level.add_metric([], info.tx_level)
self._data_transferred.add_metric([], info.usage)
# data['general']['devTemperature'] # gauge
# data['power']['deviceTempCritical'] # bool
# data['power']['resetRequired'] # enum (NoResetRequired)
# data['wwan']['IP'] # label
# data['wwan']['connection'] # enum (Connected)
# data['wwan']['sessDuration'] # counter
# data['wwan']['dataTransferred']['rxb'] # string of a number
# data['wwan']['dataTransferred']['txb'] # string of a number
def collect(self):
return self._metrics
def _gauge(self, name, description):
return self._metric(
prometheus_client.core.GaugeMetricFamily,
name, description
)
def _counter(self, name, description):
return self._metric(
prometheus_client.core.CounterMetricFamily,
name, description
)
def _metric(self, cls, name, description):
return cls(self._prefix + name, description)
async def main(loop, host, password):
jar = aiohttp.CookieJar(unsafe=True)
websession = aiohttp.ClientSession(cookie_jar=jar)
modem = eternalegypt.Modem(hostname=host, websession=websession)
c = ModemCollector(loop, 'netgear', modem)
prometheus_client.core.REGISTRY.register(c)
try:
prometheus_client.start_http_server(8000)
while True:
try:
await modem.login(password=password)
except eternalegypt.Error:
print("Could not login")
try:
while True:
await c.gather()
await asyncio.sleep(5)
except Exception:
pass
finally:
await modem.logout()
await websession.close()
if __name__ == '__main__':
loop = asyncio.get_event_loop()
if len(sys.argv) == 3:
host = sys.argv[1]
password = sys.argv[2]
else:
host = os.getenv('MODEM_HOST')
password = os.getenv('MODEM_PASSWORD')
loop.run_until_complete(main(loop, host, password))
apiVersion: v1
kind: Pod
metadata:
name: netgear-prometheus
spec:
containers:
- name: netgear-prometheus
image: mitchellrj/netgear_exporter:latest
ports:
- containerPort: 8000
env:
- name: MODEM_PASSWORD
valueFrom:
secretKeyRef:
name: netgear-lte-password
key: password
- name: MODEM_HOST
value: "127.0.0.1"
@DanielYWoo
Copy link

Do you have a plan to publish the exporter to dockerhub? It would be cool

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment