Skip to content

Monitoring and status endpoint

Operations teams monitor ZMS in production using open-source observability tools. The City of Munich lists Grafana among its approved OSS stack for visualizing metrics in real time; deployments typically pair Grafana with a metrics backend (for example Prometheus) and optional log aggregation for JSON application logs.

This page describes what ZMS exposes for that kind of monitoring and how it fits together with Monolog logging.

Status endpoint (GET /status/)

zmsapi serves operational metrics at:

http
GET /terminvereinbarung/api/2/status/

(Adjust host and API base path to your environment.)

The response follows status.json. ReDoc: zmsapi API reference.

Query parameter: includeProcessStats

ValueBehaviour
1 (default)Full payload including processes aggregates (extra DB work)
0Skips process aggregates — faster for simple health checks (DB cluster, mail queue, version)

Use includeProcessStats=0 for high-frequency liveness probes; use 1 for dashboards that track appointment volumes.

To include the processes aggregates in the response, call the endpoint with includeProcessStats=1 (default). The aggregates are available under .data.processes.

processes metrics (high level)

Counts are for non-follow-up rows in buerger (istFolgeterminvon empty), same filter as the status SQL.

FieldMeaning
confirmed, reserved, called, parked, missed, deleted, blocked, pendingCount per buerger.status
withExternalUserIdProcesses with OIDC / citizen external_user_id set (any status)
confirmedWithExternalUserIdConfirmed appointments linked to an external user (set on appointment update in zmscitizenapi, after reservation)
sinceMidnight, last7days, lastInsertBooking activity (not a total of all processes)
outdated, outdatedOldest, freeSlots, lastCalculateSlot maintenance (added when stats are included)

OIDC-linked counts help track adoption of citizen login and “my appointments” flows (zmscitizenapi).

Other sections

SectionUse in monitoring
database.nodeConnections, database.locks, database.clusterStatusDB pressure and cluster health
database.problemsConfiguration warnings (non-empty string)
mail.queueCount, mail.oldestSecondsOutbound mail backlog
sources.dldb.lastLast DLDB import
useraccounts.activeSessionsLogged-in admin users (when present)
versionDeployed API version

Grafana and real-time dashboards

A typical setup:

  1. Scrape GET /status/ on an interval (Prometheus json_exporter, custom script, or agent that parses JSON).
  2. Expose numeric fields as time series (for example zms_processes_confirmed, zms_mail_queue_oldest_seconds).
  3. Visualize in Grafana with alerts on thresholds (mail backlog, nodeConnections, zero clusterStatus, etc.).

ZMS does not ship ready-made Grafana dashboards in this repository; each environment defines targets, intervals, and alert rules. The status payload is stable JSON intended for that integration.

flowchart LR
  zmsapi["zmsapi GET /status/"]
  scraper["Metrics scraper\n(Prometheus / agent)"]
  tsdb["Time-series DB"]
  grafana["Grafana dashboards"]

  zmsapi --> scraper --> tsdb --> grafana

Logs vs metrics

SignalSourceTypical tool
Metrics (counts, queues, DB load)GET /status/Grafana + Prometheus (or equivalent)
Structured logs (errors, audit, cron)App::$log JSON on stderr/stdoutLoki, ELK, or platform log drain

See Monolog logging for log levels, DEBUGLEVEL, and the generated log call inventory.

  • API reference — ReDoc for zmsapi and zmscitizenapi
  • Monolog logging — application logging
  • Implementation: zmsapi/src/Zmsapi/StatusGet.php, zmsdb/src/Zmsdb/Status.php