Aller au contenu
medium

Alerting efficace : des alertes qui réveillent pour les bonnes raisons

38 min de lecture

Une alerte utile réveille quelqu’un pour une raison qui justifie d’être réveillé — et lui donne assez de contexte pour agir en moins de 5 minutes. C’est la définition complète. Pourtant, la majorité des systèmes d’alerting font l’inverse : ils noient les équipes sous des centaines de notifications inutiles (“CPU à 80 %”, “pod redémarré”, “disque à 70 %”) jusqu’à ce que tout le monde les ignore — y compris la seule alerte qui comptait vraiment. Ce guide vous apprend à construire un système d’alerting symptom-first, calibré sur vos SLO, avec les mécanismes anti-bruit de Prometheus et d’Alertmanager.

  • Symptom-first : pourquoi alerter sur l’impact utilisateur et pas sur les causes techniques — avec des exemples concrets pour HTTP, batch, queues et bases de données
  • Anatomie d’une alerte : les champs obligatoires d’une règle Prometheus pour qu’elle soit actionnable
  • Prometheus : for: — le premier filtre anti-bruit, directement dans les règles d’alerte
  • Alertmanager : grouping, inhibition, silences — la boîte à outils pour réduire l’alert fatigue côté notification
  • Seuils : statiques vs dynamiques, percentiles vs moyennes, et quand utiliser chacun
  • SLO-based alerting : le burn rate, le multi-window multi-burn-rate (MWMBR) — la méthode Google SRE pour alerter quand le budget d’erreur se consume trop vite
  • Watchdog et absent() : vérifier que la chaîne d’alerting fonctionne et détecter les métriques manquantes
  • Règles de qualité : chaque alerte doit avoir un runbook, un owner, une severity — sinon c’est du bruit
  • Escalade : qui avertir, quand, par quel canal — et la distinction entre le routing Alertmanager et l’escalade temporelle (PagerDuty, Opsgenie)
  • Anti-patterns : les erreurs classiques qui transforment un système d’alerting en machine à épuiser les équipes

Pourquoi la plupart des systèmes d’alerting échouent

Section intitulée « Pourquoi la plupart des systèmes d’alerting échouent »

Le problème a un nom : alert fatigue. Quand une équipe reçoit plus de quelques alertes par jour en moyenne, un engrenage se met en place :

  1. L’équipe commence à ignorer les alertes (surtout les “warning”)
  2. Pour compenser, elle silence massivement — y compris des alertes utiles
  3. Un jour, une alerte critique passe inaperçue — et l’incident dure
  4. Le management réagit en ajoutant des alertes — ce qui aggrave le problème

La cause racine est presque toujours la même : les alertes sont configurées sur les causes (CPU > 80 %, pod CrashLoopBackOff, latence réseau) au lieu des symptômes (les utilisateurs voient des erreurs, le service ne répond plus, le checkout est en panne).

Principe n°1 : alerter sur les symptômes, pas les causes

Section intitulée « Principe n°1 : alerter sur les symptômes, pas les causes »

Rob Ewaschuk, ex-SRE chez Google, a formalisé cette idée dans son document “My Philosophy on Alerting” : une alerte doit refléter un problème visible par l’utilisateur, pas un état interne de l’infrastructure.

Alerte cause (mauvaise)Alerte symptôme (bonne)Pourquoi
MySQL down""Error rate > 5 % sur le service commandes”Les utilisateurs voient des erreurs — c’est ça l’impact
”CPU > 90 %""Latence p99 > 2 s sur l’API checkout”Le CPU élevé n’est un problème que s’il dégrade le service
”Pod CrashLoopBackOff""Taux de succès < 99 % sur le service paiement”Le pod qui redémarre n’est un problème que si le service est dégradé
”Disque > 85 %""Erreurs d’écriture détectées sur le service logs”Le disque plein est une cause potentielle, l’échec d’écriture est le symptôme
”Certificat expire dans 7 jours”(celle-ci est légitime — c’est une alerte préventive)Exception : les alertes préventives sur des deadlines sont des symptômes “à venir”

Les alertes cause (CPU, disque, pod) ont leur place dans les dashboards comme aide au diagnostic — mais elles ne doivent pas réveiller quelqu’un. Incluez l’information de cause dans les annotations de l’alerte symptôme pour accélérer le diagnostic.

