HomeGrafana Tools › SMSEagle

SMSEagle Grafana Dashboard

Your SMS gateway is the thing that tells you everything else is broken — so it is worth watching too. This stack pulls an SMSEagle device's APIv2 into Prometheus metrics and ships them to Grafana Cloud: modem signal, SIM and network registration, message queues per channel, SMPP, temperature and firmware status. No SNMP, and an offline mock so you can build the whole thing before you touch the device.

Watch the setup

The full walkthrough, from empty folder to live dashboard:

What the dashboard shows

SMSEagle Grafana dashboard showing modem signal strength over time with current gauges at 75 and 81, both modems enabled and registered with SIM status OK, a service status panel listing snmp enabled and mqtt, email2sms and data_conn disabled, and a temperature panel reading 50.3 degrees Celsius.
Modem signal, SIM and network registration, service status, and temperature.
Second view of the SMSEagle dashboard: total messages sent, delivered and errored, SMPP connection showing disconnected, HA failover state, an active support contract expiring 2027-06-11, a firmware update available notice for version 6.31, and per-channel graphs for messages sent, errors, inbox and outbox queue across SMS, email, WhatsApp and Signal.
Message totals and per-channel queues, SMPP, HA failover, support and firmware.

How it works

Everything comes from the SMSEagle APIv2 — no SNMP to configure. A json-exporter sidecar maps the JSON responses onto Prometheus metrics, and Grafana Alloy scrapes those and remote-writes them to Grafana Cloud.

SMSEagle APIv2 · JSON json-exporter :7979 · Prometheus Grafana Alloy scrape · UI :12345 Grafana Cloud remote_write mock-smseagle offline · :8088
Three containers. Swap the device for the bundled mock with one line in .env.
ServiceImagePurpose
alloygrafana/alloy Scrapes metrics and remote-writes to Grafana Cloud. UI on :12345.
json-exporterprometheuscommunity/json-exporter Maps SMSEagle JSON onto Prometheus metrics. :7979.
mock-smseaglenginx:alpine Serves captured API responses for offline development. :8088.

Quick start

git clone https://github.com/dmitrylambert/grafana-monitoring.git
cd grafana-monitoring/smseagle-monitoring
cp .env.example .env    # APIv2 token + Grafana Cloud Prometheus credentials
docker compose up -d

Then check it locally — the Alloy UI on http://localhost:12345, and the mock API on http://localhost:8088/api/v2/modem/full_info.

Build it without the device

The repo ships captured API responses, so you can develop offline. Toggle the source with one line, then restart — config and environment changes need a restart, not up -d:

# MOCK (offline, no device needed):
SMSEAGLE_API_URL=http://mock-smseagle/api/v2
# LIVE (requires LAN access to the device):
# SMSEAGLE_API_URL=https://<device-ip>/api/v2

docker compose restart alloy

The APIv2 token travels as the access_token query parameter, so the mock simply ignores it — any dummy value works offline. While you are on the mock, values are static: status panels read green and graphs stay flat.

Metrics it collects

MetricLabelsAPI source
smseagle_modem_signal_strengthmodem_no, net_name, sim_status, registration_status, imei/modem/full_info
smseagle_modem_enabledmodem_no/modem/full_info
smseagle_modem_sim_statusmodem_no, sim_status/modem/full_info
smseagle_modem_network_registrationmodem_no, registration_status/modem/full_info
smseagle_messages_{inbox,outbox,sent,error,delivered}channel — sms, whatsapp, signal, email/messages/count
smseagle_update_availableversion/device/version
smseagle_support_activeexpiry_date/device/support
smseagle_service_enabledservice — snmp, mqtt, email2sms, data_conn/device/<svc>/status
smseagle_smpp_{enabled,connection,core,sms,sql}/device/smpp/status
smseagle_ha_failover_statestatus/device/ha_failover/status
smseagle_temperature_celsiussensor_id/device/temperature_sensor/<id>/read
smseagle_humidity_percentsensor_id/device/temperature_sensor/<id>/read

Alerts worth setting

Four queries that catch the failures that actually matter on a gateway:

smseagle_messages_outbox{channel="sms"} > 20               # outbox backing up
increase(smseagle_messages_error{channel="sms"}[15m]) > 0  # new send failures
smseagle_modem_sim_status{sim_status!="Operational"}       # SIM problem
smseagle_modem_signal_strength < 30                        # weak signal

Importing the dashboard

The dashboard lives at dashboards/smseagle.json. In Grafana, open Dashboards → New → Import, upload the file or paste its JSON, then pick the Prometheus data source that receives your SMSEagle metrics — the dashboard ships parameterised, so it will prompt you.

Panels reading "No data"? Confirm the metrics are actually arriving by querying {__name__=~"smseagle_.+"} in Explore, and check you picked the right data source. The dashboard opens on the last 6 hours.

Re-importing the same JSON with the same UID overwrites your copy — Grafana warns first. To keep local edits, import under a new name or change the UID beforehand.

Adding more endpoints

The SMSEagle API exposes more than this dashboard uses. To pull in another endpoint:

  1. Add a module mapping in json-exporter/config.yml — paths use Kubernetes JSONPath, so {.field} selects a field, {[*]} iterates an array and {$} takes a single object.
  2. Add a scrape target in alloy/config.alloy.
  3. docker compose restart json-exporter alloy.

Need this watching something bigger?

The same pattern — API to Prometheus to Grafana — works for almost any device or service that exposes JSON. Tell me what you need visibility into and I will reply with how I would approach it.