Production sans supervision : apprendre que vous êtes en panne par un client

Cet article vous a aidé ?

Le pire système d’alerte est un être humain qui vous paie. Il arrive en retard, incomplet et formaté émotionnellement.
«Votre site est cassé» n’est pas un symptôme. C’est un réquisitoire.

Faire tourner la production sans supervision, c’est comme voler sans instruments et appeler ça «agile».
Vous pouvez le faire jusqu’au moment où vous ne pouvez plus, et alors vous découvrez la vraie signification du «temps moyen pour innocenter».

Ce que signifie vraiment «sans supervision» (et pourquoi ça arrive)

«Sans supervision» signifie rarement littéralement rien. Cela veut généralement dire aucune supervision utile pendant un incident.
Il peut y avoir des tableaux de bord que personne ne regarde, des logs que personne ne sait interroger, et une page d’état mise à jour par quelqu’un criant à travers la salle.

En pratique, «sans supervision» est l’un de ces modes de défaillance :

  • Pas de signal externe : rien ne vérifie le service depuis l’extérieur, donc le succès interne vous trompe.
  • Pas de routage d’alerte : les métriques existent, mais personne n’est pagé, ou les alertes vont dans une boîte mail morte depuis 2019.
  • Pas de golden signals : vous collectez CPU et RAM, mais pas la latence, les erreurs, la saturation ou le trafic.
  • Pas de corrélation : vous avez métriques, logs et traces, mais ils ne partagent pas d’identifiants, de synchronisation temporelle ou de rétention.
  • Pas de responsabilité : «équipe plateforme» est un alias e‑mail, pas une équipe ; le SRE est «celui qui a le plus de contexte».
  • Pas de budget : la supervision la moins coûteuse, c’est «on l’ajoutera plus tard», ce qui est aussi la plus chère.

La raison pour laquelle cela arrive n’est que rarement l’ignorance. Ce sont les incitations. Déployer des fonctionnalités est visible. Prévenir des pannes est invisible.
Jusqu’au jour où c’est extrêmement visible.

Voici la dure vérité : si vous ne pouvez pas répondre «est‑ce que c’est en panne?» en moins de 60 secondes, vous n’avez pas de supervision.
Vous avez des impressions.

Faits et histoire qui expliquent le désordre d’aujourd’hui

L’observabilité n’est pas apparue parce que les ingénieurs aiment les graphiques. Elle est apparue parce que la production se mettait sans cesse en feu, et que les humains en ont eu assez.
Quelques points de contexte concrets qui comptent :

  1. SNMP (fin des années 1980) a rendu possible l’interrogation d’appareils réseau à grande échelle, mais a aussi normalisé «polling = supervision» même quand les applications étaient le problème.
  2. Ère Nagios (années 2000) a popularisé les vérifications «est‑ce que c’est en ligne?» et les patterns de page‑on‑fail ; utile pour des hôtes, médiocre pour des systèmes distribués.
  3. Le livre Google SRE (milieu des années 2010) a mis les SLO et les budgets d’erreur dans l’opérationnel grand public, requalifiant la fiabilité en fonctionnalité produit, pas en hobby.
  4. Microservices (années 2010) ont multiplié les modes de panne : une requête utilisateur touche maintenant 10–100 composants, transformant «logs sur la machine» en archéologie.
  5. Bases temporelles et stockage bon marché ont rendu possible la conservation de métriques haute résolution, mais ont aussi encouragé l’anti‑pattern de tout collecter sans rien comprendre.
  6. Orchestration de conteneurs a changé «serveur en panne» en «pod replanifié», ce qui est bien, jusqu’à ce que vous réalisiez qu’une replanification peut cacher une boucle de crash pendant des semaines.
  7. Pannes majeures des clouds ont appris aux entreprises que «le cloud c’est l’ordinateur de quelqu’un d’autre» veut aussi dire «le domaine de panne de quelqu’un d’autre». Vous avez toujours besoin d’instrumentation.
  8. La culture moderne des incidents est passée du blâme à la pensée systémique — du moins dans les entreprises qui veulent garder des ingénieurs employés au‑delà d’une rotation d’astreinte.

Une idée paraphrasée, parce qu’elle reste vraie à travers les décennies : «L’espoir n’est pas une stratégie.» — idée souvent attribuée au général Gordon R. Sullivan, souvent répétée dans la culture ops.

La réalité technique de «le client est le pager»

Quand un client vous dit que vous êtes en panne, trois choses sont déjà vraies :

  • Vous avez perdu du temps : l’incident a commencé avant le signalement. Votre horloge MTTR tourne déjà.
  • Vous avez perdu en fidélité : les symptômes clients sont filtrés par des navigateurs, des réseaux et l’interprétation humaine.
  • Vous avez perdu la confiance : ils ont découvert votre défaillance avant vous, et ce n’est pas un bon moment pour la marque.

