The addons agent
A single Go binary you install on external servers. It runs addons, small tasks that measure something about a target, on a schedule, and reports the measurements to the tower as ordinary events. Your rules do the rest.
What it does
- Runs the checks in its config on their own intervals, each with a timeout, up to eight at once.
- Reports on change by default, so a quiet target is not a noisy feed, with a periodic sample so you can see it is still running.
- Spools to disk through an outage, 64 MiB by default, and drains when the tower is reachable again.
- Sends a heartbeat about itself every five minutes, with counts of checks, sensors and failures, so the agent’s own health is a rule away from paging someone.
- Never executes a string from the network. There is no route that makes it run a command, restart, or upload a file.
It works identically against the hosted service and a self-hosted box: the tower URL is one line of config.
Status and levels
Every check ends in a status, and the status becomes the event’s level: up is 200, degraded is 300, down is 400, or whatever down_level the check sets, typically 500 for one that should page. Each event carries the tags addon:<name>, check:<id> and status:<status>, and the measurements as keys, so a rule can threshold any number directly.
The catalogue
| Addon | Measures | |
|---|---|---|
httpcheck | DNS, connect, TLS, first-byte and total time; body size; status, header, JSONPath, timing and body-hash assertions; basic, bearer, mTLS and OAuth authentication | |
synthetic | Up to 10 HTTP requests in order, with values carried between steps; per-step timings and the step and assertion that failed | |
browsercheck | A Playwright script in headless Chromium, run in a gVisor sandbox; per-step results and Core Web Vitals | |
grpccheck | A grpc.health.v1 health call: connect, TLS and call time; serving status | |
websocket | WebSocket upgrade, an optional message and its reply; upgrade and reply time | |
domainexpiry | Days until a domain expires, from its registry’s RDAP or WHOIS | |
tcpcheck | DNS and connect time to a port | |
dnscheck | Resolve time and answers, against a chosen resolver | |
tlscert | Days until expiry, handshake time, chain length | |
icmpping | RTT min, avg, max; packet loss | |
hostmetrics | CPU, load, memory, swap and paging on the agent’s own host | |
udpcheck | A datagram sent and a reply awaited, with retries; round-trip time | agent only |
smtpcheck, imapcheck, popcheck | Mail greeting, STARTTLS, certificate expiry and an optional login | agent only |
sshcheck | Connect, handshake, auth and command time; exit code | privileged |
portscan | Open, unexpected and missing ports against a baseline | privileged |
traceroute | Hop count, path change, per-hop RTT | privileged |
logwatch | Pattern matches in a local file, write age, rotation | privileged |
securityupdates | Pending updates, security updates, reboot required | privileged |
udpcheck and the three mail checks run only on your own agents, never on Pingtower’s servers, whose addresses are shared by every customer. A check of any of them that names a Pingtower region is refused. See Hosted checks.
Privileged addons need something beyond an outbound socket: a credential, an external binary, a heavier network footprint, or read access to a host file. They are off by default; a config naming one fails at startup unless it is listed in agent.enable_addons.
sshcheck and logwatch run only from the agent’s local config. Their parameters name a command, a key or a file on the box, so the agent refuses a check of either that Pingtower assigns to it, even when enable_addons names the addon, and the API and MCP refuse to create one. A check of either stored before Release 1 is no longer assigned and shows paused with the reason local_only; move it into the agent’s config. Pingtower can still assign traceroute, portscan and securityupdates to an agent whose enable_addons lists them.
Sensors are the other half: continuous, kernel-level watchers of the box the agent runs on, new in 0.2.0.
Down from more than one place
Run the same check from three agents and write a rule with "fire_after": {"count": 2, "window_minutes": 5, "distinct_sources": true}. One probe’s bad network no longer pages you; two agreeing do.