Le pattern REST/HTTP est le plus courant, mais le principe s’applique à tous les workloads. Voici les symptômes pertinents pour d’autres types de services :

Type de workloadAlerte cause (mauvaise)Alerte symptôme (bonne)
File d’attente / Kafka / RabbitMQ”Consumer lag > 10 000""Âge du plus vieux message non traité > 5 min” — c’est l’impact sur la fraîcheur des données
Batch / cron”Job failed""Le job n’a pas terminé avec succès dans la fenêtre attendue” — inclut les cas où le job ne s’est jamais lancé
Base de données (côté client)“Connexions MySQL > 80 %""Taux d’erreur des requêtes SQL côté application > 1 %” — c’est ce que l’application voit
Cache (Redis, Memcached)“Mémoire Redis > 90 %""Cache hit ratio < 80 %” ou “Latence p99 des requêtes cache > 50 ms”
Kubernetes”Pod CrashLoopBackOff""SLO du service dégradé” — un pod qui redémarre n’est un problème que s’il impacte le service

Une alerte Prometheus bien construite contient des labels pour le routing et des annotations pour le contexte humain. Voici la structure complète :

groups:
- name: payment-service
rules:
- alert: PaymentErrorRateHigh
expr: |
(
sum(rate(http_requests_total{service="payment-api", status=~"5.."}[5m]))
/
clamp_min(sum(rate(http_requests_total{service="payment-api"}[5m])), 1)
) > 0.01
for: 5m
labels:
severity: critical
team: payments
service: payment-api
annotations:
summary: "Taux d'erreur payment-api > 1 %"
description: >
Le service payment-api retourne {{ $value | humanizePercentage }}
d'erreurs 5xx sur les 5 dernières minutes.
Impact : les paiements échouent pour les utilisateurs.
dashboard_url: "https://grafana.example.com/d/payment-red"
runbook_url: "https://wiki.example.com/runbooks/payment-error-rate"
ChampRôleRègle de qualité
alertNom unique de l’alerteNom descriptif : ServiceSymptômeSévérité (ex: PaymentErrorRateHigh)
exprRequête PromQL — la condition de déclenchementToujours basée sur un symptôme, pas une cause. Protéger les divisions avec clamp_min
forDurée pendant laquelle la condition doit être vraie avant de déclencherFortement recommandé — empêche les alertes sur des pics transitoires (voir exceptions ci-dessous)
labels.severityNiveau de sévéritécritical (page), warning (Slack), info (ticket) — 3 niveaux max
labels.teamÉquipe responsableChaque alerte a un owner — sinon personne ne se sent responsable
labels.serviceService concernéPermet le routing et le grouping dans Alertmanager
annotations.summaryRésumé en une ligneCe qui est affiché dans la notification — clair et concis
annotations.descriptionDétail avec impactInclure la valeur actuelle ({{ $value }}), l’impact utilisateur, le contexte
annotations.dashboard_urlLien vers le dashboardLe SRE clique et voit immédiatement l’état du service
annotations.runbook_urlLien vers le runbookLa procédure de diagnostic et de remédiation — obligatoire pour les critical

Le champ for: est le premier filtre anti-bruit, directement dans la règle d’alerte Prometheus (pas dans Alertmanager). Il impose que la condition soit vraie en continu pendant la durée spécifiée avant que l’alerte ne passe de l’état pending à firing.

Sans for:, un pic de latence d’une seconde déclenche l’alerte. Avec for: 5m, la condition doit être continuellement vraie pendant 5 minutes avant que l’alerte ne fire. C’est le filtre le plus simple contre les faux positifs et les flapping alerts (alertes qui oscillent entre OK et FIRING).

Sévéritéfor: recommandéLogique
critical5 minAssez pour confirmer le problème, assez court pour réagir vite
warning15-30 minLe problème persiste mais n’est pas urgent — on attend pour confirmer
info1 h+Tendance de fond, pas d’urgence

Exceptions légitimes : quand omettre ou raccourcir for:

Section intitulée « Exceptions légitimes : quand omettre ou raccourcir for: »

Le for: est fortement recommandé par défaut, mais certains types d’alertes sont légitimes avec un for: très court ou absent :

