Introduktion
Efter fem års vagtordning på tværs af forskellige organisationer - fra startups til store virksomheder - har jeg lært, at incident management handler lige så meget om mennesker og processer som om teknologi.
Dette indlæg deler praktiske erfaringer om at opbygge en incident response, der rent faktisk virker, reducere mean time to recovery (MTTR) og skabe en vagtkultur, der ikke brænder dit team ud.
Anatomien af effektiv incident response
Alvorlighedsgrader, der giver mening
De fleste teams overkomplicerer alvorlighedsgrader. Her er en simpel ramme, der virker:
| Alvorlighed | Definition | Svartid | Eksempel |
|---|---|---|---|
| SEV1 | Fuldstændigt servicenedbrud | Øjeblikkeligt | Betalingssystem nede |
| SEV2 | Vigtig funktion nedsat | 15 minutter | Søgning returnerer fejl |
| SEV3 | Mindre påvirkning | 1 time | Langsom indlæsning af dashboard |
| SEV4 | Ingen brugerpåvirkning | Næste arbejdsdag | Problem med internt værktøj |
Den centrale indsigt: alvorlighed handler om brugerpåvirkning, ikke teknisk kompleksitet. En simpel fejl, der påvirker alle brugere, har højere alvorlighed end et komplekst problem, der ikke påvirker nogen.
De første 5 minutter
De første fem minutter af en hændelse afgør dens forløb. Sådan bør det foregå:
1. Alarm udløses → Vagthavende bekræfter (< 1 min.)
2. Hurtig vurdering: Er dette reelt? Hvor stort er skadesomfanget?
3. Beslut: Kan jeg løse dette alene, eller har jeg brug for hjælp?
4. Ved SEV1/SEV2: Start incident-kanal, tilkald yderligere hjælp
5. Kommunikér: Post en indledende statusopdatering
Jeg har set teams spilde 20+ minutter på at finde ud af, hvem der skulle involveres. Definér eskaleringsveje for almindelige scenarier på forhånd.
Reduktion af MTTR: Hvad der rent faktisk virker
Runbooks, der faktisk bliver brugt
De fleste runbooks er dokumenter, man kun skriver, men aldrig læser. Sådan gør du dem nyttige:
Dårligt runbook:
If the database is slow, check the queries and optimize them.
Godt runbook:
## Symptom: Databaselatens > 500 ms
### Hurtig diagnose (< 2 min.)
1. Tjek aktive forbindelser: `SELECT count(*) FROM pg_stat_activity;`
- Normalt: < 100
- Problem: > 200
2. Tjek for langvarige forespørgsler:
```sql
SELECT pid, now() - pg_stat_activity.query_start AS duration, query
FROM pg_stat_activity
WHERE state != 'idle'
ORDER BY duration DESC
LIMIT 5;
Almindelige løsninger
- For mange forbindelser: Genstart connection pooleren
kubectl rollout restart deployment/pgbouncer - Langvarig forespørgsel: Afbryd den (hvis sikkert)
SELECT pg_terminate_backend(<pid>);
Eskalering
Hvis ikke løst inden for 15 min., tilkald @database-team
Forskellen: konkrete kommandoer, forventede værdier og klare eskaleringsveje.
Observability under hændelser
Under en hændelse har du brug for svar hurtigt. Strukturér din observability omkring almindelige spørgsmål:
// Hvad jeg vil vide under en hændelse:
const incidentQueries = {
// Bliver problemet værre eller bedre?
errorTrend: 'rate(http_errors_total[5m])',
// Hvornår begyndte dette?
changePoint: 'changes(deployment_timestamp[1h])',
// Hvad er berørt?
affectedEndpoints: 'topk(10, sum by (endpoint) (http_errors_total))',
// Er det én enkelt synder, eller er det udbredt?
errorsByUser: 'sum by (user_id) (http_errors_total)',
};
Byg dashboards, der besvarer disse spørgsmål med ét klik, ikke fem minutters forespørgselsskrivning.
Opbygning af en bæredygtig vagtordning
Vagtkontrakten
Ethvert team bør have en eksplicit vagtkontrakt:
## Forventninger til vagtordningen
**Svartid:**
- SEV1: Bekræftelse inden for 5 minutter
- SEV2: Bekræftelse inden for 15 minutter
- SEV3+: Næste arbejdsdag
**Kompensation:**
- X kr. pr. uges vagt
- Afspadsering efter hændelser (1 times fri pr. times hændelse)
**Støtte:**
- Aldrig en forventning om at løse det alene - eskalering er opmuntret
- Ingen bebrejdelse for opkald uden for arbejdstid
- Sekundær vagthavende som backup
**Grænser:**
- Ingen vagt under ferie
- Maksimalt 1 uge om måneden
- Stilletid: 22-7 (kun SEV1)
At gøre forventninger eksplicitte forebygger udbrændthed og bitterhed.
Reduktion af alarmtræthed
Alarmtræthed er den stille dræber af en velfungerende vagtordning. Sådan bekæmper du den:
80/20-reglen for alarmer:
- 80 % af opkaldene bør være handlingsrettede
- Hvis du ignorerer alarmer, så slet dem
Ugentlig alarmgennemgang:
## Alarmgennemgang - uge 15. januar
| Alarm | Opkald | Handlingsrettet | Handling |
|-------|-------|------------|--------|
| Høj CPU | 12 | 2 | Hæv tærskel til 90 % |
| Diskplads | 8 | 8 | Behold |
| API-latens | 15 | 3 | Tilføj auto-skalering |
| Memory leak | 1 | 1 | Behold |
**Beslutning:** Slet Høj CPU-alarm, implementér auto-skalering for API
Det skyldfrie postmortem
Postmortems er stedet, hvor læring sker - eller ikke sker. Her er en skabelon, der virker:
## Hændelse: Nedbrud i betalingsbehandling
**Dato:** 15.08.2024
**Varighed:** 47 minutter
**Alvorlighed:** SEV1
**Forfatter:** [Navn]
### Resumé
Betalingsbehandlingen var utilgængelig i 47 minutter på grund af
udtømning af en database-connection-pool forårsaget af en
forespørgselsregression i den seneste deployment.
### Tidslinje
- 14:23 - Deployment afsluttet
- 14:31 - Første kunderapport
- 14:35 - Alarm udløst, vagthavende tilkaldt
- 14:42 - Grundårsag identificeret
- 14:58 - Rollback gennemført
- 15:10 - Fuld genopretning bekræftet
### Grundårsag
En ny forespørgsel i checkout-flowet manglede et indeks, hvilket
fik forbindelser til at blive holdt i 30+ sekunder i stedet for <100 ms.
### Hvad gik godt
- Hurtig identifikation af grundårsagen
- Rollback-processen forløb problemfrit
- Kundekommunikationen var rettidig
### Hvad kunne forbedres
- Forespørgselsydelsen blev ikke fanget i kodegennemgangen
- Ingen belastningstest for den nye funktion
- Alarmen blev udløst 8 minutter efter den første kunderapport
### Handlingspunkter
| Handling | Ansvarlig | Frist |
|--------|-------|----------|
| Tilføj CI-tjek for forespørgselsydelse | @backend | 22.08.2024 |
| Implementér syntetisk overvågning | @sre | 29.08.2024 |
| Gennemgå alarmgrænser | @on-call | 18.08.2024 |
Nøglen: fokus på systemer, ikke personer. “Deploymentprocessen tillod en langsom forespørgsel” i stedet for “Peter deployede en langsom forespørgsel.”
Kommunikation under hændelser
Intern kommunikation
Under en hændelse: kommunikér hellere for meget end for lidt:
## Skabelon til hændelsesopdatering
**Status:** Undersøges | Identificeret | Overvåges | Løst
**Påvirkning:** [Hvem er berørt, og hvordan]
**Aktuel handling:** [Hvad vi gør lige nu]
**Næste opdatering:** [Hvornår næste opdatering kan forventes]
Eksempel:
---
🔴 **Status:** Identificeret
**Påvirkning:** ~30 % af checkout-forsøg fejler
**Aktuel handling:** Rollback af deployment v2.3.4
**Næste opdatering:** om 10 minutter eller når løst
Ekstern kommunikation
Ved kundevendte hændelser:
Gør:
- Bekræft hurtigt, selv uden detaljer
- Brug et klart sprog, ikke teknisk jargon
- Giv regelmæssige opdateringer, selv når intet har ændret sig
- Fortæl, hvad I gør for at forhindre gentagelse
Gør ikke:
- Skyld på tredjeparter (selv hvis det er deres skyld)
- Lov konkrete løsningstider
- Overforklar tekniske detaljer
- Forsvind efter løsningen
Måling af incident response
Målinger, der betyder noget
Følg disse målinger månedligt:
// Hvor ofte har vi hændelser?
const incidentMetrics = {
incidentCount: 'count by severity',
// Hvor hurtigt reagerer vi?
timeToAcknowledge: 'median time from alert to acknowledgment',
// Hvor hurtigt løser vi ting?
timeToResolve: 'median time from alert to resolution',
// Lærer vi noget?
repeatIncidents: 'incidents with same root cause as previous',
// Er vagtordningen bæredygtig?
pagesPerWeek: 'average pages per on-call shift',
};
Bevægelse i den rigtige retning
God incident management viser sig ved:
- Faldende antal hændelser over tid
- Stabil eller faldende MTTR
- Lav andel af gentagne hændelser (< 10 %)
- Bæredygtigt alarmvolumen (< 2 pr. nat)
Erfaringer
Efter hundredvis af hændelser er her, hvad jeg ved med sikkerhed:
- Forberedelse slår reaktion. Tid investeret i runbooks og automatisering betaler sig 10-dobbelt under hændelser.
- Kommunikation er det halve slag. Det meste stress ved hændelser kommer fra usikkerhed, ikke fra det tekniske problem.
- En skyldfri kultur er ikke til forhandling. I det øjeblik folk frygter bebrejdelse, holder de op med at rapportere problemer og dele erfaringer.
- Vagtordningens bæredygtighed betyder noget. Udbrændte udviklere træffer dårligere beslutninger og forlader virksomheden.
- Hver hændelse er en gave. Det er en gratis stresstest af dine systemer og processer. Lær af den.
Konklusion
Incident management handler ikke om at forhindre alle fejl - det er umuligt. Det handler om at reagere effektivt, når fejl opstår, lære af dem og bygge systemer (både tekniske og menneskelige), der forbedres over tid.
De bedste incident response-teams, jeg har arbejdet med, deler ét træk: de betragter hændelser som muligheder for forbedring, ikke som fejl, der skal skjules.
Ressourcer
- Incident Management for Operations - Google SRE Book
- PagerDuty Incident Response Guide
- Learning from Incidents - Community-ressourcer