Le problème opérationnel n’est pas seulement la détection. C’est le triage.
La supervision n’est pas «des graphiques». C’est la capacité à répondre rapidement à une séquence de questions de production :

  1. Le service est‑il en panne ou seulement lent ?
  2. Le problème est‑il global ou régional, pour un seul tenant ou tous ?
  3. Est‑ce que ça a commencé après un déploiement, un changement de config ou un pic de charge ?
  4. Le goulot est‑il CPU, mémoire, disque, réseau, latence d’une dépendance ou un verrou ?
  5. Est‑ce que c’est dégradant (fuite) ou soudain (crash) ?
  6. Est‑ce qu’on empire la situation avec des tempêtes de retry, de l’autoscaling ou des boucles de basculement ?

Sans supervision, vous vous retrouvez à faire de la «forensique de production» sous pression : SSH sur des machines, tail des logs, deviner, redémarrer, espérer.
Ça fonctionne parfois, surtout quand le problème est trivialement résolu par un reboot. Ça ne scale pas, et c’est un excellent moyen de créer un second incident.

Blague n°1 : Faire tourner sans supervision, c’est comme conduire la nuit sans phares parce que «la route a l’air bien sur le parking».

Pourquoi «on le remarquera vite» est presque toujours faux

Les équipes supposent que les utilisateurs signaleront rapidement les pannes. Parfois oui. Parfois non.
Les pannes les plus silencieuses sont souvent les plus dommageables :

  • Défaillances partielles : un endpoint API échoue, une région échoue, ou un segment client échoue.
  • Défaillances lentes : la latence augmente progressivement jusqu’à ce que les clients churnent plutôt que de se plaindre.
  • Erreurs de correction des données : les réponses sont rapides et incorrectes. Vous n’obtenez pas de plaintes ; vous obtenez des audits.
  • Échecs de jobs en arrière‑plan : facturation, e‑mail, exports, ETL. Personne ne vérifie avant la clôture mensuelle.

La supervision ne concerne pas seulement le temps de fonctionnement. Elle concerne la correction, la performance et la capacité.
Il s’agit de savoir que le système fait la bonne chose, à la bonne vitesse, pour les bonnes personnes.

Playbook de diagnostic rapide : premières/deuxièmes/troisièmes vérifications

Voici le playbook «le client dit que nous sommes en panne». L’objectif n’est pas d’être brillant ; il est d’être rapide, répétable et difficile à foirer.
Vous cherchez le goulot et le rayon d’impact.

Premier : confirmer le symptôme depuis l’extérieur

  • Vérifiez le point d’entrée public depuis deux réseaux (votre réseau corporate et un hotspot téléphone) pour éliminer les problèmes DNS/VPN locaux.
  • Capturez le statut HTTP, la latence et un identifiant de requête si disponible.
  • Décidez : est‑ce une panne dure (connection refused/timeouts) ou une panne douce (500s/lenteur) ?

Deuxième : déterminer le rayon d’impact

  • Est‑ce une région/zone ? Un client/tenant ? Un endpoint ?
  • Vérifiez d’abord les composants de bord : DNS, load balancer, ingress, CDN, expiration de certificats.
  • Décidez : est‑ce un problème de routage du trafic ou un problème de capacité applicative ?

Troisième : isoler la catégorie du goulot

  • Calcul : CPU saturé, load élevé, file d’exécution pleine.
  • Mémoire : OOM kills, tempêtes d’swap, croissance RSS.
  • Disque : systèmes de fichiers pleins, iowait élevé, pics de latence, RAID/ZFS dégradé.
  • Réseau : perte de paquets, exhaustion conntrack, trafic mal routé, blocages de handshake TLS.
  • Dépendances : BDD saturée, cache down, API amont lente, délais de résolution DNS.

Quatrième : arrêter l’hémorragie en sécurité

  • Revenir sur le dernier déploiement/config si cela correspond au début.
  • Limiter le débit ou sacrifier de la charge (retourner 429/503) plutôt que de fondre.
  • Scaler uniquement si vous êtes sûr de ne pas amplifier une défaillance d’une dépendance.
  • Décidez : atténuer maintenant, diagnostiquer après stabilisation.

Cinquième : préserver les preuves

  • Instantanénez les logs, capturez l’état des processus, enregistrez les horodatages.
  • Assurez‑vous que les horloges système sont saines ; la dérive temporelle ruine la corrélation.
  • Décidez : de quoi a‑t‑on besoin pour le postmortem, avant que «le redémarrage règle ça».

Tâches pratiques : commandes, sorties et décisions

