Skip to content

chap-checker

Python 3.13+ License: AGPL v3

A small command-line health-check and alerting tool for DHIS2 instances that integrate with chap-core via a DHIS2 route.

Operating a DHIS2 deployment with chap-core means several moving pieces all have to stay healthy at once:

  • the DHIS2 server itself (reachable, accepts credentials, reports a version),
  • the chap route on DHIS2 that proxies traffic to chap-core,
  • the chap-core service behind that route (alive, reports a version),
  • the modeling app on the DHIS2 frontend,
  • the climate app on the DHIS2 frontend.

chap-checker runs one HTTP probe per piece against each DHIS2 instance it's pointed at, rolls the results up into a non-zero exit code on any failure, and optionally fires alerts (Slack, generic webhook, or a custom transport) when something flips between OK and broken — transition-only, so a sustained outage produces one message on entry and one on recovery, not a ping every cron tick.

It's designed to be run by cron / a Kubernetes CronJob / any scheduler that cares about exit codes and a quiet stdout when everything is fine. You can also run it interactively for ad-hoc one-off checks, open the Textual dashboard for an at-a-glance TV view, or run chap-checker serve as a 24/7 daemon backing a browser dashboard and remote thin-client TUIs.

Install

# One-shot run without installing (no PATH pollution):
uvx chap-checker --version
uvx chap-checker verify --url https://dhis2.example.com --token-env DHIS2_TOKEN

# Persistent install into uv's isolated tool environment:
uv tool install chap-checker
chap-checker --version

# Upgrade to the latest release later:
uv tool upgrade chap-checker

# Or, if you're embedding into another uv project:
uv add chap-checker

Released versions are published to PyPI and the docs site tracks the latest tag. See Releasing for the operator-side release playbook.

Quick start

Ad-hoc against a single instance (credentials resolved safely):

# With a DHIS2 Personal Access Token (recommended on modern servers):
export PROD_TOKEN=...
chap-checker verify \
    --url https://dhis2.example.com \
    --token-env PROD_TOKEN

# With a password (Basic auth) read from a named env var:
export PROD_PASSWORD=...
chap-checker verify \
    --url https://dhis2.example.com \
    --username admin \
    --password-env PROD_PASSWORD

# Omit --password / --token entirely and you'll be prompted on the
# terminal (hidden input). DHIS2_TOKEN / DHIS2_PASSWORD env vars
# work as defaults too. Passing --password / --token inline still
# works but is discouraged - the value lands in shell history and
# `ps` output. Token and password flags are mutually exclusive.

Multiple instances in ./chap-checker.toml:

[instances.prod]
url = "https://dhis2.example.com"
username = "ops"
password_env = "PROD_PASS"
alerts = ["slack", "ops-webhook"]   # fan out to as many alerters as you opt in

[alerts.slack]
webhook_url_env = "SLACK_WEBHOOK_URL"

[alerts.ops-webhook]
url_env = "OPS_WEBHOOK_URL"          # generic HTTP POST with the canonical envelope

Then chap-checker verify runs every configured instance and fires the opted-in alerters on status transitions. chap-checker init writes a minimal annotated template if you'd rather start from a scaffold.

Where to go next

  • Configuration — the TOML file in detail.
  • Checks — what each built-in check does and how they depend on each other.
  • Custom checks — the @register_check decorator and Protocol contract for adding your own probe.
  • Alerting — Slack and generic-webhook transports, per-instance opt-in, transition semantics, delivery-failure retries.
  • CLI — every command and flag.
  • Cron — production deployment recipes.
  • TUI dashboard — the at-a-glance Textual UI (with --connect for cross-machine consistency).
  • Server — long-running daemon, browser dashboard, JSON state API, systemd autostart.

License

AGPL-3.0-or-later