Type d’alertePourquoi pas de for:
Watchdog / Deadman’s switchL’alerte doit toujours être active — le for: retarderait la détection d’une panne de l’alerting
Perte totale de traficSi le trafic tombe à zéro, quelques secondes suffisent pour confirmer
Certificat / deadlineL’alerte est préventive et basée sur un calcul (expiration dans N jours) — le for: n’apporte rien

Anti-bruit côté Alertmanager : grouping, inhibition, silences

Section intitulée « Anti-bruit côté Alertmanager : grouping, inhibition, silences »

Prometheus évalue les règles et envoie les alertes à Alertmanager, qui est responsable du routing (qui reçoit quoi), du grouping (regrouper les alertes liées), de l’inhibition (supprimer les alertes redondantes) et du silencing (taire les alertes pendant les maintenances).

Quand une base de données tombe, 50 services qui en dépendent génèrent chacun une alerte. Sans grouping, le SRE de garde reçoit 50 notifications en rafale. Avec le grouping, il reçoit 1 notification groupée.

# alertmanager.yml — extrait
route:
group_by: ['alertname', 'service']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
ParamètreRôleValeur recommandée
group_byLabels utilisés pour regrouper les alertes['alertname', 'service'] — une notification par alerte × service
group_waitDélai avant d’envoyer la première notification (attend d’autres alertes du même groupe)30 s — assez pour capturer les alertes corrélées
group_intervalDélai entre les mises à jour d’un groupe existant5 min — évite le spam si de nouvelles alertes rejoignent le groupe
repeat_intervalDélai avant de re-notifier si l’alerte est toujours active4 h — rappel régulier sans harcèlement

Si le cluster est down, inutile de recevoir en plus les alertes de chaque service. L’inhibition permet de supprimer automatiquement les alertes de faible priorité quand une alerte de haute priorité est active.

# alertmanager.yml — extrait
inhibit_rules:
- source_matchers:
- severity = critical
target_matchers:
- severity = warning
equal: ['service']

Cette règle dit : “si une alerte critical est active pour un service, supprime toutes les alertes warning du même service”. Le SRE ne voit que l’alerte la plus grave — il n’est pas distrait par les avertissements secondaires.

3. Silencing : taire les alertes pendant les maintenances

Section intitulée « 3. Silencing : taire les alertes pendant les maintenances »

Avant une maintenance planifiée (mise à jour, migration, redémarrage), créez un silence dans Alertmanager pour les services concernés. Sinon, chaque action de maintenance déclenche des alertes et pollue les canaux.

Un silence se crée via l’interface web d’Alertmanager ou via l’API :

Fenêtre de terminal
# Silence de 2 h sur le service payment-api
amtool silence add service="payment-api" \
--comment="Maintenance planifiée — mise à jour DB" \
--author="sre-team" \
--duration=2h

Choisir ses seuils : statiques, dynamiques, percentiles

Section intitulée « Choisir ses seuils : statiques, dynamiques, percentiles »

Le choix du seuil détermine la sensibilité de l’alerte : trop bas = faux positifs (bruit), trop haut = faux négatifs (incidents ratés).

Un seuil statique est une valeur fixe : “alerte si error rate > 1 %”, “alerte si latence p99 > 2 s”. C’est simple, compréhensible, et suffisant pour la majorité des cas.

# Seuil statique — error rate > 1 %
- alert: PaymentErrorRateHigh
expr: |
(
sum(rate(http_requests_total{service="payment-api", status=~"5.."}[5m]))
/
clamp_min(sum(rate(http_requests_total{service="payment-api"}[5m])), 1)
) > 0.01
for: 5m

Avantage : facile à comprendre, à expliquer, à auditer.

Limite : un seuil fixe ne s’adapte pas aux variations de trafic. 1 % d’erreurs à 3 h du matin (10 req/s) = 0.1 req/s en erreur. 1 % d’erreurs à 14 h (10 000 req/s) = 100 req/s en erreur — l’impact est radicalement différent.

Pour les seuils de latence, la même règle que pour les dashboards s’applique : n’alertez jamais sur la moyenne.

ApprocheProblèmeRecommandation
Moyenne > 2 s1 requête à 60 s + 99 à 10 ms = moyenne 610 ms — pas d’alerte, mais un utilisateur a attendu 1 minNe pas utiliser
p99 > 2 sLe 1 % des requêtes les plus lentes dépasse 2 s — détecte les outliersBon pour les alertes critiques
p50 > 500 msLa médiane dépasse 500 ms — l’expérience typique est dégradéeBon pour les alertes warning