Ci‑dessous se trouvent des tâches concrètes que vous pouvez exécuter lors d’un incident. Chacune contient : une commande, une sortie représentative, ce que ça signifie et la décision à prendre.
Choisissez celles qui correspondent à votre stack ; ne jouez pas au sorcier Linux si vous êtes sur des services managés. Mais apprenez la forme des signaux.

Task 1: Confirm DNS is returning what you think

cr0x@server:~$ dig +short api.example.com
203.0.113.10

Ce que cela signifie : Vous avez obtenu un enregistrement A. S’il est vide, renvoie une IP inattendue ou change entre deux requêtes, vous pouvez avoir un problème de propagation DNS ou de split‑horizon.

Décision : Si le DNS semble incorrect, arrêtez de toucher l’application. Corrigez le routage (enregistrement, TTL, zone, health checks) ou contorcez avec une IP connue pour le débogage.

Task 2: Check TLS validity and handshake from outside

cr0x@server:~$ echo | openssl s_client -servername api.example.com -connect api.example.com:443 2>/dev/null | openssl x509 -noout -dates
notBefore=Jan 10 00:00:00 2026 GMT
notAfter=Apr 10 23:59:59 2026 GMT

Ce que cela signifie : Si cela échoue à se connecter ou montre un cert expiré, votre «panne» peut être une rotation de certificat ratée.

Décision : Si le certificat est expiré ou la chaîne cassée, priorisez la correction du certificat plutôt que le débogage applicatif ; aucune montée en charge ne corrige la cryptographie.

Task 3: Measure endpoint behavior (status + latency)

cr0x@server:~$ curl -sS -o /dev/null -w "code=%{http_code} total=%{time_total} connect=%{time_connect} ttfb=%{time_starttransfer}\n" https://api.example.com/health
code=503 total=2.413 connect=0.012 ttfb=2.390

Ce que cela signifie : Connexion rapide, TTFB lent implique que le serveur a accepté la connexion mais n’a pas pu répondre vite — latence applicative ou dépendance, pas un pur problème réseau.

Décision : Traitez comme une «panne douce» et concentrez‑vous sur la saturation ou les timeouts de dépendance plutôt que DNS ou firewall.

Task 4: Identify whether the host is overloaded (CPU/run queue)

cr0x@server:~$ uptime
 14:02:11 up 36 days,  3:18,  2 users,  load average: 38.12, 35.77, 29.05

Ce que cela signifie : Une charge moyenne bien au‑dessus du nombre de CPU indique beaucoup de tâches exécutables ou bloquées. «Bloquées» signifie souvent attente I/O, pas CPU.

Décision : Vérifiez immédiatement iowait et l’usage proces par processus ; n’ajoutez pas de CPU en espérant que ça suffise.

Task 5: See CPU, iowait, and saturation quickly

cr0x@server:~$ mpstat -P ALL 1 3
Linux 6.5.0 (app-01)  02/02/2026  _x86_64_  (16 CPU)

02:02:15 PM  all  %usr %sys %iowait %idle
02:02:16 PM  all  12.3  6.1   62.4  19.2
02:02:17 PM  all  10.9  5.7   64.0  19.4
02:02:18 PM  all  11.1  5.9   63.2  19.8

Ce que cela signifie : Un %iowait élevé signifie que les CPU sont inactifs mais attendent le disque. Votre problème est la latence de stockage ou la saturation disque.

Décision : Arrêtez de scaler les instances applicatives comme premier réflexe ; trouvez ce qui cloue le disque (logs, BDD, swap, compactions) et atténuez.

Task 6: Find the top offenders by CPU and memory

cr0x@server:~$ ps -eo pid,comm,%cpu,%mem,rss --sort=-%cpu | head
  PID COMMAND         %CPU %MEM    RSS
 7321 java            380 12.4 2068420
  914 nginx            45  0.6   98120
 5210 node             33  2.1  349812

Ce que cela signifie : Un processus Java consommant plusieurs cœurs fortement suggère un travail lié au calcul ou une boucle incontrôlée.

Décision : Si c’est CPU‑bound et corrélé au trafic, envisagez du shedding, réduire la concurrence ou rollback. Si inattendu, capturez des stacks avant de redémarrer.

Task 7: Check for OOM kills (silent service death)

cr0x@server:~$ dmesg -T | tail -n 8
[Mon Feb  2 13:58:41 2026] Out of memory: Killed process 5210 (node) total-vm:4123456kB, anon-rss:1765432kB, file-rss:0kB, shmem-rss:0kB
[Mon Feb  2 13:58:41 2026] oom_reaper: reaped process 5210 (node), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB

Ce que cela signifie : Le noyau a tué un processus. Votre service peut redémarrer «au hasard», flapper ou disparaître.

