Health endpoint
Expose one small JSON endpoint and Perch charts CPU, memory, disk, network, processes and Docker containers — and alerts when your app reports a failure or a resource crosses a limit.
Set up in 3 steps
- Step 1 of 3Create a health-endpoint monitorGo to Add monitor → Health endpoint. Enter where the endpoint will live and, optionally, CPU / memory / disk limits.
- Step 2 of 3Copy the secretThe monitor page shows your secret. Perch sends it as
Authorization: Bearer <secret>; your endpoint only answers when it matches. - Step 3 of 3Add the endpoint and test itAdd the endpoint with one of the Recipes below, set
PERCH_HEALTH_TOKEN, and press Test endpoint — Perch shows exactly what it understood and what is missing.
Recipes
Each recipe uses one of three ready-made files — download them directly: perch_health.py · perch-health.js · perch-health.php.
- Download the agent (one Python file) on the server you want to watch:
- Run it with your secret. It serves the health JSON on port 9105:
- Allow Perch to reach port 9105 in your firewall, then use this URL in Perch.
What Perch reads (Perch Health Spec v1)
Already have a health endpoint? Return this shape and Perch understands it. Every field is optional — send what you have; unknown fields are ignored. Respond with HTTP 200 (or 503 when failing).
| Field | Meaning |
|---|---|
status | pass, warn or fail (also accepts ok / healthy / degraded / error / down). Missing → derived from the HTTP code. |
checks | Your own checks (database, cache, queue…). A failing check is listed in the alert. |
redis[] | Redis your app uses: status, memory vs maxmemory, clients, evicted keys. The integration files fill it in by themselves from PERCH_REDIS_URL or REDIS_URL (else a Redis on 127.0.0.1:6379, if one answers); PERCH_REDIS_URL=off skips it. |
system.cpu.percent | CPU usage 0–100. load = 1, 5 and 15-minute load averages. |
system.memory | Give percent, or used_bytes + total_bytes and Perch calculates it. |
system.disks[] | One entry per mount; Perch alerts on the fullest one. |
system.network | Cumulative byte counters (rx_bytes, tx_bytes). Perch turns them into in / out rates. |
processes | Total count and up to 10 top processes. |
containers[] | Name, image, state, CPU and memory per container. |
When does Perch alert?
| Situation | Result |
|---|---|
| Endpoint unreachable, times out, or returns something that is not JSON | Down → incident + alert |
status: "fail" | Down; the alert names the failing checks |
A Redis with status: "fail" (unreachable, wrong password) | Down, e.g. Redis 127.0.0.1:6379 failing: connection refused |
| CPU / memory / fullest disk above the limit you set | Down, e.g. Disk 93% > 90% on / |
status: "warn" | Shown on the dashboard, no alert |
| HTTP 401 / 403 | Down with a hint to check PERCH_HEALTH_TOKEN |
Security
The recipes answer only when the Authorization header matches PERCH_HEALTH_TOKEN (constant-time comparison) and never include environment variables or command lines. Prefer HTTPS for endpoints on the public internet, or restrict the port to Perch in your firewall. You can create a new secret any time from the monitor page.
Troubleshooting
| Test endpoint says | Fix |
|---|---|
| Connection refused / timed out | The endpoint is not running or a firewall blocks Perch. For Standalone, open port 9105. |
| HTTP 401 — rejected Perch’s token | Set PERCH_HEALTH_TOKEN to the secret on the monitor page and restart the app. On Apache + PHP, keep CGIPassAuth On. |
| Response is not JSON | The URL points at a web page (often a login redirect). Use the exact endpoint path. |
| `system.memory` missing | On macOS / Windows the Python file needs pip install psutil for CPU and memory. |