Combinez les deux : critical sur p99, warning sur p50. Le p99 détecte les cas extrêmes, le p50 détecte les dégradations généralisées.

Les seuils dynamiques comparent la valeur actuelle à un historique (moyenne glissante, saisonnalité, bande de prédiction). Ils disent : “alerte si la valeur est anormale par rapport au comportement habituel”.

# Alerte si le taux de requêtes est 50 % inférieur
# à la moyenne de la même heure 7 jours avant
http_requests_total_rate5m
< 0.5 * avg_over_time(http_requests_total_rate5m[1h] offset 7d)

Les seuils dynamiques demandent une baseline propre (au moins 2-4 semaines de données stables) et une attention particulière aux jours fériés, campagnes marketing, et migrations qui faussent l’historique.

SLO-based alerting : le burn rate multi-window (MWMBR)

Section intitulée « SLO-based alerting : le burn rate multi-window (MWMBR) »

L’approche la plus sophistiquée — et la plus fiable — consiste à alerter non pas sur une valeur instantanée, mais sur la vitesse de consommation du budget d’erreur. C’est le burn rate alerting, décrit dans le chapitre 5 du Google SRE Workbook.

Si votre SLO de disponibilité est de 99.9 % sur 30 jours, votre budget d’erreur est de 0.1 % — soit environ 43 minutes d’indisponibilité autorisées par mois.

Le burn rate mesure la vitesse à laquelle ce budget se consume :

Burn rateSignificationBudget épuisé en
Consommation normale (0.1 % d’erreurs)30 jours (toute la fenêtre)
Deux fois plus vite que prévu15 jours
10×Dix fois plus vite3 jours
14.4×Très rapide — alerte critique~50 heures
36×Panne majeure~20 heures

L’idée : au lieu d’alerter sur un taux d’erreur instantané (qui peut être un pic transitoire), on alerte quand le budget d’erreur se consume trop vite pour tenir jusqu’à la fin de la fenêtre SLO.

Un burn rate élevé mesuré sur une seule fenêtre peut être un artefact (pic de 5 minutes qui fait monter la moyenne). La technique multi-window combine deux fenêtres :

  • une fenêtre longue pour confirmer la tendance
  • une fenêtre courte pour vérifier que le problème est actuel (pas un résidu d’un incident déjà résolu)

L’alerte ne se déclenche que si les deux fenêtres dépassent le seuil.

Le SRE Workbook recommande deux paires de fenêtres avec des burn rates différents — une pour les incidents rapides (page), une pour les dégradations lentes (ticket) :

NiveauBurn rateFenêtre longueFenêtre courtefor:Action
Page (critical)14.4×1 h5 min2 minIntervention immédiate
Ticket (warning)6 h30 min15 minAction dans les heures ouvrées

La paire Page détecte les incidents rapides : à 14.4×, le budget serait épuisé en ~50 heures — c’est assez rapide pour justifier une intervention immédiate. La paire Ticket détecte les dégradations lentes : à 6×, le budget serait épuisé en ~5 jours — assez pour créer un ticket, pas pour réveiller quelqu’un la nuit.

Pour un SLO de 99.9 % de disponibilité sur 30 jours :

