Modul 12 — Monitoring, logging a observabilita

60. Alerting a nastavení smysluplných alertů (bez alert fatigue)

Jak z nashromážděných metrik a logů vybrat, na co má smysl upozorňovat, a jak nastavit Prometheus alerting rules a Alertmanager, aby na pager chodilo jen to důležité.

Odhadovaná délka studia: 55 minut · Stav: nehotovo

Technologie: Prometheus/Grafana

Úvod a kontext

Máme metriky v Prometheu, dashboardy v Grafaně a logy centralizované
v Loki nebo ELK. To samo o sobě nikoho nezachrání ve tři ráno — dokud
se někdo nedívá na dashboard, incident si nikdo nevšimne. Proto
poslední vrstva observability je alerting: automatické upozornění
lidí, když metriky nebo logy ukazují na problém. Špatně nastavený
alerting je ale horší než žádný — pokud lidem chodí desítky
nedůležitých upozornění denně, po týdnu je začnou ignorovat i ty
důležité. Tomuto jevu se říká alert fatigue a je jednou
z nejčastějších provozních chyb.

Teorie

Na co alertovat — symptomy, ne příčiny

Klíčové pravidlo: alertujte na symptomy, které pociťuje uživatel
nebo SLA, ne na každou možnou vnitřní příčinu.
Špatný přístup je
mít alert na "CPU uzlu nad 80 %" — vysoké CPU samo o sobě nemusí nic
znamenat, pokud aplikace odpovídá rychle a bez chyb. Lepší přístup je
alert na "5 % požadavků končí chybou 5xx za posledních 5 minut" nebo
"p99 latence odpovědi nad 2 sekundy" — to jsou symptomy, které
uživatel skutečně vnímá. Vnitřní metriky (CPU, paměť, délka fronty)
jsou užitečné pro diagnostiku až poté, co alert na symptom
spustí vyšetřování, ne jako primární spouštěč.

Urgentnost a kanály

Ne každý alert má budit člověka uprostřed noci. Rozlišujeme typicky:

  • Kritický (page) — něco už je rozbité pro uživatele právě teď,
    vyžaduje okamžitý zásah → jde na pager/telefon on-call inženýra.
  • Varování (warning) — něco směřuje k problému, ale zatím
    funguje (např. disk na 85 % plný, certifikát vyprší za 10 dní) →
    jde do chatového kanálu nebo ticketu, řeší se v pracovní době.
  • Informativní — jen pro záznam, nikam neupozorňuje aktivně,
    slouží k pozdější analýze trendů.

Jak se vyhnout alert fatigue

  • Alertujte na dostatečně dlouhém okně (for: 5m v Prometheu) —
    jednorázový výkyv metriky na jednu vteřinu není incident.
  • Seskupujte související alerty — pokud spadne celý datacentrum,
    chcete jednu zprávu "datacentrum X nedostupné", ne 200 zpráv
    o jednotlivých službách.
  • Potlačujte (inhibice) odvozené alerty — pokud víte, že databáze
    je down, nepotřebujete zvlášť alert na každou službu, která na ní
    závisí a proto také hlásí chyby.
  • Pravidelně revidujte alerty — alert, který za posledních
    6 měsíců spustil poplach 50× a nikdy nevedl k akci, je špatně
    nastavený a měl by se buď opravit, nebo smazat.
  • Runbook u každého kritického alertu — text alertu by měl
    obsahovat odkaz na postup, co dělat, ne nutit člověka přemýšlet
    ve tři ráno, co daná metrika vlastně znamená.

Architektura: Prometheus + Alertmanager

Prometheus server vyhodnocuje alerting rules (výrazy v PromQL,
které se pravidelně přepočítávají) a když je podmínka splněná déle
než for, pošle alert do Alertmanageru. Alertmanager je
samostatná komponenta, která alerty seskupuje, potlačuje duplicity,
řeší inhibice a směruje
je na správný kanál (e-mail, Slack,
PagerDuty, SMS) podle štítků (labelů) alertu.

