Observability
View as MarkdownMonitoring, logs and retention
Health endpoints#
| Endpoint | Meaning |
|---|---|
GET /healthz |
process is up (always {"status":"ok"}) |
GET /readyz |
process is up and the database answers (200 {"status":"ready"}, otherwise 503) |
nebulactrl-server healthcheck |
the same readiness probe run inside the container (used by the image's HEALTHCHECK and Compose, so the check needs no curl). Reads NEBULACTRL_LISTEN; --url overrides. |
Use /readyz for load balancers and uptime monitors.
Logs#
The control plane writes JSON, one object per line, to stdout: docker compose logs -f nebulactrl. Level via NEBULACTRL_LOG_LEVEL. Every HTTP request is logged with method, path, status, duration and a request id. Lines produced while handling a deployment carry correlation_id = the deployment ID, so one deployment is traceable end to end:
docker compose logs nebulactrl | jq -c 'select(.correlation_id=="<deployment-uuid>")'Secrets are never logged. Values of secret variables (6+ characters) are replaced with •••••• before build/deploy/runtime log lines are stored or streamed.
Agent logs: journalctl -u nebulactrl-agent -f on the host (also JSON).
In the UI#
| What | Where | Retention |
|---|---|---|
| Build and deploy output | Deployment row → logs | stored per deployment, capped at 10,000 lines (a final marker line says so) |
| Runtime logs | Service → Logs, Environment → Observability | stored on each server by its agent, 7 days and 500 MB per service by default (configurable per server); Live streams, History searches the stored lines. Not available while the server is offline. Log history and drains |
| Audit log | Settings → Audit log (GET /api/v1/audit-events) |
kept indefinitely (not pruned) |
Resource metrics#
Collected from agent heartbeats (host: CPU, memory, disk) and container stats (per service: CPU, memory), sampled about every 10 seconds, the way Coolify's Sentinel does. Container memory is reported as usage minus inactive file cache.
| Setting (per server) | Default | Range | Effect |
|---|---|---|---|
metricsRetentionDays |
7 | 1–90 | Samples older than this are pruned by an hourly job. A 30d chart range only shows the history that is retained ("History kept for N days"). |
diskAlertThresholdPercent |
80 | 50–99 | Root-filesystem usage above this shows a warning on the server card and server page. |
Chart ranges: 5m, 10m, 30m, 1h, 6h, 12h, 24h, 7d, 30d; the response is bucketed to at most about 300 points, and the short ranges refresh every 5 s, the others every 15 s. Older data is downsampled into coarser buckets (the API reports stepSeconds).
Change the settings on the server page, or with PATCH /api/v1/servers/{serverId} (scope servers:write).
Traffic analytics#
Request analytics (requests, bandwidth, status classes, p95 latency, unique visitors, top paths, referrers, browsers, devices) are collected from the agent-managed Traefik's access log, on each host, as aggregates only. Raw access logs are never shipped or stored by the control plane. Unique visitors are hashed with a salt that rotates daily; raw IP addresses are never sent.
| Setting (per server) | Default | Effect |
|---|---|---|
trafficAnalyticsEnabled |
on | Turn collection off per server. Like Coolify, this recreates the proxy container (a brief proxy restart), because the access log is a static Traefik setting. |
trafficHourlyRetentionDays |
7 | Hourly buckets (fine-grained charts) kept this long. |
trafficDailyRetentionDays |
90 | Daily roll-ups kept this long. |
Views: service inspector → Analytics, server page → Analytics, environment → Observability. Each has a "Where requests come from" map (country, optionally city); see Traffic analytics and request origins for the GeoIP databases, licences and settings. Runtime logs can be shipped to Loki, OTLP, syslog or an HTTP intake: log drains.
Liveness semantics#
- A server is offline after 30 seconds without a heartbeat (the agent sends one every 10 s). The UI marks observations older than 30 s as stale instead of showing them as current.
- Each state change in the UI also appears as text or a glyph, not only as animation.
- Live updates use Server-Sent Events. If the connection drops the UI shows "Live updates paused — retrying" and falls back to polling every 15 s.
Capacity planning#
- Metrics volume is roughly (servers + running containers) samples per 10 s per retention window; the default 7 days is small. Raising retention to 90 days multiplies it by ~13.
- The agent keeps the 5 newest built images per service (
imageRetention) and prunes the builder cache older than 7 days daily. Watch the disk gauge on the server card.