groups:
- name: slo-payment-api
rules:
# Recording rules — pré-calcul du taux d'erreur
- record: service:http_error_ratio:rate5m
expr: |
sum by (service) (rate(http_requests_total{status=~"5.."}[5m]))
/
clamp_min(sum by (service) (rate(http_requests_total[5m])), 1)
- record: service:http_error_ratio:rate30m
expr: |
sum by (service) (rate(http_requests_total{status=~"5.."}[30m]))
/
clamp_min(sum by (service) (rate(http_requests_total[30m])), 1)
- record: service:http_error_ratio:rate1h
expr: |
sum by (service) (rate(http_requests_total{status=~"5.."}[1h]))
/
clamp_min(sum by (service) (rate(http_requests_total[1h])), 1)
- record: service:http_error_ratio:rate6h
expr: |
sum by (service) (rate(http_requests_total{status=~"5.."}[6h]))
/
clamp_min(sum by (service) (rate(http_requests_total[6h])), 1)
# --- Page (critical) : burn rate 14.4× ---
# Fenêtre longue 1h + fenêtre courte 5m
- alert: SLOBudgetBurnCritical
expr: |
service:http_error_ratio:rate1h{service="payment-api"} > (14.4 * 0.001)
and
service:http_error_ratio:rate5m{service="payment-api"} > (14.4 * 0.001)
for: 2m
labels:
severity: critical
team: payments
slo: availability
annotations:
summary: "Burn rate critique — budget d'erreur payment-api se consume 14× trop vite"
description: >
Le service payment-api consomme son budget d'erreur (SLO 99.9 %)
au rythme de {{ $value | humanize }}× la normale. À ce rythme,
le budget sera épuisé bien avant la fin de la fenêtre de 30 jours.
runbook_url: "https://wiki.example.com/runbooks/slo-budget-burn"
# --- Ticket (warning) : burn rate 6× ---
# Fenêtre longue 6h + fenêtre courte 30m
- alert: SLOBudgetBurnWarning
expr: |
service:http_error_ratio:rate6h{service="payment-api"} > (6 * 0.001)
and
service:http_error_ratio:rate30m{service="payment-api"} > (6 * 0.001)
for: 15m
labels:
severity: warning
team: payments
slo: availability
annotations:
summary: "Burn rate élevé — budget d'erreur payment-api se consume 6× trop vite"
runbook_url: "https://wiki.example.com/runbooks/slo-budget-burn"

Quand utiliser le burn rate vs les seuils statiques

Section intitulée « Quand utiliser le burn rate vs les seuils statiques »
SituationApproche recommandée
Service sans SLO définiSeuils statiques (error rate > X %, latence p99 > Y s)
Service avec SLO mais trafic faible (< 100 req/min)Seuils statiques — le burn rate est instable sur peu de données
Service avec SLO et trafic significatif (> 100 req/min)MWMBR — c’est la méthode la plus fiable
Alerte préventive (certificat, disque)Seuils statiques — pas de notion de SLO

Santé de la chaîne d’alerting : Watchdog et absent()

Section intitulée « Santé de la chaîne d’alerting : Watchdog et absent() »

Un système d’alerting qui ne fonctionne plus sans que personne ne le sache est pire qu’un système sans alerting — il donne une fausse impression de sécurité. Deux mécanismes permettent de détecter ces pannes silencieuses.

Le Watchdog est une alerte qui doit toujours être en état firing. Si elle disparaît, c’est que la chaîne d’alerting est cassée (Prometheus ne scrape plus, Alertmanager ne reçoit plus rien, le receiver est en panne).

groups:
- name: meta-alerting
rules:
- alert: Watchdog
expr: vector(1)
labels:
severity: info
annotations:
summary: "Watchdog — chaîne d'alerting OK"
description: >
Cette alerte doit toujours être en firing. Si elle disparaît,
c'est que Prometheus, Alertmanager ou le receiver est en panne.

Configurez votre outil d’astreinte (PagerDuty, Opsgenie, Grafana OnCall) pour recevoir un heartbeat du Watchdog. Si le heartbeat cesse pendant plus de 5 minutes, l’outil d’astreinte page automatiquement — c’est le filet de sécurité ultime.

Un cas classique : votre exporter tombe, les métriques disparaissent, et vos alertes basées sur ces métriques ne se déclenchent plus (pas de données = pas de condition remplie = pas d’alerte). C’est le piège du “no data means no alert”.

La fonction absent() de Prometheus détecte la disparition d’une série temporelle :

