3h du matin, le pager se déclenche : HighCPUUsage, nœud à 92 %. Vous ouvrez un laptop, vous regardez, tout fonctionne. Les utilisateurs dorment, le batch qui a fait grimper le CPU s’est terminé tout seul, et vous retournez vous coucher agacé. Deux semaines de ce régime et l’équipe coupe le son du canal d’alertes. La règle était techniquement correcte et totalement inutile, parce qu’elle signalait une cause qui n’a pas forcément de conséquence visible.
L’idée la plus utile en alerting tient en une phrase : on réveille un humain sur un symptôme, et on laisse les causes sur les tableaux de bord. Un CPU élevé n’est pas un problème. Des réponses lentes en sont un. Si le CPU est à 92 % et que le service tient toujours sa cible de latence, il n’y a rien à faire. En alertant sur ce que les utilisateurs ressentent réellement, on obtient un pager qui veut dire « quelque chose est cassé maintenant » au lieu de « un chiffre a franchi un seuil ».
Alerte sur symptôme contre alerte sur cause
Une règle par cause surveille une ressource interne : CPU, mémoire, profondeur de file, remplissage disque. Une règle par symptôme surveille le contrat avec l’utilisateur : taux d’erreur, latence, disponibilité. Le défaut de l’alerte par cause, c’est que la correspondance entre cause et symptôme n’est pas bijective. Un CPU saturé fait mal parfois, et le plus souvent non. Un disque plein est une vraie urgence sur un nœud de base de données, un haussement d’épaules sur un réplica sans état. Chaque cause exige qu’un humain tranche pour savoir si elle compte, à 3h du matin, ce qui est précisément la décision que l’alerte était censée prendre à votre place.
Il ne s’agit pas de supprimer vos métriques de ressources. Gardez-les : c’est avec elles que vous diagnostiquez un incident une fois qu’une alerte de symptôme vous a réveillé. La règle de pouce tient en trois mots : les symptômes réveillent, les causes renseignent. Le disque qui se remplit et le certificat qui expire sont les exceptions honnêtes, parce que ce sont des causes dont le symptôme futur est garanti et prévisible ; alerter en avance est justement tout l’intérêt.
Ce que font vraiment for et le label de sévérité
Prometheus évalue les règles d’alerte à chaque evaluation_interval (1 minute par défaut). Quand l’expression d’une règle renvoie des séries, les alertes correspondantes passent à l’état pending. Elles ne deviennent firing, et ne sont transmises à Alertmanager, qu’une fois l’expression restée vraie sans interruption pendant la durée du champ for. Une seule évaluation où l’expression ne renvoie rien remet le compteur à zéro.
Cette clause for est votre premier filtre anti-bruit, et le moins cher. Une expression sans for se déclenche sur un seul scrape : un scrape lent isolé ou un pic transitoire suffit à vous notifier. for: 10m signifie « je ne m’y intéresse que si c’est encore vrai dans dix minutes », ce qui écarte exactement les micro-incidents auto-résolus à l’origine des fausses alertes nocturnes. La contrepartie est un délai de détection, alors ajustez-le par symptôme : un service franchement à terre justifie un for: 2m, une latence qui dérive lentement un for: 15m.
La sévérité est un simple label, pas une fonctionnalité intégrée. La convention retient severity: critical pour « réveiller quelqu’un » et severity: warning pour « à regarder en heures ouvrées ». Le label ne veut rien dire pour Prometheus lui-même ; il devient utile dans le routage Alertmanager, où l’on envoie critical vers le pager et warning vers un canal de discussion. Bien poser ce partage, c’est l’essentiel de ce qui sépare une astreinte sereine d’une astreinte épuisée. Si tout est critique, plus rien ne l’est.
Une mauvaise règle réécrite en bonne règle
Voici une règle qui a l’air raisonnable et qui notifie sans arrêt :
groups:
- name: bad.rules
rules:
- alert: HighCPUUsage
expr: rate(node_cpu_seconds_total{mode!="idle"}[5m]) > 0.8
labels:
severity: critical
annotations:
summary: "CPU élevé"
Tout y invite à la fatigue. Elle se déclenche par cœur et non par nœud, n’a pas de for donc un pic isolé notifie, qualifie un chiffre de consommation de critical, et son annotation ne dit rien d’exploitable au répondant. Réécrite autour d’un symptôme :
groups:
- name: good.rules
rules:
- alert: HighRequestErrorRate
expr: |
sum(rate(http_requests_total{status=~"5.."}[5m])) by (service)
/
sum(rate(http_requests_total[5m])) by (service)
> 0.05
for: 10m
labels:
severity: critical
annotations:
summary: "{{ $labels.service }} sert plus de 5 % d'erreurs"
description: "Ratio d'erreurs 5xx à {{ $value | humanizePercentage }} sur 5m. Vérifier les déploiements récents et les dépendances en aval."
runbook_url: "https://runbooks.internal/high-error-rate"
La bonne règle alerte sur ce que vit un utilisateur (une requête en échec), agrège à une unité qui a du sens (par service), survit à un pic transitoire (for: 10m) et fournit au répondant un point de départ via ses annotations et un lien de runbook. Décider où placer ce seuil de 5 % relève d’un error budget et d’un objectif de niveau de service défini, pas d’un nombre inventé au clavier. Et cette règle suppose que les bonnes métriques existent déjà : le taux d’erreur et la latence qu’on interroge ici viennent d’une application instrumentée pour les exposer, un préalable détaillé dans instrumenter une application avec Prometheus.
Les pièges qui résistent aux bonnes intentions
Trois pièges reviennent même dans un dispositif orienté symptômes. La division par zéro d’abord : un ratio comme celui ci-dessus ne renvoie rien quand un service ne reçoit aucun trafic, si bien qu’une panne stoppant toutes les requêtes peut faire taire l’alerte censée la détecter. Doublez les alertes de taux d’erreur d’un contrôle de trafic faible ou d’absence. Les seuils trop zélés sans notion de burn rate ensuite : un « 5 % pendant 10m » figé rate une combustion lente qui grignote le budget du mois et hurle sur un pic bref, d’où l’existence de l’alerting multi-fenêtre multi-burn-rate. L’inflation de critical enfin : chaque alerte ajoutée en critique parce qu’elle « semblait importante » entraîne l’astreinte à ignorer le pager, et un pager qu’on ignore est pire que pas de pager.
À retenir
Alertez sur les symptômes, gardez les causes pour le diagnostic. Servez-vous de for pour filtrer le bruit auto-résolu, et réservez critical à ce qui mérite vraiment de sortir un humain du lit. Rédigez les annotations pour la personne fatiguée qui les lit à 3h, pas pour vous qui les écrivez à 15h. Un dispositif d’alerte construit ainsi est un livrable central d’une mission fiabilité et observabilité. D’autres sujets dans la catégorie observabilité, et la même discipline appliquée aux sondes se trouve dans readiness et liveness sur Kubernetes.