feat: ADD Prometheus endpoint for simple app monitoring #30

This commit is contained in:
Caffeine Fueled 2026-07-24 23:10:27 +02:00
parent e42e55c7e4
commit 082a9f81d7
Signed by: cf7
GPG key ID: CA295D643074C68C
2 changed files with 131 additions and 1 deletions

View file

@ -16,7 +16,7 @@ The goal is to keep it simple! For feature-rich solutions please check out [hedg
## Features
**Use cases:**
- shared notepad across multiple machines
- shared notepad across multiple machines and users
- collaboration on the same notepage with multiple people (notes, config, etc)
- piping configs: `curl -o app.conf https://aukpad.com/{pad_id}/raw` → edit in aukpad → repeat
@ -33,6 +33,7 @@ The goal is to keep it simple! For feature-rich solutions please check out [hedg
- `GET /{pad_id}/raw` — raw text (auth via `?pw=…` for protected pads)
- `GET /system/info` — instance configuration page
- `GET /health` — JSON health check (200 `ok` / 503 `degraded`)
- `GET /system/metrics` — Prometheus metrics, disabled by default (see *Monitoring*)
- WebSocket `/ws/{pad_id}` — live collaboration
**Deployment:**
@ -128,6 +129,35 @@ The following environment variables can be configured:
| `MAX_ROOMS` | `10000` | Maximum number of pads kept in memory; new pads are refused (WS close 1008) when full until cleanup reclaims space |
| `TRUST_PROXY` | `false` | If `true`, read the client IP from `X-Forwarded-For` (first entry) or `X-Real-IP` for per-IP rate/connection limits. Only enable when aukpad sits behind a reverse proxy that strips/sets these headers — otherwise they can be spoofed |
| `DESCRIPTION` | `powered by aukpad.com` | Instance description shown on info page |
| `ENABLE_METRICS` | `false` | Serve Prometheus metrics on `/system/metrics`. While `false` the path returns 404 |
| `METRICS_KEY` | *(empty)* | If set, scrapes must send `Authorization: Bearer <key>`. Empty means no auth — only sane if the path is blocked at the reverse proxy |
---
## Monitoring
- `/health` simple healthcheck
- `/system/metrics` optional Prometheus endpoint
| Metric | Description |
|--------|-------------|
| `aukpad_rooms` | Pads currently held in memory |
| `aukpad_rooms_active` | Pads with at least one connected peer |
| `aukpad_rooms_protected` | Pads with a password set |
| `aukpad_peers_connected` | Live WebSocket peers across all pads |
| `aukpad_peers_authenticated` | Peers past authentication; a gap vs. the above means clients are stuck at the password prompt |
| `aukpad_stored_bytes` | Total UTF-8 bytes of all pad text |
| `aukpad_pad_bytes_mean` / `aukpad_pad_bytes_max` | Mean and largest pad size in bytes |
| `aukpad_pad_versions` | Sum of all pad version counters — a proxy for edit volume. Drops when pads are evicted, so use `deriv()`, not `rate()` |
| `aukpad_room_idle_seconds_max` | Age of the least recently used pad; shows whether cleanup is keeping up |
| `aukpad_client_ips` / `aukpad_ip_connections_max` | Distinct IPs connected, and the busiest single IP |
| `aukpad_pads_created_last_hour` | Rolling pad creations via `POST /`, all IPs |
| `aukpad_auth_failures_recent` | Failed pad passwords inside the 60s window — brute-force signal |
| `aukpad_cache_enabled` / `aukpad_cache_up` | Valkey configured, and answering `PING` right now |
| `aukpad_cache_keys` | Keys in the Valkey database (all of them, if the DB is shared) |
| `aukpad_max_rooms`, `aukpad_max_text_bytes`, `aukpad_max_connections_per_ip`, `aukpad_retention_seconds` | Configured limits, so alert rules can use ratios instead of hardcoded numbers |
| `aukpad_start_time_seconds` | Unix start time; uptime is `time() - aukpad_start_time_seconds` |
| `aukpad_build_info` | Always 1, carries `DESCRIPTION` as a label |
---