Monitoring and health
Prometheus metrics
Section titled “Prometheus metrics”metrics: enabled: true addr: "127.0.0.1:9101" readiness_grace: 30sWith metrics.enabled, the runner serves three endpoints on metrics.addr:
| Endpoint | Purpose |
|---|---|
/metrics |
Prometheus exposition of the runner’s own metrics |
/healthz |
liveness: the process is up |
/readyz |
task admission: 503 while a health check reports the machine as unavailable, once polling has been failing for longer than readiness_grace, or after the runner has been deleted on the instance |
There is no authentication on this listener. The default address binds to localhost only; expose it more widely (":9101") only behind a firewall or a scrape-only network.
All series are prefixed with gitea_runner_, among them:
| Metric | Meaning |
|---|---|
gitea_runner_info |
always 1, with the version and runner name as labels |
gitea_runner_uptime_seconds |
seconds since the daemon started |
gitea_runner_capacity / gitea_runner_job_running / gitea_runner_job_capacity_utilization_ratio |
configured capacity, jobs in flight, and their ratio |
gitea_runner_job_total |
jobs by result (success, failure, cancelled, skipped, unknown) |
gitea_runner_job_duration_seconds |
job duration histogram |
gitea_runner_poll_fetch_total / gitea_runner_poll_fetch_duration_seconds |
task fetches by result (task, empty, error) and their latency |
gitea_runner_poll_backoff_seconds |
last polling backoff interval |
gitea_runner_report_log_total / gitea_runner_report_state_total |
log and state reports by result |
gitea_runner_report_log_buffer_rows |
log rows buffered but not yet sent |
gitea_runner_client_errors_total |
RPC errors by method |
Useful things to alert on: gitea_runner_poll_fetch_total{result="error"} rising (the instance is unreachable or the runner was deleted), a capacity_utilization_ratio pinned at 1 (the pool is too small), and a growing report_log_buffer_rows (log delivery is falling behind).
Local health checks
Section titled “Local health checks”Health checks let a runner take itself out of rotation when the machine it runs on is not fit for work — most commonly when the disk is full.
health_check: enabled: false min_free_disk_space_mb: 1024 script: '' interval: 30s timeout: 10s- while a check fails, the runner stops fetching new tasks; jobs already running are unaffected and finish normally;
- no check runs while a job is active — the last result is reused until the runner is idle again;
min_free_disk_space_mbis measured on the filesystem holding the runner’s workspaces, and defaults to 1024 MiB when omitted or zero;scriptis any executable. A non-zero exit, a timeout, or a failure to start marks the runner unavailable. Its result is cached forintervaland it is killed aftertimeout;- recovery is automatic and logged (
runner local health recovered, resuming task polling), and the state is reflected by/readyz.
The runner logs to stderr; log.level controls the verbosity, with debug and trace adding file:line to each line. Under systemd the log ends up in the journal (journalctl -u gitea-runner), in Docker in docker logs.
The runner log is not the job log: step output is streamed to Gitea and is tuned with the runner.log_report_* settings, while things like post-task script output only ever appear in the runner log.
Reporting a problem
Section titled “Reporting a problem”gitea-runner bug-report prints the version, Go version, OS/architecture and CPU count — paste its output into an issue at gitea/runner:
gitea-runner bug-reportRunner version: 3.0.2Go version: go1.26.5OS/Arch: linux/amd64NumCPU: 8To reproduce a workflow locally, without a Gitea instance and without touching the runner’s registration, use gitea-runner exec — see the command line reference.