Praktický příklad

Pravidlo v Prometheu pro vysokou chybovost a vysokou latenci
(soubor alert-rules.yml, načtený přes rule_files v konfiguraci
Promethea):

groups:
  - name: objednavky-servis
    rules:
      - alert: VysokaChybovost
        expr: |
          sum(rate(http_requests_total{job="objednavky", status=~"5.."}[5m]))
          /
          sum(rate(http_requests_total{job="objednavky"}[5m])) > 0.05
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Objednávkový servis má přes 5 % chyb 5xx"
          description: "Chybovost {{ $value | humanizePercentage }} po dobu 5 minut. Runbook: https://wiki.interni/runbook/objednavky-5xx"

      - alert: VysokaLatence
        expr: |
          histogram_quantile(0.99,
            rate(http_request_duration_seconds_bucket{job="objednavky"}[5m])) > 2
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "p99 latence objednávkového servisu nad 2s"
          description: "Aktuální p99: {{ $value }}s."

      - alert: DiskSkoroPlny
        expr: node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"} < 0.15
        for: 30m
        labels:
          severity: warning
        annotations:
          summary: "Méně než 15 % volného místa na disku {{ $labels.instance }}"

Konfigurace Alertmanageru, která kritické alerty posílá okamžitě na
pager a varování jen do Slacku, s potlačením duplicit po dobu
seskupování:

route:
  group_by: ['alertname', 'job']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  receiver: slack-warnings
  routes:
    - matchers:
        - severity="critical"
      receiver: pagerduty-oncall
      repeat_interval: 1h

receivers:
  - name: slack-warnings
    slack_configs:
      - channel: '#provoz-varovani'
        send_resolved: true
  - name: pagerduty-oncall
    pagerduty_configs:
      - routing_key: '<PAGERDUTY_KEY>'
        send_resolved: true

inhibit_rules:
  - source_matchers: ['alertname="DatabazeNedostupna"']
    target_matchers: ['severity="critical"']
    equal: ['cluster']

Sekce route říká: každý alert se ve výchozím stavu seskupí podle
alertname a job a čeká 30 sekund (group_wait), aby se stihly
přidat příbuzné alerty do jedné zprávy, a jde do Slacku. Podřazené
routes přesměrují alerty se štítkem severity="critical" na
PagerDuty s kratším repeat_interval (opakuje připomínku po hodině,
dokud se neřeší). inhibit_rules zajistí, že pokud běží alert
o nedostupné databázi, potlačí se odvozené kritické alerty na stejném
clusteru — nedostane se tak 20 pagerů najednou za jednu skutečnou
příčinu.

Shrnutí

Dobrý alerting hlásí symptomy vnímané uživatelem (chybovost, latence),
ne každou vnitřní odchylku. Rozlišujte urgentnost (kritické na pager,
varování do chatu), používejte dostatečně dlouhé okno (for),
seskupování a inhibici v Alertmanageru, aby jeden incident nevygeneroval
desítky zpráv, a pravidelně revidujte alerty, které nevedou k žádné
akci. Cílem je, aby každý alert, který přijde, byl důležitý a měl
jasný další krok — jinak hrozí alert fatigue a lidé přestanou
alertům věřit.

Kontrolní otázky

  1. Proč je lepší alertovat na symptomy (chybovost, latence) než na
    vnitřní metriky (CPU, paměť) jako primární spouštěč?
  2. K čemu slouží for: 5m v Prometheus alerting rule a proč jeho
    vynechání zvyšuje riziko alert fatigue?
  3. Jaký je rozdíl mezi seskupováním (group_by) a inhibicí
    (inhibit_rules) v Alertmanageru?
  4. Mini cvičení: navrhněte, jak byste rozdělili alerty vaší aplikace
    do tří úrovní urgentnosti (kritický/varování/informativní) a na
    jaký kanál by měl jít každý z nich.

Lekce na sebe nejsou zamčené — libovolnou lekci můžete otevřít i označit jako hotovou v jakémkoliv pořadí.