Run the advisor as a service

Always-on checks per target with a read-only JSON API.

pgdba serve turns the one-shot checker into an always-on advisor: it runs each fleet target on its own schedule, keeps the latest report plus a rotating history per target, and serves them over a read-only local HTTP API. No cron, no external orchestration.

Setup

Serve reads the same fleet file as fleet check, plus per-target interval (seconds, default 3600, jittered ±10%), alert thresholds, and webhooks:

# pgdba-fleet.toml
[fleet.targets.prod]
connection = "prod"
interval = 1800
warning = 1
critical = 1
webhook_url = "https://alerts.example.com/hook"

[fleet.targets.stage]
connection = "stage"
skip_heavy = true
pgdba serve --state-dir /var/lib/pgdba-serve
# pgdba serve listening on 127.0.0.1:8420

Each target keeps the standard artifacts under <state-dir>/targets/<name>/ — pgdba-report.json, runs.jsonl, pgdba-audit.jsonl, pgdba-baseline.json — the same layout fleet check writes, so the two interoperate: point them at one directory and --fail-on-drift baselines saved by either are honored by both. Scheduled runs reuse the CLI pipeline exactly (thresholds, webhooks, drift), and every run appends to the audit journal.

One-shot mode

pgdba serve --once runs exactly one scheduling pass over all targets and exits with the worst per-target exit code — the same loop logic, for cron or supervisor users who want the orchestration without the daemon.

The API

Local only by design: the server binds 127.0.0.1:8420 unless --bind names another address, and a non-loopback bind refuses to start without --i-know-this-is-unauthenticated. There is no auth and no TLS — keep it on localhost or behind your own proxy. Full endpoint reference: serve API.

Operations

  • Single instance: the state dir holds pgdba-serve.pid; a second start exits 3 naming the live pid. A stale pidfile (dead pid) is replaced with a warning.
  • Shutdown: SIGTERM/SIGINT stop scheduling; in-flight checks finish (bounded by the 120s wall cap each) before the pidfile is released. History files are atomic rewrites, so a kill can never leave them half-written.
  • Logs: JSON lines on stderr, run-id annotated, like --agent runs.