Décision : Atténuez en réduisant l’utilisation mémoire, ajustant les limites, ajoutant de la RAM ou corrigeant les fuites. Ajoutez aussi des alertes sur les événements OOM ; ils ne sont pas subtils, juste ignorés.

Task 8: Check disk space (the classic boring outage)

cr0x@server:~$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme0n1p2  200G  200G     0 100% /

Ce que cela signifie : Disque plein. Attendez‑vous à des effets secondaires bizarres : écritures échouées, processus bloqués, risque de corruption BDD, échecs du gestionnaire de paquets.

Décision : Libérez de l’espace en sécurité : supprimer vieux logs, faire une rotation, déplacer des artefacts, étendre le disque. Puis corrigez la cause racine (politiques de rétention, logs en boucle, dumps trop volumineux).

Task 9: Find what’s eating disk right now

cr0x@server:~$ sudo du -xhd1 /var | sort -h
120M	/var/cache
2.1G	/var/lib
38G	/var/log

Ce que cela signifie : /var/log est énorme. C’est souvent l’incident «on a activé le debug logging».

Décision : Faites tourner/tronçonnez les plus gros coupables, puis fixez des niveaux de log sensés et la rotation. Si vous avez besoin de logs debug, envoyez‑les hors machine avec une rétention.

Task 10: Check disk latency and saturation (where outages hide)

cr0x@server:~$ iostat -xz 1 3
Linux 6.5.0 (app-01)  02/02/2026  _x86_64_  (16 CPU)

avg-cpu:  %user %system %iowait  %idle
          11.2    5.8   63.7    19.3

Device            r/s     w/s   rkB/s   wkB/s  await  svctm  %util
nvme0n1          12.0   850.0   512.0  98432.0  48.3   1.2   99.8

Ce que cela signifie : %util proche de 100% et await élevé signifie que le périphérique est saturé ; les écritures sont mises en file et tout ralentit.

Décision : Identifiez l’écrivain (checkpoint BDD, inondation de logs, job de sauvegarde). Limitez‑le, déplacez‑le ou scalez le stockage. Ne faites pas semblant que c’est «juste CPU».

Task 11: Validate service health under systemd

cr0x@server:~$ systemctl status nginx --no-pager
● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled)
     Active: active (running) since Mon 2026-02-02 13:40:07 UTC; 21min ago

Ce que cela signifie : Le processus est en cours. Cela ne signifie pas que le service fonctionne ; il peut être bloqué ou renvoyer des erreurs.

Décision : Si «active» mais que les utilisateurs échouent, vérifiez la santé en amont, le nombre de connexions et les logs. Ne vous arrêtez pas là et ne déclarez pas victoire.

Task 12: Check recent logs for obvious errors

cr0x@server:~$ journalctl -u nginx -S "-15 min" --no-pager | tail -n 8
Feb 02 13:55:10 app-01 nginx[914]: connect() failed (111: Connection refused) while connecting to upstream, client: 198.51.100.33, server: api.example.com, request: "GET /v1/orders HTTP/2.0", upstream: "http://127.0.0.1:8080/v1/orders"

Ce que cela signifie : Nginx ne peut pas atteindre l’app upstream sur 127.0.0.1:8080. C’est probablement un crash de l’app, un échec de bind ou un firewall local.

Décision : Examinez le service upstream : port à l’écoute, crash loop, OOM, config. Corrigez l’app en premier ; nginx n’est que le messager.

Task 13: Confirm a port is listening (and by whom)

cr0x@server:~$ ss -lntp | grep ':8080'
LISTEN 0      4096       127.0.0.1:8080      0.0.0.0:*    users:(("java",pid=7321,fd=123))

Ce que cela signifie : Le port est ouvert et détenu par le processus Java. Si rien n’écoute, l’erreur upstream est expliquée.

Décision : Si rien n’écoute, vérifiez les logs de crash et la config. Si ça écoute, suspectez que l’app est bloquée ou liée à une dépendance ; probez‑la localement.

Task 14: Local health check bypassing the load balancer

cr0x@server:~$ curl -sS -o /dev/null -w "code=%{http_code} total=%{time_total}\n" http://127.0.0.1:8080/health
code=500 total=0.083

Ce que cela signifie : L’app répond rapidement mais renvoie 500 : erreur interne, mauvaise config, dépendance en échec ou démarrage incomplet.

Décision : Cherchez des traces de stack et des échecs de dépendances ; ne perdez pas de temps sur le débogage réseau.

Task 15: Check database connectivity quickly (PostgreSQL example)

cr0x@server:~$ psql -h db-01 -U app -d appdb -c "select now(), count(*) from pg_stat_activity;"
              now              | count
-------------------------------+-------
2026-02-02 14:02:44.221+00     |   198

Ce que cela signifie : La BDD est joignable et a 198 connexions actives. Si c’est proche de votre limite de connexions, vous flirtez avec une panne auto‑infligée.

