Skip to main content

Monitoring

:::info Status Implemented. Source: DEPLOY.md. :::

Health endpoint

/health/detail (behind X-Monitoring-Token) is where the Super Admin Health page and external monitors look. It folds broker metrics in alongside application health:

curl -s -H "X-Monitoring-Token: $MONITORING_TOKEN" \
https://azan360.com/health/detail | jq .broker

Requires EMQX_API_KEY / EMQX_API_SECRET on both the emqx and fastapi-backend services — the emqx service mints the key at first start, the backend authenticates with it (core/broker_metrics.py). Unset, the block reports not_configured — not an error, an honestly unmonitored broker.

Broker metrics to watch

FieldMeans
mqtt_connections vs. the device registry's ACTIVE countthe gap is the fleet going dark
mqtt_messages_received_ratefar above the modeled ~18/s at 5,000 units suggests a firmware bug before it suggests growth
mqtt_authn_failures / mqtt_authz_denieda device that can't connect reports nothing itself — this is the only place a broken credential rollout is visible
mqtt_memory_used_pct, mqtt_max_fdsthe two ways a single-node broker dies quietly

Rates are derived from two samples: the first call after a backend restart reports null (not 0) — 0 would misleadingly read as "the fleet went silent." A counter that goes backwards (broker restarted) also reports null rather than a fake spike.

The scrape credential is administrator-scoped (per-key RBAC is EMQX Enterprise-only) — what limits blast radius is that the listener carrying it is never published, not the key's own scope.

What a broker outage costs

Scheduled azaan keeps playing from cached device config for as long as the entitlement lease holds; Bluetooth on a stream player is unaffected; app installs never touch the broker at all. What stops: live broadcast play commands, status/heartbeat, and config changes (the last of which queue in the outbox and drain on recovery). Retained state is rebuildable from devices.config via POST /api/v1/super-admin/republish-retained — which is why a single broker node is defensible as a first stage; see Device Deployment.

Traces and metrics

Observability covers fastapi-backend's own request/broadcast/MQTT tracing and metrics — a different surface from the broker metrics above (this section is about the EMQX broker specifically; that page is about the backend's own behavior). Two dashboards, both auto-provisioned in Grafana:

  • Azan360 — Broadcast & Backend Observability — broadcast fan-out duration/errors, FFmpeg spawn time, MQTT publish duration/failures, push delivery by provider, HTTP request duration.
  • Azan360 — Traces — quick-view trace tables (Recent/Error/Slow), click-through to the full span waterfall.

The broadcast fan-out trace (broadcast.started/broadcast.ended) is always 100% sampled regardless of the general 10% ratio — see Observability — Sampling for why.

Broadcast delivery

Broadcast Audit is the primary delivery-analytics surface — per-broadcast push send/failure counts and MQTT timing, queryable via /api/v1/broadcast-audit/* and visible on the Super Admin Broadcast Audit screen.

Rollout gates

Two staged rollouts expose their own monitoring queries before flipping to enforce — see Backend Deployment for the FANOUT_V2 and STREAM_AUTHZ_ENFORCE gate-check SQL.