Skip to content
Oznog

2.19 · monitoring and alerting · after redaction

A capacity alarm that compared totals paged every night, and a notifier that did not log its own failures went silently blind

date
20260729 to 20260801
what happened
A nightly offsite backup script compared the total size of everything it planned to copy against the total free space on the destination drive, which fires on essentially every run once a rotation is mature. It logged a capacity error nightly for weeks while the actual nightly transfer took fifteen seconds. Separately, the same script's notification helper swallowed its own delivery failures without logging them, and a nearly-truncated token file had been causing every notification attempt to fail.
what it cost
Weeks of a nightly false alarm training the operator to distrust the capacity check entirely, plus an unknown window in which real notification failures went unrecorded except in a debug log line nobody was reading.
what changed
The capacity check now compares only the data that would actually need to be newly transferred against free space. The notification helper logs its own delivery failures explicitly, so a broken notification path leaves visible evidence of itself.
the check now
Each run's log line states all four relevant numbers (planned size, already present, actually to send, free space) so a false alarm and a genuine capacity problem can be told apart by reading one line.

Two mistakes in one script arrived at the same destination, an alarm system nobody could trust, from opposite directions.

The first was a capacity guard that compared the total size of the dataset it intended to copy against the free space on the destination. That comparison is correct on the first night and meaningless on every night after, because a mature backup rotation works precisely by having nearly everything already present at the destination, which is also why little space is free. So the guard fired every single night, for weeks, while the actual work each night was fifteen seconds of new data. Any alarm comparing one mostly-unchanging total against another mostly-unchanging total will settle into a permanent state and stop carrying information. The fix is almost always to alert on the marginal change rather than the total: what is new tonight, against what is free tonight.

The second is the more important one. The script’s own notification helper caught and discarded its own delivery failures. When the notification service was unreachable for a period, a capacity alert and a health alert were both lost, with no record anywhere except a debug line nobody read. It later turned out that a nearly-truncated token file had been quietly failing every notification attempt. A component whose entire job is telling you something else has failed cannot, by construction, be relied on to alert about its own failure through its own channel. It must therefore log that failure somewhere durable, so that a broken notifier at least leaves a trail for whoever eventually goes looking.

Source: node0 lessons v0.1, lesson 2.19. Sanitized: checklist v0.1, 20260921; script path, dataset names, sizes; voice pass 20260921. Part of oznog.com/node0.