Observabilité — 06 — Alerting : symptômes vs causes, pager fatigue, runbooks

Construire des alertes actionnables : alerter sur les symptômes plutôt que les causes, réduire le bruit, écrire des runbooks utiles. Prometheus Alertmanager et Grafana.

06 — Alerting : symptômes vs causes, pager fatigue, runbooks

Ce que tu vas apprendre

  • La distinction fondamentale symptôme / cause — et pourquoi elle change tout
  • Les anti-patterns d'alerting qui créent du bruit inutile
  • Comment structurer une alerte actionnable
  • Les runbooks : documenter la réponse avant l'incident
  • Configuration Prometheus Alertmanager et Grafana Alerts

Prérequis


Symptôme vs cause : la règle fondamentale

Alerter sur les symptômes, pas sur les causes.

Un symptôme est ce que l'utilisateur ressent : latence élevée, erreurs, données manquantes. Une cause est ce qui produit le symptôme : CPU élevé, mémoire pleine, disque saturé.

Le problème des alertes sur les causes : un CPU à 90% n'impacte pas forcément les utilisateurs. La mémoire peut être à 95% et le service répond parfaitement (cache chaud). À l'inverse, un CPU à 30% peut accompagner un taux d'erreur de 50% si le bottleneck est ailleurs.

❌ Alertes sur des causes — beaucoup de bruit, peu d'impact
  "CPU > 80%"
  "Mémoire > 90%"
  "Disque > 85%"
  "Connexions BDD > 80"

✓ Alertes sur des symptômes — impact direct sur les utilisateurs
  "Taux d'erreur HTTP > 5% depuis 5 minutes"
  "p99 latence > 1s depuis 10 minutes"
  "Error budget consommé à 50% en 6 heures"
  "Aucune commande traitée depuis 15 minutes"

La règle de Google SRE :

"Every page should be actionable and there should be a clear response to every alert. If you can't act on an alert, why are you sending it?" — Beyer et al., Site Reliability Engineering (2016), Chapitre 6


Les 4 questions d'une bonne alerte

Avant d'ajouter une alerte, répondre aux 4 questions :

  1. Est-ce que l'utilisateur est impacté ? Si non → log ou métrique, pas une alerte
  2. Est-ce actionnable ? Si on ne peut rien faire → pas d'alerte
  3. Est-ce urgent ? Si ça peut attendre le matin → ticket, pas un page de nuit
  4. Est-ce que l'alerte indique clairement quoi faire ? Si non → écrire un runbook d'abord

Configuration Prometheus Alertmanager

Alertes PromQL

yaml# rules/alerts.yml
groups:
  - name: api-alerts
    rules:

      # SLO — symptôme : taux d'erreur utilisateur
      - alert: HighErrorRate
        expr: |
          sum(rate(http_requests_total{status=~"5.."}[5m]))
          /
          sum(rate(http_requests_total[5m])) > 0.05
        for: 5m
        labels:
          severity: critical
          team: backend
        annotations:
          summary: "Taux d'erreur HTTP > 5% depuis 5 minutes"
          description: "Taux actuel : {{ $value | humanizePercentage }} sur {{ $labels.route }}"
          runbook: "https://wiki.exemple.fr/runbooks/high-error-rate"
          dashboard: "https://grafana.exemple.fr/d/api-overview"

      # SLO — symptôme : latence élevée
      - alert: HighLatencyP99
        expr: |
          histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m])) > 1.0
        for: 10m
        labels:
          severity: warning
          team: backend
        annotations:
          summary: "p99 latence > 1s depuis 10 minutes"
          description: "p99 actuel : {{ $value | humanizeDuration }} sur {{ $labels.route }}"
          runbook: "https://wiki.exemple.fr/runbooks/high-latency"

      # Symptôme métier : aucune commande traitée
      - alert: NoOrdersProcessed
        expr: |
          increase(orders_processed_total[15m]) == 0
          AND
          hour() >= 8 AND hour() <= 22
        for: 0m
        labels:
          severity: critical
          team: backend
        annotations:
          summary: "Aucune commande traitée depuis 15 minutes (heures ouvrées)"
          runbook: "https://wiki.exemple.fr/runbooks/no-orders"

      # Error budget — burn rate critique
      - alert: SLOBurnRateCritical
        expr: |
          (1 - job:sli_availability:ratio_rate5m) / (1 - 0.999) > 14.4
          AND
          (1 - job:sli_availability:ratio_rate1h) / (1 - 0.999) > 14.4
        labels:
          severity: critical
        annotations:
          summary: "Burn rate SLO critique — error budget épuisé en < 1h"
          runbook: "https://wiki.exemple.fr/runbooks/slo-burn-rate"

