Until now, the only way to use my monitor was to write a test.
That’s not a product. So this checkpoint gives it a front door.
What I built
One command:
service-monitor check https://example.com/health
It checks the address once and tells you what happened, in plain words. A few options:
--expect 200,204: which status codes count as fine.--timeout-ms 5000: how long to wait, at most.--contains "ready": only pass if the page says this.--dev-allow-port 9000: allow exactly127.0.0.1on that port, for testing on my laptop.
And it ends with an exit code, a number that scripts read to know what happened:
0: it’s fine.1: the site is broken.2: you typed something wrong.3: “I couldn’t look”, for example a blocked address.
That last one matters. A script can tell “the site is down” apart from “the monitor couldn’t check”, and those need very different reactions at 3 a.m.
Here it is, for real
Against my practice server:
$ service-monitor check http://127.0.0.1:9124/healthy --dev-allow-port 9124
PASS 200 OK
time 0.4 ms, until the headers arrived
$ service-monitor check http://127.0.0.1:9124/error --dev-allow-port 9124
FAIL expected {200}, got 500 Internal Server Error
$ service-monitor check http://127.0.0.1:9124/hang --timeout-ms 1000 --dev-allow-port 9124
FAIL no reply before the deadline
time 1001.1 ms, until it gave up
$ service-monitor check http://169.254.169.254/latest/meta-data/
GAP 169.254.169.254 is in 169.254.0.0/16 (link-local, incl. cloud metadata), which monitors may not reach
The last one is the cloud’s password address from Checkpoint 0.3. Refused before a single byte is sent.
If you type something wrong, it tells you which option, in the words you typed:
service-monitor: that check can't run:
--timeout-ms: must be between 1000 and 15000 (got 20)Does it actually work?
6 new tests run the real program as a separate process, against the practice server, and check its exit code and output, exactly as a script would see them. They cover:
- pass,
- broken,
- hanging,
- blocked,
- bad input,
- and complete nonsense.
73 tests in the project now. 0 warnings.
Where I messed up
Using the command myself, instead of just testing it, found two rough edges:
- The same hang got two different descriptions. Sometimes it said “timed out”, sometimes “no reply before the deadline”. Two timers were racing (mine, and a backup in the web library), and whichever won picked the wording. The answer was always right; only the words changed. Now every failure is described from one list of plain-English names, so the wording can’t depend on a race.
- “Connection refused” said it waited “until the headers arrived”. No headers ever arrived. It now says “until it gave up”.
Tests check that the answer is right. Actually using the thing checks whether it makes sense to a human.
What it doesn’t do yet
- It checks once. There’s no schedule yet (that’s the next milestone).
- Certificate problems on secure sites still show up as “couldn’t connect” instead of their own category.
Up next
Before I call this first milestone done, I want the testing to be aggressive. So Checkpoint 0.7 lets tools attack the code instead of me: automatic mutation testing, thousands of random inputs, and hundreds of checks at once.