groups:
- name: scrape-health
rules:
# Détecte si un node-exporter ne remonte plus de métriques
- alert: NodeExporterDown
expr: absent(up{job="node-exporter"} == 1)
for: 5m
labels:
severity: warning
team: platform
annotations:
summary: "node-exporter ne remonte plus de métriques"
description: >
Le job node-exporter n'a plus de target avec up=1 depuis 5 min.
Cause probable : exporter crashé, pod non schedulé, ou scrape
config incorrecte.
runbook_url: "https://wiki.example.com/runbooks/exporter-down"
# Détecte si aucune métrique HTTP n'arrive pour un service critique
- alert: NoHTTPMetrics
expr: absent(http_requests_total{service="payment-api"})
for: 10m
labels:
severity: critical
team: payments
annotations:
summary: "Aucune métrique HTTP reçue pour payment-api"
description: >
Aucune série http_requests_total n'existe pour le service
payment-api depuis 10 min. Soit l'application est down, soit
l'instrumentation est cassée.
SituationCe que vous voyezCe que absent() détecte
Exporter downLa cible disparaît de Prometheusabsent(up{job="..."} == 1) — la série up n’existe plus
Application non instrumentéePas de métriques applicativesabsent(http_requests_total{service="..."}) — la série n’a jamais existé ou a disparu
Pipeline de collecte casséLes métriques s’arrêtent d’arriverabsent() sur les métriques clés du pipeline (ex: logs/s, spans/s)

Règles de qualité : chaque alerte doit être complète

Section intitulée « Règles de qualité : chaque alerte doit être complète »

Une alerte sans runbook, c’est un réveil à 3 h du matin suivi de 30 minutes de “qui sait ce que c’est ?”. Chaque alerte critical doit respecter 5 critères avant d’être mise en production :

CritèreQuestionSi la réponse est “non”
OwnerQuelle équipe est responsable ?L’alerte ne sera jamais traitée — personne ne se sent concerné
RunbookUn lien runbook_url vers la procédure de diagnostic existe-t-il ?Le SRE de garde perd du temps à chercher quoi faire
SeverityLe niveau (critical/warning/info) est-il justifié ?Tout en critical = plus rien n’est critical
ActionnableLe destinataire peut-il faire quelque chose ?L’alerte est du bruit — transformez-la en métrique de dashboard
TestéeL’alerte a-t-elle été testée dans un environnement dédié ?Risque de faux positifs ou de non-déclenchement

Adoptez une convention de nommage systématique pour que chaque alerte soit identifiable au premier coup d’œil :

Format : ServiceSymptômeSévérité
Exemples :
PaymentErrorRateHigh → critical
PaymentLatencyDegraded → warning
CheckoutAvailabilityLow → critical
CertificateExpiresIn7Days → warning
SeverityActionCanalHoraire
criticalIntervention immédiate — le SRE de garde est paginéPagerDuty / Opsgenie / Grafana OnCall24/7
warningAction requise dans les heures qui viennentSlack / Teams / emailHeures ouvrées
infoÀ traiter quand possible — ticket automatiqueJira / GitLab IssuesBacklog

Escalade : routing Alertmanager + outil d’astreinte

Section intitulée « Escalade : routing Alertmanager + outil d’astreinte »

L’escalade a deux composantes distinctes qu’il ne faut pas confondre :

  • Alertmanager gère le routing : quelle alerte va vers quel receiver (PagerDuty, Slack, Jira) en fonction des labels (severity, team)
  • L’outil d’astreinte (PagerDuty, Opsgenie, Grafana OnCall) gère l’escalade temporelle : si personne ne répond en 15 min, on page le secondaire, puis le manager

Alertmanager ne fait pas d’escalade temporelle — il envoie la notification initiale au bon receiver, point. L’escalade (T+15, T+30) est configurée dans l’outil d’astreinte.

Structure d’escalade type (côté outil d’astreinte)

Section intitulée « Structure d’escalade type (côté outil d’astreinte) »
DélaiActionDestinataire
T+0Page (notification push + appel)SRE de garde (primaire)
T+15 minRe-page si non acquittéeSRE de garde (secondaire)
T+30 minEscaladeEngineering Manager
T+1 hEscaladeVP Engineering / incident commander

Le routing dans Alertmanager utilise un arbre de correspondance : chaque alerte descend dans l’arbre selon ses labels jusqu’à trouver le receiver approprié.

