llms.txt
Search Documentation
Search through all documentation pages
Core Concepts

Heartbeat Monitor

Push health signals from jobs, workers, and external systems

Heartbeat monitors are push-based: your job calls a URL, and Kener measures how long it has been since the last signal.

Heartbeat endpoint

URL format:

/ext/heartbeat/{tag}/{secret}

Accepted methods: GET and POST.

Older heartbeat URLs used a colon — /ext/heartbeat/{tag}:{secret}. Those still work; they are rewritten to the path-separated form automatically, so existing cron jobs need no changes.

Heartbeat secret

The {secret} part of the URL is the heartbeat secret. The monitor tag is public, so the secret is what stops others from sending fake heartbeats. Kener stores it in type_data.secretString.

Rule: at least 12 characters, using only A-Z a-z 0-9 . _ ~ -. A secret that follows the rule goes into the URL without encoding.

  • Admin UI: type a value in Heartbeat secret, or click New URL for a random one.
  • API: set type_data.secretString on POST /api/v4/monitors or PATCH /api/v4/monitors/{tag}. A new or changed value that breaks the rule returns HTTP 400 with code BAD_REQUEST, and the message starts with Heartbeat secret breaks the rule. See the API Reference.
  • Not set: when a HEARTBEAT monitor is saved without secretString, Kener generates one, for example focused-galois-sharp-chaum. The POST response includes it. GET and PATCH responses mask it.
  • Clone: a cloned heartbeat monitor gets a new secret. Give the sender the clone's URL.

Tip

For infrastructure as code, set secretString yourself when you create the monitor. Then the sender (a cron job, a Prometheus Alertmanager rule) can be configured with the URL before the monitor exists.

Kener checks the rule only for a new or changed secretString. A secret stored before the rule keeps working, and a save that sends it back unchanged succeeds.

Minimum setup

Set:

  • degradedRemainingMinutes (default 5)
  • downRemainingMinutes (default 10)

downRemainingMinutes must be greater than degradedRemainingMinutes.

Status logic

If no heartbeat has ever been received:

  • status is NO_DATA

Otherwise let diff = elapsed time since last heartbeat:

  • diff > downRemainingMinutes → DOWN
  • diff > degradedRemainingMinutes → DEGRADED
  • otherwise → UP

Latency is recorded as elapsed time since the last heartbeat (ms).

Example

Request body for POST /api/v4/monitors:

{
    "tag": "my-job",
    "name": "My job",
    "monitor_type": "HEARTBEAT",
    "type_data": {
        "degradedRemainingMinutes": 5,
        "downRemainingMinutes": 10,
        "secretString": "my-job-hb-secret-01"
    }
}

Minimal cron usage pattern:

*/5 * * * * /path/to/job.sh && curl -s "https://your-kener-host/ext/heartbeat/my-job/my-job-hb-secret-01"

Troubleshooting

  • Always NO_DATA: endpoint never called or wrong tag/secret
  • Invalid heartbeat secret: the URL secret does not match secretString. Copy the URL again from the monitor page, which shows the secret to users with monitors.write. API responses mask the secret, except the POST response that created the monitor.
  • Always DOWN/DEGRADED: thresholds too low for actual job interval
  • Signal accepted but stale: ensure heartbeat is sent only after successful completion