Décision : Si les connexions sont élevées, activez le pooling, réduisez la concurrence ou tuez les requêtes folles. Si inaccessible, traitez la BDD comme incident principal.

Task 16: Identify lock contention (PostgreSQL example)

cr0x@server:~$ psql -h db-01 -U app -d appdb -c "select wait_event_type, wait_event, count(*) from pg_stat_activity where state='active' group by 1,2 order by 3 desc;"
 wait_event_type |     wait_event      | count
-----------------+---------------------+-------
 Lock            | transactionid        |    62
 Client          | ClientRead           |    21

Ce que cela signifie : Beaucoup de sessions attendent des verrous, indiquant que la base est bloquée, pas simplement «lente». Votre app fait la queue derrière la contention.

Décision : Trouvez la requête bloqueuse et remédiez (terminer la session, rollback du déploiement, ajuster index/transactions). Scaler les serveurs applicatifs augmentera la pression et empirera la situation.

Task 17: Check kernel-level network errors

cr0x@server:~$ netstat -s | egrep -i 'listen|overflow|dropped' | head
    124 times the listen queue of a socket overflowed
    124 SYNs to LISTEN sockets dropped

Ce que cela signifie : Votre serveur perd des connexions entrantes. Cela ressemble à des «timeouts aléatoires» côté client.

Décision : Augmentez les réglages de backlog, ajustez les files d’accept, réduisez le travail par requête ou scalez horizontalement. Confirmez aussi que l’app peut réellement tenir la charge.

Task 18: Storage integrity check (ZFS example)

cr0x@server:~$ sudo zpool status
  pool: tank
 state: DEGRADED
status: One or more devices has experienced an unrecoverable error.
  scan: scrub repaired 0B in 01:12:33 with 0 errors on Mon Feb  2 01:10:02 2026
config:

        NAME        STATE     READ WRITE CKSUM
        tank        DEGRADED     0     0     0
          mirror-0  DEGRADED     0     0     0
            sda     ONLINE       0     0     0
            sdb     FAULTED      9    12     0  too many errors

errors: No known data errors

Ce que cela signifie : Votre pool est dégradé. Les performances peuvent chuter, un resilvering peut être en attente, et une autre défaillance pourrait devenir une perte de données.

Décision : Remplacez le disque défaillant, planifiez l’impact du resilvering et envisagez de limiter les jobs lourds. Aussi : ajoutez la supervision de l’état du pool dès hier.

Task 19: Check if you’re swapping (a silent latency killer)

cr0x@server:~$ free -m
               total        used        free      shared  buff/cache   available
Mem:           64000       61200         300         210        2500         900
Swap:          16000       15850         150

Ce que cela signifie : Le swap est presque plein ; le système est probablement en thrashing. La latence devient aléatoire, l’iowait CPU augmente et tout semble hanté.

Décision : Réduisez la pression mémoire immédiatement (redémarrez les workers qui fuient, augmentez la RAM, ajustez les caches). À long terme : imposez des limites, dimensionnez correctement et alertez sur l’usage du swap.

Blague n°2 : Si votre seule alerte est un e‑mail client, félicitations — vous avez construit un système de supervision distribué alimenté par l’anxiété humaine.

Trois mini‑histoires du monde corporate (anonymisées et plausibles)

Mini‑histoire 1 : L’incident causé par une fausse hypothèse

Une entreprise SaaS de taille moyenne faisait tourner un seul service «API» derrière un load balancer. Ils avaient des métriques hôtes : CPU, mémoire et disque.
Ils n’avaient pas de checks synthétiques ni d’alertes sur le taux d’erreur. La rotation d’astreinte était de deux développeurs et une personne infra qui gérait aussi les backups.

Un lundi matin, un client signale que les uploads échouent. L’équipe suppose un «problème de stockage», parce qu’uploads et stockage sont liés dans l’esprit de tout le monde.
Ils SSHent sur les hôtes applicatifs, vérifient l’usage disque (ok), regardent la page de statut du store d’objets (vert), et redémarrent les workers d’upload juste pour «dégager».
Ça a empiré, parce que les redémarrages ont drop les uploads en vol et déclenché des retries côté client.

Le vrai problème était une dérive d’horloge sur un nœud après une migration d’hyperviseur. Les handshakes TLS échouaient de façon intermittente parce que le nœud se croyait dans le futur.
Le load balancer continuait d’envoyer une fraction du trafic d’upload vers ce nœud. CPU, mémoire, disque semblaient normaux. Le service était «up».
Depuis le navigateur du client, c’était de la roulette.

