Confirm the symptom with a series of requests
A single curl may hit a lucky moment: with one dead backend of two,
only part of the requests fails. A series shows the error share.
An incident is an outage users can see: restore the service by the runbook first, look for the cause later.
curl -s -o /dev/null -w '%{http_code}\n' http://localhost/
mkdir -p ~/incident; cd ~/incident
echo "$(date -u +%T) alert 'site 502', confirmed" >> timeline.txt
sudo journalctl -t sudo --since -1h | grep COMMAND
who ran what
sudo find /etc /opt /srv -newermt '-1 hour' -type f
fresh files
ls -lt /etc/nginx/sites-enabled/ | head
sudo cp -a /etc/default/lab-app ~/incident/
An incident is when a service does not do for users what it should: the site answers 502, responses take seconds, the error share eats the budget faster than normal (sli-slo). An alert reports it (alertmanager), or a user does.
Incident response is an order of actions that shortens the outage: confirm the symptom → restore the service → understand the cause → review the outage (postmortem). The first two steps are the on-call's — whoever answers alerts during this shift.
Every minute of an outage means errors for users and budget spent. So the first goal is to bring the service back by the fastest reversible means. The cause is looked for once the service works: calmly, from the timeline and the saved copies.
| Means | When it fits |
|---|---|
| roll back the last change | the outage began right after an edit or a release |
| restart the service | the service crashed or hung, the config did not change |
| switch to a standby machine | one machine out of several is broken |
| take a server out of the pool | one backend of several answers with errors |
Reversible means the step can be undone and leaves evidence behind.
Before a rollback, copy the changed file to ~/incident/ (cp -a
keeps the time and permissions). Before a restart, save
systemctl status and the last lines of the service journal: a
restart wipes the process state.
Most outages start after a change: a config edit, a release, a package upgrade. Where to look:
sudo journalctl -t sudo --since -1h — commands run with sudo:
who ran what and when;sudo find /etc /opt /srv -newermt '-1 hour' -type f and ls -lt
in the config directory — which files changed (find);journalctl -u <service> --since -1h — when the service restarted;/var/log/apt/history.log — which packages were upgraded.A sudo line in the journal (wrapped for width):
User deploy changed the port in the service file at 12:00:41. If the
site began answering 502 at 12:00:43, this is suspect number one.
Compare the time of a change with the start of the symptom: a change
seconds or minutes before it is a rollback candidate.
A runbook is an instruction for one alert: what it means, which commands to run first, how to restore the service and whom to call. It is written in advance, without haste; during an outage the on-call follows the steps instead of inventing them.
Keep the runbook where it is found during an outage: next to the
service (/srv/runbooks/<alert>.md) and linked from the alert text.
The timeline is a list of outage events by time, a line per event:
Time first and in UTC (date -u +%T), then a fact: what was seen or
done and by whom, as a role. No judgements in the line. Write it as
you go, appending with >>: under stress the times and the order of
steps are forgotten, and the review needs both. Whoever joins later
reads the timeline and sees what has been done. How to assemble a
timeline from the logs after the outage — postmortem.
When an incident lasts longer than a few minutes or involves more than one person, the roles are split:
| Role | What it does |
|---|---|
| incident commander | decides what to do, hands out tasks, does not fix things |
| communications | tells users and management what is going on |
| responders | fix things per the commander's tasks and write the timeline |
In a small team one on-call does it all, but the decision "tell people" is made apart from "fix it": users and colleagues need to know about the outage while it is being fixed.
The service answers the same request that confirmed the symptom, and the time is in the timeline. If the fix is temporary (a rollback, a manual restart), a task for the real fix is opened. Next comes the outage review (postmortem).
A single curl may hit a lucky moment: with one dead backend of two,
only part of the requests fails. A series shows the error share.
The first command lists what people ran with sudo, the second lists
files with their modification time (with fractions of a second) in
order. -newermt also takes an
exact time: -newermt '2026-10-22 12:00'.
reload or
restart.The restart removed the symptom and the cause stayed: a memory leak, a
growing log, exhausted connections. Save systemctl status, the
service journal and free -m before the next restart — they show what
piles up.
The change did not go through sudo: a root login, a release running
as the service user, automation (cron, ansible, package upgrades).
Look at file modification times (stat, find -newermt) and at the
whole journal around the outage start:
journalctl --since '12:00' --until '12:05'.
journalctl prints time in the machine's time zone, date -u in UTC.
On the lab machine they are the same. On a machine with another zone,
compare in one: journalctl --utc, TZ=UTC date.
Editing in place, deleting the "broken" file, restarting without
saving the journal erases the evidence. The review is then built on
guesses, and the same outage repeats. A copy in ~/incident/ takes
seconds.
Three changes in a row with no check in between: the service is back, but which one helped is unclear, and the other two may have added a new breakage. One change — one check — one line in the timeline.
--since, -t, -u.status, reload, restart.Found an inaccuracy? Report an error in the article