# alertmanager.yml — routing
route:
receiver: 'default-slack'
group_by: ['alertname', 'service']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
routes:
# Alertes critical → PagerDuty (l'escalade est gérée côté PagerDuty)
- matchers:
- severity = critical
receiver: 'pagerduty-critical'
repeat_interval: 1h
routes:
# Sous-route : équipe payments
- matchers:
- team = payments
receiver: 'pagerduty-payments'
# Alertes warning → Slack canal équipe
- matchers:
- severity = warning
receiver: 'slack-warnings'
repeat_interval: 4h
# Alertes info → webhook vers Jira
- matchers:
- severity = info
receiver: 'jira-tickets'
repeat_interval: 24h
receivers:
- name: 'default-slack'
slack_configs:
- channel: '#alerts-general'
- name: 'pagerduty-critical'
pagerduty_configs:
- service_key: '<PD_SERVICE_KEY>'
- name: 'pagerduty-payments'
pagerduty_configs:
- service_key: '<PD_PAYMENTS_KEY>'
- name: 'slack-warnings'
slack_configs:
- channel: '#alerts-warnings'
- name: 'jira-tickets'
webhook_configs:
- url: 'https://jira.example.com/api/alertmanager-webhook'
Anti-patternPourquoi c’est un problèmeSolution
Alerter sur les causes (CPU, RAM, pod restart)Bruit — ces métriques fluctuent sans impact utilisateurAlerter sur les symptômes (error rate, latence, disponibilité)
Pas de for: (sauf Watchdog)Un pic d’1 seconde déclenche l’alerteMinimum 5 min pour critical, 15 min pour warning
Tout en criticalLe mot perd son sens, l’équipe ignore3 niveaux (critical, warning, info) avec des critères stricts
Pas de runbookLe SRE de garde ne sait pas quoi faireChaque critical a un lien runbook_url dans les annotations
Pas de grouping50 notifications pour le même incidentgroup_by: ['alertname', 'service'] dans Alertmanager
Pas d’inhibitionAlertes warning + critical en parallèle — confusionInhiber les warning quand un critical est actif sur le même service
Alerter sur la moyenneMasque les outliers, fausse impression de normalitéAlerter sur p99 (critical) et p50 (warning)
Seuils jamais revusLes seuils de 2022 ne correspondent plus au trafic de 2026Revue trimestrielle des seuils et des alertes
Silences permanentsMasque des problèmes réelsDurée maximale d’un silence = durée de la maintenance + 30 min
Escalade manuelle”Appelle le manager si c’est grave” — personne ne le fait à 3 h du matinEscalade automatique configurée dans PagerDuty/Opsgenie
Alertes non versionnéesModifications non traçables, pas de reviewAlertes as code dans Git, déployées via CI/CD
Pas de WatchdogSi l’alerting tombe, personne ne le saitToujours avoir un Watchdog + heartbeat côté outil d’astreinte
Division sans clamp_minNaN si trafic = 0, alerte imprévisibleclamp_min(dénominateur, 1) sur tous les ratios

Métriques d’alerting : mesurer la santé du système

Section intitulée « Métriques d’alerting : mesurer la santé du système »

Un système d’alerting a besoin d’être observé lui-même. Suivez ces métriques pour savoir si vos alertes sont utiles ou si elles dérivent :

MétriqueCibleSi hors cible
Alertes critical / semaine2-3 maxTrop de bruit → revoir les seuils ou passer en warning
% d’alertes actionnables> 80 %Trop de faux positifs → revoir les conditions et les for:
MTTA (Mean Time To Acknowledge)< 15 minL’équipe ne réagit pas → problème d’escalade ou d’alert fatigue
Taux de flapping< 5 %Seuils trop proches du comportement normal → ajouter de l’hystérésis
Alertes silencées (%)< 10 %Trop d’alertes inutiles que l’équipe silence au lieu de corriger
Alertes sans runbook (%)0 % pour les criticalUn critical sans runbook est un billet de loterie