Alertmanager : routing et déduplication

yaml# alertmanager.yml
global:
  resolve_timeout: 5m

route:
  group_by: ["alertname", "team"]
  group_wait: 30s          # Attendre 30s avant d'envoyer le premier groupe
  group_interval: 5m       # Délai entre les notifications du même groupe
  repeat_interval: 4h      # Renvoi si l'alerte persiste

  routes:
    # Critical → PagerDuty (page immédiat)
    - match:
        severity: critical
      receiver: pagerduty
      continue: false

    # Warning → Slack (notification silencieuse)
    - match:
        severity: warning
      receiver: slack-warnings

receivers:
  - name: pagerduty
    pagerduty_configs:
      - service_key: "${PAGERDUTY_KEY}"
        description: "{{ .CommonAnnotations.summary }}"

  - name: slack-warnings
    slack_configs:
      - api_url: "${SLACK_WEBHOOK}"
        channel: "#alerts-backend"
        title: "{{ .CommonAnnotations.summary }}"
        text: "{{ .CommonAnnotations.description }}\nRunbook: {{ .CommonAnnotations.runbook }}"

# Inhibitions — supprimer les alertes de cause si le symptôme est déjà alerté
inhibit_rules:
  - source_match:
      alertname: HighErrorRate
      severity: critical
    target_match:
      severity: warning
    equal: ["team"]

La pager fatigue : comment l'éviter

La pager fatigue survient quand les alertes sont trop nombreuses, trop bruyantes ou non actionnables. Résultat : les ingénieurs ignorent les alertes ou les snooze sans investiguer.

Symptômes de la pager fatigue :

  • Plus de 5 pages par semaine par ingénieur
  • Les ingénieurs snooze les alertes sans regarder
  • Les mêmes alertes reviennent toutes les nuits
  • Personne ne sait pourquoi une alerte a été créée

Remèdes :

yaml# 1. Inhibitions — ne pas alerter sur les causes si le symptôme est déjà alerté
inhibit_rules:
  - source_match:
      alertname: HighErrorRate
    target_match_re:
      alertname: (HighCPU|HighMemory|HighDiskIO)

# 2. Silences temporaires (via UI Alertmanager ou API)
# Silence automatique hors heures ouvrées pour les alertes non-critiques
- match:
    severity: warning
  time_intervals:
    - weekdays: ["saturday", "sunday"]
    - times: [{ start_time: "22:00", end_time: "08:00" }]

# 3. for: suffisamment long pour éviter les faux positifs
- alert: HighMemory
  expr: process_resident_memory_bytes > 1e9
  for: 15m  # Pas 0m — attendre 15 minutes de mémoire élevée continue

Écrire un runbook utile

Un runbook est la procédure à suivre quand une alerte se déclenche. Sans runbook, l'ingénieur d'astreinte passe 10 minutes à chercher quoi faire — souvent de nuit.

Structure d'un runbook :

markdown# Runbook : HighErrorRate

## Contexte
Cette alerte se déclenche quand le taux d'erreur HTTP 5xx dépasse 5% pendant 5 minutes.

## Impact
Les utilisateurs voient des erreurs sur les pages qui appellent l'API Order Service.

## Étapes de diagnostic

