Add ox_health --format json for machine-readable output - #41
Conversation
|
Pushed a follow-up commit: Verified locally:
|
|
Thanks @burakeyler, a few things before I merge:
|
A healthcheck or monitoring agent wanting the figures had to parse the OK line or re-query the database. `--format json` prints one object with the same figures (backlog, oldest age, last claim age) plus `ok` and the list of problems. On a failing check the object is still printed before the same CommandError, so the exit status keeps its meaning and the numbers are there when they matter most. Text output is unchanged. Closes oxpull#36 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Rebases onto main (CHANGELOG entries combined under one Added heading). ox_health --format json now prints the object (ok: false, figures null) before raising CommandError on an invalid --max-backlog/--max-age/ --worker-timeout, matching the existing database-unreachable path. Adds the --format row to README.md and docs/monitoring.md, clarifies that null also covers a check that could not run, and regenerates docs/llms-full.txt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
57702e7 to
49d3c1a
Compare
|
Thanks for the detailed review — all five addressed in the latest push:
Verified locally:
PostgreSQL test run also not done here (no local Postgres in this environment) — relying on CI for that leg. |
|
The one red job on the latest push is |
The README, configuration and monitoring tables each described --format in slightly different words, and only one named the cases where the figures are null. All three now carry the same row. The validation helper in handle() always raises, so it is typed NoReturn rather than None.
|
Thanks @burakeyler, merged. All five points landed cleanly, and the test for an invalid threshold was exactly what was missing. The red Postgres job was a flaky supervisor test, not your change. |
Closes #36
Output
python manage.py ox_health --format json --max-backlog 1{"ok": false, "queue": null, "backlog": 2, "oldest_age_seconds": 41.3, "last_claim_age_seconds": null, "problems": ["backlog is 2, over --max-backlog 1"]}timedelta.total_seconds()floats,nullwhere the text form saysnone.problemsholds the same strings theCommandErrorjoins with"; ".The question the issue asked to settle
On failure, JSON prints the object and still exits non-zero.
handle()writes the object to stdout, then raises the sameCommandErroras before. So the exit status (and the stderr reason) are identical to text mode, and stdout always has a parseable object.That includes database unreachable: the object is printed with
backlog/agesnullandproblems: ["Database unreachable: ..."].Only the reporting at the end of
handle()changed. The default output and the checks themselves are untouched.Tests (
tests/test_health.py, 4 new)problems: [].--queuegivesnullages and echoes the queue.ok: falseand both problems, and the raisedCommandErrormessage equals the joined problems.Gates (local, Windows, SQLite)
pytest -q tests/test_health.py: 45 passed.ruff check .,ruff format --check .,mypy --strict src/,tools/check_release.py: pass.mkdocs build --strict.--formatrow in theox_healthtable indocs/configuration.md.This is independent of #40 (
ox_prune --queue); both touchCHANGELOG.mdunder Unreleased, so whichever lands second may need a trivial rebase.🤖 Generated with Claude Code