Alerts
How alerts work
How signals become incidents and when kogut sends notifications.
kogut groups related failures into incidents and notifies about the incident, not each check.
States
Checks, heartbeats, certificates, host thresholds, containers, and agents produce signals:
| State | Meaning |
|---|---|
| Up | Working as expected |
| Degraded | Working, but slow, rate-limited, or over a soft limit |
| Down | Failing |
| Unknown | Not enough information to judge, such as a silent agent or a check that has not run |
Degraded and down signals open alerts. Unknown never notifies. States and counters survive restarts, so a restart does not repeat an alert.
Grouping
A new alert joins an open incident with activity in the last 10 min on the same service, a directly related service (one dependency away), or the same host.
If a host’s agent is silent for 2 min or two or more signals on that host fail, the host becomes the incident’s root. Otherwise, the deepest failing dependency becomes the root. Services that depend on it appear under Also affected instead of notifying separately.
Timing
These rules are fixed, except for the host limits, which are defaults:
- Checks need two consecutive failures. The second run follows after 30 s, or the check interval if shorter. Checks, certificates, host thresholds, and containers recover after two successes and 3 min since the first success.
- A single check failure that the second run clears is a blip. It sends no message and
opens no alert. The timeline records it as a
blipevent with the failure and its likely causes, also shown on hover over the failed run on the check page. Each check records at most one blip in 10 min, and all checks together at most 30 in an hour. Blips of checks that need the internet are not recorded while kogut’s connection is in doubt: while a round of probes fails, or when one failed within a minute before. - Heartbeats, certificates, host thresholds, and agents need one failure. Heartbeats and agents recover after one success. Heartbeats cannot alert before their first ping.
- HTTP 429 and 503 that fail a status assertion mean degraded. Certificates become degraded within 14 days of expiry and down within 7 days.
- CPU and memory above 90%, or swap above 50%, must persist for 5 min. A disk above 90%
degrades immediately. Temperature has no alert by default. Set other limits, turn an
alert off, or leave a mount out of the disk alert per host, in a
[[host]]table or under Alerts on the host page. An agent becomes down after 2 min without data. A CPU or memory alert names the three containers or systemd units that used the most in those 5 min, such as95%, above 90% for 5 min; top: postgres 2.1 GB (+1.5 GB), api 600 MB, with the change from their usual use in brackets when known. - The first notification waits 30 s for related alerts. A failure that resolves during this wait stays on the timeline but sends no message.
- Changed incidents send updates at most every 5 min. An incident resolves after all its alerts have been up for 5 min.
- Unacknowledged incidents receive reminders at intervals of 1 h, 2 h, 4 h, and so on, capped at 24 h. Acknowledgement stops reminders, not updates or the resolution.
- More than four state changes in 30 min marks a signal as flapping. Ten minutes without a change clears that state. If all failing signals are flapping, only the resolution can notify.
There are no quiet hours. Silences and maintenance
hold messages without stopping checks or changing history. Acknowledge in the panel,
or POST /api/v1/incidents/<id>/ack, stops reminders.
Containers
Each container of a service has a signal of its own, such as Container api on vps-1. A
container belongs to a service when its name contains the service name, or when the
service is the only one on its host. Other containers have no signal.
The container is down when:
- it restarted 3 times within 10 min, even if it reads
runningbetween restarts; - two samples in a row show it exited or dead with a non-zero exit code, or stopped by the OOM killer;
- two samples in a row show it unhealthy, whatever its health was before.
The alert names the reason, such as restarted 4 times in 10 min, exited with code 137,
or unhealthy. A container that exited with code 0 is not failing. A restart loop stays
down until its restarts are 10 min old, then recovers like a check.
While the agent is silent or cannot read the container list, container signals are unknown. A removed container stops being judged and its alert closes.
Update agents to report exit codes and OOM kills. With an older agent, the restart and health rules still work, but an exited container is never down.
When kogut loses its internet connection
While a server-run check targets a public address, kogut probes its own connection every 30 s. Probe targets and how to turn probing off are in configuration.
One failed round holds messages for incidents made only of server-run public checks. Two consecutive failed rounds mark kogut offline:
- One connection alert replaces the apparent public outages. Channels that cannot be reached follow the normal delivery retries.
- Failed public checks become unknown and do not count as downtime. kogut also changes failures that began within a minute before the first failed round to unknown and closes their alerts.
- Public-check-only incidents hold their messages until connectivity returns.
Checks of non-public targets, agent-run checks, heartbeats, and agents continue as usual.
Non-public targets include loopback, private, link-local, and 100.64.0.0/10 addresses,
names without a dot, and names under localhost, local, internal, lan, home.arpa,
localdomain, or test. Domain expiry checks always use the internet.
When a probe answers, the connection alert resolves and checks start afresh. A public check that still fails runs again after 30 s. If a public check passes while probes fail, kogut treats the probes as blocked. Failures count normally, and the connection alert stays open without notifications. kogut restores this judgement from stored results after a restart.
When checks stop running
kogut expects a result from every check within three of its intervals plus its timeout.
A check without one becomes unknown. One alert, such as kogut has not run 2 checks since 14:07, covers all such checks and
updates as more join. It resolves once each of them has a result again. A
checks_not_run entry on the timeline lists the checks.
- Counting starts at the last result, when the check was added or changed, or when kogut started, whichever is latest. A restart alone raises nothing. An alert open before a restart stays open until its checks run.
- Agent-run checks count only while their agent reports. A silent agent raises its own alert instead. Checks on an agent that has never connected are not counted.
- Heartbeats have their own deadlines and are not counted. Domain checks count with their daily interval.
- Silences and maintenance hold the alert when they cover every check it lists, by its service, its host, or everything. Counting continues during the window, and a held alert is sent when the window ends.
kogut outages
A stopped or stuck server cannot notify. Run kogut apart from the servers it watches, and use kogut edge or a heartbeat URL to get an alert when kogut stops.
Message contents
Messages contain the state and start time, up to five failing signals with their observed errors, the likely cause, affected services, and an incident link:
website is down since 14:07 (3 signals failing)
Storefront failing since 14:07: status 503, expected 2xx.
Checkout failing since 14:07: status 503, expected 2xx.
API health failing since 14:08: no answer within 10000 ms.
Likely cause: deploy of api 3f9c2e1 at 14:02.
Also affected: api.Open incident
Longer lists end with the remaining count. Updates name what still fails, reminders state the elapsed time, and recoveries give the outage duration. Cause wording follows the correlation rules.
Times use the server’s time zone. Incident links need a public server URL. Both settings are in configuration.
Message destinations
Every incident message goes to every channel, from the panel or the file. There is no routing by service or severity. Daily summaries and deploy reports stay on the timeline, not in channels.