La correction fut simple : restaurer NTP, drainer le nœud, puis le réintroduire. La leçon n’était pas «NTP importe» (ça compte).
La leçon était que le modèle mental de l’équipe était trop étroit : ils supposaient que toute défaillance se manifeste par une saturation de ressources.
Sans métriques de succès au niveau requête et sans checks externes, ils étaient aveugles aux pannes de correction.

Après coup, ils ont ajouté deux choses : un test synthétique d’upload chaque minute et une alerte sur les erreurs de handshake TLS en bordure.
Pas une centaine de dashboards. Deux signaux qui cartographient la douleur utilisateur.

Mini‑histoire 2 : L’optimisation qui s’est retournée

Une autre entreprise, sous pression de coûts, a décidé «d’optimiser» la journalisation. Ils sont passés de logs applicatifs envoyés hors machine à des logs locaux avec un batch shipper.
L’argument était séduisant : moins d’appels réseau, coûts d’ingestion plus faibles et «on peut envoyer en bloc».

Pendant un pic de trafic, le batch shipper n’a pas suivi. Les logs se sont accumulés localement. Le disque s’est rempli lentement, puis soudainement.
Quand le disque a atteint 100 %, la base a commencé à échouer les checkpoints et l’app a commencé à lancer des erreurs qu’elle ne pouvait plus écrire dans ses propres logs.
L’équipe n’a pas vu les erreurs parce qu’elles étaient piégées derrière le problème disque qui les causait.

Les clients ont signalé des timeouts. L’équipe a scalé la couche API, ce qui a augmenté le trafic d’écriture et le volume de logs, remplissant les disques plus vite.
Boucle de rétroaction positive classique : «scaler pour résoudre» est devenu «scaler pour accélérer».

Le postmortem a été franc : le buffering local sans quotas stricts est un déni de service que vous planifiez vous‑même.
L’optimisation correcte aurait inclus des réservations disque strictes, un plafonnement du débit de logs et un comportement de backpressure (dropper d’abord les logs debug, pas la base).
Ils ont finalement implémenté des caps par service sur le volume de logs et gardé un flux minimal d’erreurs envoyé en temps réel.

Mini‑histoire 3 : La pratique ennuyeuse mais correcte qui a sauvé la situation

Une équipe plateforme interne d’entreprise gérait un service adjacent aux paiements. Ils n’étaient pas glamour. Ils étaient les gens qui disaient «non» souvent.
Leur supervision était aussi ennuyeuse : checks synthétiques, alertes sur taux d’erreur, percentiles de latence et timeouts de dépendances. Ils avaient des runbooks.

Un déploiement du jeudi a introduit une fuite de connexion subtile vers une BDD en aval. Les connexions s’accumulaient lentement.
Comme ils avaient un dashboard pour la pool de connexions et une alerte sur la «saturation de pool», l’astreinte a été pagée avant que les clients ne remarquent quoi que ce soit.
L’alerte ne disait pas «quelque chose est bizarre». Elle disait «la pool BDD est à 90% et augmente».

La réponse fut tout aussi ennuyeuse : rollback immédiat, vérification que la pool s’est vidée, puis redéploiement avec le correctif derrière un feature flag.
Ils ont aussi limité le débit de l’endpoint le plus touché pour réduire la pression pendant la validation.

Les clients n’ont jamais déposé de tickets. L’entreprise n’a jamais convoqué de war room. L’équipe n’a pas reçu d’éloges, ce qui est le plus grand compliment en ingénierie de fiabilité.
Leur pratique n’était pas du génie ; elle était disciplinée : alertes qui correspondent à l’impact utilisateur, et autorité pour rollback sans comité.

Erreurs courantes : symptôme → cause racine → correctif

Quand vous n’avez pas de supervision, vous tombez dans des pièges prévisibles. En voici les plus fréquents, cadrés pour que vous puissiez agir pendant un incident.

1) «Le service tourne» mais les utilisateurs ont des erreurs

  • Symptôme : systemctl status dit actif ; les clients voient des 500/503.
  • Cause racine : Défaillance d’une dépendance, exhaustion d’un thread pool, ou l’app renvoie des erreurs alors que le process reste vivant.
  • Correctif : Ajouter des health checks qui valident les dépendances ; alerter sur le taux d’erreur et la latence, pas sur l’existence du process.

2) Timeouts aléatoires qui «disparaissent» après un redémarrage

  • Symptôme : Timeouts sous charge ; le redémarrage aide brièvement.
  • Cause racine : Fuite de ressources (connexions, descripteurs, mémoire), ou limites noyau (backlog d’écoute, conntrack).
  • Correctif : Alerter sur l’usage des FD, le nombre de connexions et les drops réseau noyau ; imposer des limites et ajouter du pooling.

