Metrics for the worker's job, the queues and the work in flight (#195)
The healthcheck answers while the worker is stuck on one job, and nothing showed which job or for how long. STATS, one static of atomics, is kept as the work happens: the worker's job and since when (a guard, so a failed or stopped job is counted too), jobs and their seconds by kind, when a scan last finished, web requests, feed fetches and downloads in progress, bytes downloaded, live updates dropped for a listener that fell behind, DeadAir's backlog and how long it has been on its file, and the artwork kept. With the event queue, the DNS retries and the healthcheck's last counts, /metrics still reads memory only. The dashboard's Daemon row and the prod-check skill take them up. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -68,6 +68,16 @@ from 2026-10-11 15:15 UTC. All gauges:
|
||||
| `ipx_runtime_workers`, `ipx_runtime_tasks`, `ipx_runtime_queue` | tokio: threads, live tasks, tasks waiting for a thread |
|
||||
| `ipx_process_resident_bytes`, `ipx_process_open_fds` | memory and open files and sockets |
|
||||
| `ipx_uptime_seconds`, `ipx_build_info{version}` | since the daemon started; what runs |
|
||||
| `ipx_worker_busy`, `ipx_worker_job_seconds{kind}` | the worker's job now (`scan`, `reap`, `download`, `status`, `reload`) and for how long; the healthcheck passes while it is stuck |
|
||||
| `ipx_jobs_total{kind}`, `ipx_job_seconds_total{kind}` | counters: jobs finished, and their seconds all told |
|
||||
| `ipx_last_scan_age_seconds` | since a scan last finished; absent until one has since starting |
|
||||
| `ipx_http_requests_in_flight`, `ipx_scan_feeds_fetching`, `ipx_downloads_active` | work in progress |
|
||||
| `ipx_download_bytes_total` | counter; `rate()` is the download speed |
|
||||
| `ipx_event_queue`, `ipx_events_missed_total` | live updates unread by some listener; counter of those dropped for one that fell behind |
|
||||
| `ipx_deadair_backlog`, `ipx_deadair_busy_seconds` | files of shows with DeadAir on not yet looked at (episodes everyone heard through stay counted); how long it has been on its file |
|
||||
| `ipx_feed_retries` | feeds waiting to retry a failed name lookup |
|
||||
| `ipx_art_cache_bytes`, `ipx_art_cache_limit_bytes` | artwork kept, as of the last sweep, and the most kept |
|
||||
| `ipx_feeds`, `ipx_downloads_pending`, `ipx_files_downloaded` | the library, as the healthcheck last counted it (every 30 s) |
|
||||
|
||||
## The checks
|
||||
|
||||
@@ -135,6 +145,12 @@ a count says something happened, the lines and traces say why.
|
||||
$Q prom 'ipx_process_resident_bytes{job="ipx"} - ipx_process_resident_bytes{job="ipx"} offset $range' 24h
|
||||
$Q prom 'ipx_process_open_fds{job="ipx"} - ipx_process_open_fds{job="ipx"} offset $range' 24h
|
||||
$Q prom 'ipx_runtime_tasks{job="ipx"} - ipx_runtime_tasks{job="ipx"} offset $range' 24h
|
||||
$Q prom 'max(max_over_time(ipx_worker_job_seconds{job="ipx"}[$range])) by (kind)' 24h
|
||||
$Q prom 'max(max_over_time(ipx_last_scan_age_seconds{job="ipx"}[$range]))' 24h
|
||||
$Q prom 'sum by (kind) (increase(ipx_job_seconds_total{job="ipx"}[$range]))' 24h
|
||||
$Q prom 'max(max_over_time(ipx_http_requests_in_flight{job="ipx"}[$range]))' 24h
|
||||
$Q prom 'sum(increase(ipx_events_missed_total{job="ipx"}[$range]))' 24h
|
||||
$Q prom 'max(max_over_time(ipx_deadair_busy_seconds{job="ipx"}[$range]))' 24h
|
||||
```
|
||||
`up` 0 means Prometheus cannot reach the port: the container is down or `metrics_bind` is
|
||||
unset. Connections in use at the pool's max (10 on Postgres) means something is waiting for
|
||||
@@ -145,6 +161,13 @@ a count says something happened, the lines and traces say why.
|
||||
is a leak (a file or socket not closed, a task never ending); a step after a deploy is not. A
|
||||
reset of the uptime is a restart: match it with a deploy, or it is a crash (check 4).
|
||||
|
||||
The worker: one job over 30 minutes (`ipx_worker_job_seconds`), or a scan last finished over
|
||||
15 minutes ago, is the worker stuck, which the healthcheck does not notice; its trace and the
|
||||
log lines of that time say on what. A kind whose share of `ipx_job_seconds_total` jumps is
|
||||
where the worker's time went (reap was most of it until #193). Web requests in flight near
|
||||
the pool's max mean the pool is what they wait on. Live updates missed mean a page showed stale
|
||||
counts until reloaded. DeadAir over a minute on one file is a file ffmpeg chokes on.
|
||||
|
||||
Also check the container itself, since Loki cannot see a daemon that is not running:
|
||||
|
||||
```sh
|
||||
|
||||
Reference in New Issue
Block a user