Chaque trimestre, passez en revue votre système d’alerting :

  1. Quelles alertes ont sonné le plus ? — Si une alerte sonne 20 fois par semaine, elle est soit mal calibrée, soit un symptôme d’un problème de fond non résolu
  2. Quelles alertes n’ont jamais sonné ? — Après 6 mois sans trigger, l’alerte est peut-être obsolète ou son seuil est trop haut
  3. Quelles alertes ont été systématiquement silencées ? — C’est un signe qu’elles sont du bruit — corrigez-les ou supprimez-les
  4. Les runbooks sont-ils à jour ? — Un runbook périmé est pire que pas de runbook (il donne de fausses instructions)
  1. Listez vos services critiques et leurs SLO

    Identifiez les 3-5 services dont l’indisponibilité a le plus d’impact métier. Si vous n’avez pas encore de SLO, définissez des cibles initiales (ex: 99.9 % de disponibilité, latence p99 < 500 ms).

  2. Écrivez les alertes symptom-first

    Pour chaque service : une alerte sur le taux d’erreur (symptôme principal) et une alerte sur la latence (dégradation). Pas plus de 2-3 alertes critical par service pour commencer.

  3. Ajoutez les annotations et les runbooks

    Chaque alerte doit avoir : summary, description avec impact, lien dashboard_url, lien runbook_url. Pas de runbook = pas de mise en production de l’alerte.

  4. Configurez le Watchdog et les alertes absent()

    Déployez le Watchdog + heartbeat côté outil d’astreinte. Ajoutez absent() sur les exporters et métriques critiques. C’est le filet de sécurité qui détecte les pannes silencieuses.

  5. Configurez Alertmanager

    Routing par severity et par équipe, grouping (group_by: ['alertname', 'service'] — ajoutez cluster/env si multi-cluster), inhibition (critical supprime warning), silencing (procédure documentée pour les maintenances).

  6. Configurez l’escalade dans l’outil d’astreinte

    Dans PagerDuty/Opsgenie/Grafana OnCall : primaire → secondaire → manager avec des délais explicites (15 min, 30 min). Alertmanager route vers l’outil, l’outil escalade si personne ne répond.

  7. Testez de bout en bout

    Simulez un incident (inject error rate) et vérifiez : l’alerte se déclenche ? La notification arrive au bon canal ? Le lien dashboard fonctionne ? Le runbook est accessible ? Le Watchdog heartbeat est actif ?

  8. Mesurez et itérez

    Après 2 semaines, consultez les métriques d’alerting (MTTA, % actionnable, flapping). Ajustez les seuils, les for:, le routing. L’alerting est un système vivant — il doit évoluer avec votre infrastructure.

PiègeConséquenceSolution
Commencer par 50 alertesAlert fatigue immédiate — l’équipe ignore toutCommencer par 5-10 alertes sur les services les plus critiques
Copier les alertes d’un article de blogSeuils non adaptés à votre contexteCalibrer chaque seuil sur vos données réelles (baseline 2 semaines)
Alerter depuis le dashboard GrafanaLes alertes dépendent de Grafana — si Grafana tombe, plus d’alertesAlertes = rules Prometheus + Alertmanager, indépendants de Grafana
Pas de distinction critical/warningTout se mélange, rien n’est priorisé3 niveaux max, critères stricts pour chaque niveau
Runbook = “regarder le dashboard”Ce n’est pas un runbook, c’est un post-itUn runbook = symptôme → diagnostic → remédiation → escalade
  1. Alertez sur les symptômes (impact utilisateur), pas sur les causes (CPU, RAM, pod restart) — les causes ont leur place dans les dashboards, pas dans les alertes. Le pattern s’applique aussi aux queues (âge du message), batch (échec dans la fenêtre attendue) et bases de données (taux d’erreur côté client)

  2. Le champ for: (côté Prometheus) est votre premier anti-bruit : 5 min par défaut pour les critical, 15-30 min pour les warning — exceptions : Watchdog, perte totale de trafic, deadlines

  3. Côté Alertmanager, utilisez grouping (une notification par incident, pas 50), inhibition (critical supprime warning) et silencing (maintenances) — ajoutez cluster/env au group_by en multi-cluster

  4. Pour les services avec des SLO et un trafic suffisant, le MWMBR (multi-window multi-burn-rate) est la méthode la plus fiable : page à 14.4× (1 h + 5 min), ticket à 6× (6 h + 30 min)

  5. Chaque alerte critical doit avoir un owner, un runbook_url, une severity justifiée et être testée — sinon c’est du bruit

  6. Déployez un Watchdog (alerte toujours firing + heartbeat) et des alertes absent() sur vos exporters critiques — sans eux, une panne de l’alerting passe inaperçue

  7. L’escalade temporelle (T+15, T+30) se configure dans l’outil d’astreinte (PagerDuty, Opsgenie), pas dans Alertmanager — Alertmanager fait le routing, l’outil fait l’escalade

  8. Revoyez vos alertes chaque trimestre : alertes trop fréquentes, jamais déclenchées, systématiquement silencées — chacune est un signal que le système doit évoluer

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.