3) Un seul client se plaint

  • Symptôme : «C’est en panne chez nous, pas chez les autres.»
  • Cause racine : Problème de données spécifique au tenant, routage géographique, déséquilibre de shard, ou différences de politique d’auth.
  • Correctif : Ajouter des métriques de succès par tenant/par région et du tracing ; implémenter des checks canary depuis plusieurs régions.

4) Tout est lent, le CPU est bas

  • Symptôme : CPU bas, latence élevée.
  • Cause racine : iowait disque, contention de verrous, ou latence d’une dépendance amont.
  • Correctif : Suivre iowait et disk await ; alerter sur la latence des dépendances ; ajouter la surveillance des verrous en base.

5) Le scaling aggrave la situation

  • Symptôme : Ajouter des instances, le taux d’erreurs augmente.
  • Cause racine : Thundering herd/tempêtes de retries, ou saturation d’une dépendance partagée (BDD, cache, filesystem).
  • Correctif : Implémenter backoff exponentiel avec jitter, circuit breakers et limites de débit par endpoint ; alerter sur la saturation des dépendances.

6) La panne «commence» quand les clients la remarquent

  • Symptôme : Aucun timestamp interne ; heure de début d’incident vague.
  • Cause racine : Pas de monitoring synthétique externe, pas de timeline d’événements (marqueurs de deploy), mauvaise rétention des logs.
  • Correctif : Ajouter des synthétiques et des annotations de déploiement ; conserver logs/métriques suffisamment longtemps pour voir les tendances (pas seulement les 15 dernières minutes).

7) Les health checks passent tandis que le vrai trafic échoue

  • Symptôme : /health renvoie 200 ; /checkout échoue.
  • Cause racine : Health checks superficiels qui n’exercent pas les vraies dépendances ou chemins.
  • Correctif : Ajouter des checks en couches : liveness (process), readiness (dépendances) et transactions synthétiques (parcours utilisateur réel).

Checklists / plan étape par étape

Étape par étape : passer de «rien» à «les clients ne sont plus votre supervision»

  1. Définissez ce que «en panne» signifie pour vos utilisateurs. Choisissez un ou deux parcours utilisateur (connexion, checkout, requête API) et mesurez‑les.
  2. Ajoutez des checks synthétiques externes. Exécutez‑les depuis au moins deux réseaux/régions. Alertez sur échec et régression de latence.
  3. Adoptez les golden signals par service. Trafic, erreurs, latence, saturation. Si vous ne pouvez pas les nommer, vous ne pouvez pas les alerter.
  4. Instrumentez des request IDs. Chaque requête reçoit un ID de corrélation à la bordure et les logs l’incluent de bout en bout.
  5. Créez une page d’astreinte minimale. Une page, pas dix : statut courant, dernier déploiement, taux d’erreur, p95 latence, santé des dépendances.
  6. Alertez sur les symptômes, pas sur les causes. «Spike de 500s» est un symptôme. «CPU 70%» est trivia.
  7. Établissez la responsabilité. Chaque alerte a une équipe et un runbook. Si personne n’en est responsable, elle pagera tout le monde et n’aidera personne.
  8. Fixez la rétention et les quotas. Les logs remplissent les disques. Les métriques remplissent les budgets. Décidez la rétention nécessaire pour déboguer tendances et régressions.
  9. Synchronisation temporelle et horloges. NTP/chrony partout. Si le temps est faux, l’observabilité est une fiction.
  10. Entraînez le rollback. Faites du rollback une routine, pas un rituel sacré nécessitant des approbations pendant que la production brûle.
  11. Rédigez des postmortems qui changent les systèmes. Si l’action est «faire plus attention», vous avez écrit un journal, pas un artefact d’ingénierie.
  12. Révisez les alertes chaque mois. Tuez les alertes bruyantes. Ajoutez les manquantes. La supervision est un système vivant, pas un projet ponctuel.

Checklist incident : quand un client signale une panne

  • Confirmer depuis l’extérieur (code statut, latence, texte d’erreur).
  • Enregistrer l’heure, la région client, l’endpoint, l’ID de requête si possible.
  • Vérifier le dernier déploiement/changement de config.
  • Vérifier la bordure : DNS, TLS, santé du load balancer, expiration des certificats.
  • Vérifier l’app : logs d’erreur, connectivité des dépendances, saturation (CPU/mem/disque/réseau).
  • Atténuer : rollback, shedding, désactiver les fonctionnalités non critiques.
  • Préserver les preuves : logs, snapshots système, sortie top, info de verrous BDD.
  • Communiquer : un propriétaire, un canal, une mise à jour client claire.

