Skip to content

The activity watcher

A system can be perfectly healthy and produce nothing. A cron job that has been failing for three days, a queue holding work from the day before yesterday, a role whose budget ran out on the 8th: all of that returns 200, writes not a single error to the log and delivers nothing. The clock fires and Docker keeps the process alive, but neither of those answers the question that matters.

The watcher answers it in SQL, every six hours (VIGILANTE_HORAS, 0 switches it off). It spends no tokens and has no opinion: the signals are accounting facts.

Signal What it looks at Severity
Broken cron jobs Approved ones with 2 or more consecutive failures grave
Stuck queue Messages waiting more than 2 h grave
Exhausted budgets A role whose month’s spend is above its cap grave
Stalled requests Resources requested more than 2 days ago aviso
Unverified deliveries Work done that nobody accepted (3 days) aviso
Bogged-down tasks Tasks in progress for more than 3 days aviso

Grave means something is stopped and will not fix itself. Aviso, that it is running slow.

  1. It writes it to organtia.vigilancia, one row per pass. Without history you cannot tell a one-off problem from something that has been repeating for a week.
  2. It notifies the board live if it is serious.
  3. It leaves it for the CEO in his notice inbox, so he deals with it on his next shift. Detecting without anyone acting fixes nothing. Only the serious ones: if every slow thing reached management, the inbox would turn into noise and stop being read, which is worse than not having it.

You query it at GET /vigilante.json:

{
"nivel": "aviso",
"resumen": "1 notice(s): 1 resource request(s) waiting more than 2 days",
"hallazgos": [
{
"clave": "solicitudes_paradas",
"nivel": "aviso",
"detalle": ["ERP access (onboarding), requested on 01-11"]
}
]
}
  • Its own thread, not an Agno cron job: there is no need to wake a model to count rows, and a cron job would burn shifts on what is a query.
  • One broken probe does not blind the others: if a query blows up, it is logged and the other five keep looking. A watcher that goes quiet when one part fails is worse than not having one.
  • A signal exists when there are cases, not when the query ran: _sonda counts the rows and revisar discards those that come back with zero. Without this, the first watcher announced «0 cron jobs with failures» at grave severity — the bug that slipped through and the tests caught.
  • It never throws: the loop catches everything and carries on. If the watcher dies, the only one watching dies with it.