Health File¶
When the COSALETTE_HEALTH_FILE environment variable names a path, the app
writes its heartbeat to that file and the health probes check it
(ADR-083).
This page is the contract between the writer and the probes. The native
cosalette-health binary and the Python probes implement the same rules and
share one set of test fixtures
(ADR-087).
Format¶
The file is one JSON object, written atomically:
{
"health_file_version": 1,
"written_at": 1791100800.25,
"interval": 60.0,
"status": "online",
"uptime_s": 3600.0,
"devices": {
"sensor": {"status": "ok"},
"relay": {"status": "stale"}
}
}
| Key | Required | Meaning |
|---|---|---|
health_file_version |
no | Contract major version, an integer. A missing key means 1. |
written_at |
yes | Unix time of the write, in seconds. Must be a finite number. |
interval |
no | Seconds between writes. A missing, non-numeric or non-positive value means 60. |
devices |
no | Device name mapped to an object with a string status. Entries of any other shape are ignored. |
The probes ignore every other key, including the rest of the
heartbeat payload. The file must be strict JSON: NaN,
Infinity and numbers that overflow to infinity make it unreadable. Integers
outside the signed/unsigned 64-bit range are represented as finite floating
point values when possible, matching serde_json; values too large for a finite
float make the file unreadable.
Checks¶
A probe reports the file unhealthy at the first of these that applies:
- The file does not exist, cannot be read, or is not valid JSON.
- The top-level value is not an object.
health_file_versionis not an integer, or is a version the probe does not know. A newer writer therefore never passes an older probe.written_atis missing or not a finite number.- The file is older than
--max-age, which defaults to three timesinterval. - A device's
statusis listed in--fail-on(default:stale).
Otherwise the file is healthy.
Versioning¶
The current version is 1. Adding optional keys does not change the version,
because probes ignore keys they do not know. A change that an older probe would
misread, such as renaming written_at or changing its unit, needs a new major
version and probes that accept it.
Probes¶
| Command | Installed by | Cost per run |
|---|---|---|
cosalette-health |
every install of cosalette |
about 1 ms and 2 MiB (native), about 60 ms and 15 MiB (Python fallback) |
cosalette health |
every install of cosalette |
about 390 ms and 46 MiB |
myapp health |
your app's CLI | the app's import time on top of cosalette health |
All of them exit 0 when healthy and 1 otherwise, including on usage errors.
See Health Probe for the options and
Health Checks for when to run a probe
at all.
Native binary or Python fallback
Platform wheels contain cosalette-health as a native binary for Linux
x86_64, aarch64 and armv7, with glibc 2.17 or newer or with musl
(Alpine), macOS x86_64 and arm64, and Windows x86_64 (see
Supported platforms).
Elsewhere, for example on armv6, cosalette-health is a Python script with the
same options and exit codes and imports only the standard library. A source
install still builds the required cosalette-filters-rs extension through
maturin/PyO3, so it needs Rust when no matching wheel is available; the
health fallback adds no further Rust build requirement.
head -c 4 "$(command -v cosalette-health)" | od -c shows 177 E L F for
the native binary on Linux and #! for the Python script.