Checklist Build‑it‑right : monitoring minimal viable (MVM)

  • Synthétique externe : un endpoint «réel», un endpoint «health».
  • Métriques service : taux de requêtes, taux d’erreur, p95 latence, saturation (profondeur de queue, thread pool, connexions BDD).
  • Métriques dépendances : latence BDD, taux de hit cache, timeouts amonts.
  • Métriques hôte : usage disque, iowait, pression mémoire, drops réseau.
  • Événements : marqueurs de déploiement, changements de config, événements de scaling.
  • Hygiène d’alerte : pager seulement pour les symptômes impactant l’utilisateur ; tout le reste fait l’objet d’un ticket ou d’un dashboard.

FAQ

1) Pas de supervision, ça va si l’app est petite ?

Les petites apps échouent en petits morceaux, puis grandissent. La supervision ne dépend pas de la taille ; elle dépend du temps de diagnostic.
Même une VM unique bénéficie d’alertes disque plein et d’un check synthétique basique.

2) Quel est le premier signal de supervision à ajouter ?

Un check synthétique externe du parcours utilisateur le plus important, avec latence et code statut enregistrés.
S’il échoue, vous paginez. S’il ralentit, vous enquêtez avant que ça ne casse.

3) Pourquoi les graphiques CPU et mémoire semblent inutiles pendant les pannes ?

Parce que beaucoup de pannes concernent des dépendances et la saturation ailleurs : latence disque, contention de verrous ou drops réseau.
Les graphiques hôtes sont nécessaires mais pas suffisants ; ce sont les constantes vitales, pas le diagnostic.

4) Comment éviter la fatigue d’alerte ?

Pager seulement sur des symptômes impactant l’utilisateur et des seuils actionnables. Tout le reste devient un ticket ou un dashboard.
Si une alerte ne peut pas mener à une décision, c’est du bruit déguisé en responsabilité.

5) Ai‑je besoin du tracing distribué pour être «vrai» SRE ?

Non. Vous avez besoin de clarté. Le tracing aide en microservices, mais vous pouvez aller loin avec des request IDs, des alertes de taux d’erreur et des métriques de latence de dépendances.
Ajoutez le tracing quand la corrélation devient votre goulot.

6) Quel est l’ensemble minimal de dashboards qui aide vraiment ?

Un tableau de bord par service critique : trafic, erreurs, p95/p99 latence, saturation et principales dépendances.
Plus un tableau «bord» : santé DNS/TLS/LB et checks synthétiques.

7) Comment gérer les pannes partielles quand seuls certains utilisateurs se plaignent ?

Segmentez vos signaux : par région, par tenant, par endpoint et par version de build.
Les pannes partielles arrivent quand votre supervision agrège la vérité.

8) Les health checks doivent‑ils toucher la base de données ?

Les readiness checks doivent valider les dépendances critiques, base incluse, mais soigneusement : ils doivent être légers et limités en taux.
Utilisez une simple requête ou un check de connexion, pas une transaction complète.

9) Si on ne peut pas installer d’agents pour des raisons de sécurité ?

Vous pouvez faire beaucoup avec du monitoring black‑box (synthétiques), des endpoints de métriques applicatives et un envoi centralisé de logs via des collecteurs approuvés.
Les politiques de sécurité doivent faire évoluer l’architecture, pas éliminer la visibilité.

10) Comment convaincre la direction de financer la supervision ?

Ne vendez pas «l’observabilité». Vendez la réduction du coût des pannes et la résolution plus rapide des incidents.
Montrez une timeline d’un incident récent et mettez en évidence combien de temps a été perdu à deviner. Rendez le gaspillage visible.

Conclusion : prochaines étapes à faire cette semaine

Si vous avez appris que vous étiez en panne via un client, traitez‑le comme un défaut de production, pas comme une mauvaise journée.
La correction n’est pas un joli tableau de bord. C’est construire un système qui vous dit la vérité rapidement et de façon cohérente.

Faites ces étapes suivantes dans l’ordre :

  1. Ajoutez un check synthétique externe qui mesure code statut et latence pour un endpoint réel.
  2. Créez une alerte de paging sur le taux d’erreur (pas CPU), et orientez‑la vers un planning d’astreinte réel.
  3. Instrumentez des request IDs et assurez‑vous que les logs les incluent de bout en bout.
  4. Alertez sur disque plein, OOM kills et timeouts de dépendances — parce que ce sont les «tueurs silencieux» que les clients trouvent en premier.
  5. Rédigez un runbook court pour les trois modes de panne que vous avez réellement vus (disque plein, saturation BDD, crash loops).

Ensuite faites la partie ennuyeuse : entretenez‑le. La supervision qui n’est pas entretenue devient décorative.
Et la supervision décorative n’est qu’une façon coûteuse d’apprendre que vous êtes en panne via un client — encore.

← Précédent
Pentium II / III : l’âge d’or où la fréquence avait encore du sens
Suivant →
Auditd sur Debian 13 sans ruiner les disques : réglages pratiques pour un audit raisonné

Laisser un commentaire