← All projects Monitoring · reliability

Knowing when the triage agent stops

systemd · Elastic · healthchecks.io · Python · Bash

What this demonstrates: Monitoring the monitoring. A least-privilege check catches a stopped agent, a failed run and an expiring key, and an outside dead man's switch covers the case where nothing reports. I tested each alert path live except one, and the page says which.

Homelab project: a fake company, real systems, my own test traffic.

In short: my AI triage agent checks for new alerts every 5 minutes. A separate read-only check confirms it's still ticking, that its last run succeeded, and that none of the three keys it has expiry dates for is about to expire. The check reports to an outside service, which emails me on a failure and also when the check goes quiet. I tested the failure paths live.

Problem

A triage agent that has stopped looks exactly like a quiet day: no posts in Slack. There are three ways it can fail:

Design

A separate check watches the agentThe agent's timer ticks every 5 minutes and writes audit records to Elastic. A separate check runs 2 minutes after each tick. It reads the audit records with a read-only account, asks systemd for the agent unit's last result, and compares known key expiry dates. It reports one short line to healthchecks.io, which emails on a failure or when no report arrives. Agent timer every 5 minutes Elastic audit log one record per tick writes Timer check 2 min after each tick read-only account unit result · key dates reads healthchecks.io emails on failure, or no report in 15 min one line
The highlighted boxes are the controls. The check is separate from the agent and only reads. The outside service catches the case where nothing reports at all.

Before and after

The same moment, seen two ways. Here the model API key expires in 3 days. All values are made up, in the check's real output format.

A heartbeat alonesynthetic example
tick: 0 open alerts in 24h, 0 not yet run, running 0
heartbeat: ok                     # green until the first alert hits the expired key
The timer checksynthetic example, real format, two lines and the unit name left out
Window:  last 15 minutes
Records: 3
Unit:    agent service: success
Keys:    anthropic_api_key, 3 days left
SUMMARY fail status=key_expiring records=3 last_min=2 unit=success key=anthropic_api_key key_days=3

# the only thing sent to healthchecks.io:
FAIL status=key_expiring records=3 last_min=2 unit=success key=anthropic_api_key key_days=3 tries=1

The warning arrives a week ahead, while every tick still succeeds.

What I got wrong

How I tested it

What I learned

A heartbeat proves something ran. It doesn't prove the next real job will work. Watching the slow failures too, like a key that's about to expire, turns a surprise outage into a reminder a week ahead.