### 1. Vérifier les logs d'erreur (2 minutes)
kibana.exemple.fr → filtre : level:error AND service:order-api

### 2. Vérifier les métriques (2 minutes)
Dashboard : grafana.exemple.fr/d/api-overview
- Quelle route a le plus d'erreurs ?
- Quelle est la distribution des codes d'erreur (500 vs 503 vs 504) ?

### 3. Vérifier la BDD (2 minutes)
- Connexions actives : grafana.exemple.fr/d/postgres
- Latence des requêtes > 500ms ?

### 4. Vérifier les dépendances
- Payment Service health : curl http://payment-service/health
- Redis : redis-cli ping

## Actions correctives

### Si erreurs 503 (service unavailable)
→ Vérifier le nombre de pods : kubectl get pods -n production
→ Si pods en CrashLoopBackOff : kubectl logs <pod> -n production

### Si erreurs 500 avec trace "connection refused" vers la BDD
→ Vérifier le pool de connexions : grafana.exemple.fr/d/postgres
→ Si pool saturé : redémarrer le service (kubectl rollout restart)

### Si pic d'erreurs après un déploiement
→ Rollback immédiat : kubectl rollout undo deployment/order-api -n production

## Escalade
Si non résolu en 30 minutes → contacter [Lead Backend] sur Slack #incidents

## Post-mortem
Après résolution → créer un ticket et planifier un post-mortem si impact > 15 minutes

Grafana Alerts (alternative à Alertmanager)

Si tu utilises Grafana Cloud ou Grafana 9+, les alertes peuvent être gérées directement dans Grafana sans Alertmanager :

yaml# Grafana alert rule (format JSON/YAML via API ou UI)
apiVersion: 1
groups:
  - name: API Alerts
    rules:
      - uid: high-error-rate
        title: High Error Rate
        condition: C
        data:
          - refId: A
            datasourceUid: prometheus
            model:
              expr: |
                sum(rate(http_requests_total{status=~"5.."}[5m]))
                /
                sum(rate(http_requests_total[5m]))
          - refId: C
            datasourceUid: __expr__
            model:
              type: threshold
              conditions:
                - evaluator:
                    type: gt
                    params: [0.05]
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Taux d'erreur > 5%"
          runbook: "https://wiki.exemple.fr/runbooks/high-error-rate"
        noDataState: NoData
        execErrState: Error

Résumé de la série

Article Contenu
00 — Introduction Les 3 piliers, monitoring vs observabilité
01 — Logs structurés pino, structlog, correlation ID
02 — Métriques Types Prometheus, RED, USE, PromQL
03 — Traces distribuées Spans, W3C TraceContext, sampling
04 — OpenTelemetry SDK TypeScript + Python, auto-instrumentation
05 — SLO / SLI / SLA Error budgets, burn rate, PromQL
06 — Alerting Symptômes vs causes, runbooks, Alertmanager

Un système observable avec de bonnes alertes te permet de dormir sereinement — et surtout de te réveiller uniquement quand c'est vraiment nécessaire.


Sources

  • Beyer, B., et al. (2016). Site Reliability Engineering, Chapitre 6 "Monitoring Distributed Systems". O'Reilly. sre.google/sre-book/monitoring-distributed-systems/
  • Beyer, B., et al. (2018). The Site Reliability Workbook, Chapitre 5 "Alerting on SLOs". O'Reilly. sre.google/workbook/alerting-on-slos/
  • Prometheus Authors. Alerting Rules. prometheus.io/docs/prometheus/latest/configuration/alerting_rules/
  • Prometheus Authors. Alertmanager Configuration. prometheus.io/docs/alerting/latest/configuration/
  • Grafana Labs. Grafana Alerting. grafana.com/docs/grafana/latest/alerting/
  • Kim, G., et al. (2016). The DevOps Handbook, Partie IV "Technical Practices of Feedback". IT Revolution Press.

Réservez un audit gratuit de 30 minutes. Je vous montre concrètement ce qu'on peut automatiser.