How it works
From 41,318 log lines to one page that gets acked.
There's no agent to install and no SDK to adopt. Anything that can make an HTTP request POSTs its log events to Pingtower; deduplication, rules, and escalation do the rest — and don't stop until a human acknowledges.
curl -s $PINGTOWER_URL/v1/ingest \
-H "Authorization: Bearer $SOURCE_TOKEN" \
-d '{
"message": "payment worker crashed",
"level": 500,
"keys": { "service": "payments", "signal": "SIGSEGV" },
"tags": ["prod"]
}'The pipeline
Three steps from noise to a page
Send it a log line
Create a project, add a source, get a token. One POST with a message, a severity from 100 to 500, and whatever structured keys and tags your rules should match on — from an error hook, a cron job, a shell script, anywhere.
Rules turn the stream into state
Pingtower strips the variable parts of each message to recover its shape and hashes it. New problem: an alert opens. Repeat: the count bumps on the alert you already have. Threshold not met yet: it waits — thresholds like “5 hits in 10 minutes” live in the rule, so the slow bleed pages you and the one-off doesn't.
It finds a human
The on-call rotation picks whose phone rings; integrations fan out — Slack, Telegram, HMAC-signed webhooks, critical push to the iOS app — and runbook actions fire automatically. Unacked alerts climb the ladder on the schedule you set, and stop the moment someone acks.
Escalation
The ladder climbs until someone answers.
Each rule carries its own escalation ladder: step one might notify a Slack channel, step two pages whoever's on shift, step three wakes the founder — each step on its own delay, repeating until acked. Every notification is a durable outbox row, delivered at-least-once and logged per integration, so a restart never drops a page.
- Per-rule ladders, up to your own paranoia level
- Repeats on the schedule you set — until ack
- Acked alerts hold their place; quiet ones auto-resolve
- Every delivery logged, failures surfaced
"escalations": [
{ "schedules": ["payments-oncall"] },
{ "after_minutes": 10,
"repeat_minutes": 10 },
{ "after_minutes": 30,
"accounts": ["[email protected]"] }
]Where it runs
Hosted or self-hosted — same three steps.
The hosted service runs everything for you at api.pingtower.com. Or self-host the single Go binary and the whole inbound half — ingest, dedup, rules, escalation, plus webhook, Slack, and Telegram delivery — runs on your box, with each tenant in its own SQLite file. Pair the box with a pingtower.com account and the iOS app's push rings for your self-hosted alerts too.
- One static binary, no runtime, no dependencies
- Signed releases you verify before running
- A backup is a file copy
$ pingtower -listen 127.0.0.1:8391 \
-data-dir /var/lib/pingtowerStart now
Your first page is one POST away.
Sign up, grab a source token, and send the curl from the top of this page. Everything after that — rules, ladders, on-call — you add when you need it.