Appearance
Monitoring
Quikcast gives you three ways to see what is happening: health checks (is it alive?), metrics (numbers over time), and logs (what happened and why). All three work without any extra software.
Health checks
The private admin address (admin_listen, default 127.0.0.1:9090) has two endpoints for load balancers, Docker and uptime monitors:
| Endpoint | Meaning |
|---|---|
/health/live | The process is up. Returns 200. |
/health/ready | The server is accepting new work. Returns 200, or 503 while draining or shutting down. |
sh
curl -fsS http://127.0.0.1:9090/health/readyReady does not mean "on air"
Readiness only says the server is accepting connections. It does not check that an encoder is connected or that audio is playing. To alert on a silent station, watch the active_sources metric below.
Prometheus metrics
GET /metrics on the admin address returns standard Prometheus text. Add it to your prometheus.yml:
yaml
scrape_configs:
- job_name: quikcast
static_configs:
- targets: ['127.0.0.1:9090']Because the admin address only listens on localhost, run Prometheus on the same machine, or scrape through an SSH tunnel or a private network. Don't publish the port.
Useful numbers
| Question | Metric |
|---|---|
| Is a source connected? | active_sources (active_mounts is the same number: mounts that currently have a source) |
| How many people are listening? | active_listeners |
| Is audio flowing? | rate(bytes_served_total[1m]) |
| Are listeners being dropped for being too slow? | rate(slow_consumers_total[5m]) |
| Are we refusing connections? | rate(admission_rejections_total[5m]) |
| Did my last reload work? | config_reload_failures_total and config_generation |
| Is a relay struggling? | rate(relay_failures_total[5m]), relay_cycles_exhausted_total |
| Are logs being dropped? | logging_dropped_total |
The full list is in the metrics reference.
Example alerts
yaml
groups:
- name: quikcast
rules:
- alert: StationOffAir
expr: active_sources == 0
for: 2m
annotations: { summary: "No encoder connected to Quikcast" }
- alert: ReloadFailed
expr: increase(config_reload_failures_total[10m]) > 0
annotations: { summary: "A Quikcast config reload was rejected" }
- alert: ListenersBeingDropped
expr: rate(slow_consumers_total[5m]) > 0.1
for: 10m
annotations: { summary: "Listeners are falling behind" }Live details from the API
For a snapshot of one stream or one listener, use the management API. Common reads:
sh
TOKEN=$(cat secrets/management-token)
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:9090/api/stats
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:9090/api/mountsListener history
Quikcast keeps the last 24 hours of listener numbers in memory: peak concurrent listeners and new listeners per minute, and an estimate of unique listeners per hour.
sh
# Server-wide, last 60 minutes
curl -H "Authorization: Bearer $TOKEN" \
"http://127.0.0.1:9090/api/history?minutes=60"
# One mount
curl -H "Authorization: Bearer $TOKEN" \
"http://127.0.0.1:9090/api/history?mount=/radio.mp3&minutes=1440"Unique-listener counts are estimates (about 3% error) and listener addresses are never stored. History is lost when Quikcast restarts. For anything you want to keep for months, scrape the metrics into Prometheus. See the API reference for the response format.
Logs
Quikcast writes one structured line per important event to standard output: sources connecting, listeners joining, reloads, relay failovers and errors.
text
INFO quikcast::mounts: source admitted mount=/radio.mp3 source_id=1 content_type="audio/mpeg" codec="mp3"
INFO quikcast::mounts: source closed mount=/radio.mp3 bytes_received=86562 disconnect_reason="shutdown"Change how much is logged with log_filter, for example:
toml
log_filter = "quikcast=debug" # also shows each listener and the reason for each access denialor temporarily with the QUIKCAST_LOG environment variable.
Where logs go matters
Logs are written through a fast, non-blocking buffer. Standard output must be a terminal, a pipe, or the systemd journal, something that is actively read. Redirecting straight to a regular file (> quikcast.log) is refused at startup. Under systemd or Docker this is automatic. From a shell, pipe through tee: quikcast --config q.toml | tee quikcast.log.
If the reader stops, Quikcast drops log lines rather than freezing your stream, and counts them in logging_dropped_total.
Passwords, tokens and Authorization headers are never logged.