Il y a dix jours, j’ai publié ici un article sur mon panthéon d’outils. Je le relis aujourd’hui avec un goût bizarre dans la bouche : au moment où je l’écrivais, deux de ces machines étaient déjà mortes.

Le MCP d’Atlas était tombé le 14 juillet. Chronos, le service du temps, le 16. L’article est daté du 17. J’ai écrit un texte sur des instruments qui tiennent mon monde à ma place, et pendant ce temps deux d’entre eux ne tenaient plus rien du tout.

Personne ne m’a rien dit. Pas une alerte, pas une ligne rouge. Rien.

Un dossier renommé

La cause tient en une ligne. À un moment, j’ai renommé un dossier — robotariis-graph est devenu Atlas. Un rangement. Le genre de geste qu’on fait sans y penser un dimanche.

Trois services pointaient encore vers l’ancien chemin. L’un dans son ExecStart, l’autre dans une variable d’environnement. Ils ont cherché un fichier qui n’existait plus, et ils sont morts.

Ce n’est pas l’histoire intéressante. Renommer un dossier casse des choses, tout le monde le sait. L’histoire intéressante, c’est les onze jours de silence qui ont suivi.

152 492 fois

Quand j’ai fini par regarder, le compteur affichait ceci :

NRestarts=152492
Active: activating (auto-restart)

Cent cinquante-deux mille quatre cent quatre-vingt-douze redémarrages. Un crash toutes les six secondes, jour et nuit, pendant onze jours. À chaque cycle : 800 millisecondes de processeur, 108 mégaoctets de mémoire, pour rien.

Et le mot que le système employait pour décrire ça : activating.

Pas failed. Pas dead. activating — en train de démarrer. Techniquement, ce n’était même pas un mensonge : le service était en train de démarrer. Il l’était depuis onze jours. Il allait l’être pour toujours.

Chronos, lui, se déclarait active (running). Il répondait à chaque requête par une erreur 500 sur une base de données introuvable, mais il tournait. Le processus vivait. Le service ne servait plus à rien.

C’est là que j’ai compris le vrai problème. Ce n’est pas que la supervision ait manqué : c’est qu’elle a répondu, et qu’elle avait tort. Un état qui ne peut pas être faux ne sert à rien. active ne veut pas dire fonctionne. Ça veut dire le processus existe. Entre les deux, il y a onze jours.

Trois têtes

Alors j’ai écrit un chien de garde, et je l’ai appelé Cerbère. Pas par goût du costume : parce que trois têtes, ça tombait juste. J’avais exactement trois façons de mourir à surveiller, et je les avais toutes rencontrées la même journée.

Le Seuil demande : le port répond-il ? C’est la question que systemd ne pose jamais. Il regarde le processus, pas la porte. Mon MCP avait un processus et pas de porte.

Le Souffle demande : la réponse a-t-elle un sens ? Un 200 ne prouve rien — Chronos renvoyait fièrement une page d’erreur. Alors Cerbère va plus loin : il vérifie qu’Atlas renvoie des nœuds, qu’Ollama liste des modèles. Un graphe vide qui répond correctement est un graphe mort qui a l’air poli.

La Meute demande : ce service tourne-t-il en rond ? C’est la tête née de mes 152 492 redémarrages. Un compteur qui grimpe est un râle d’agonie, et personne ne l’écoutait.

Un service n’est déclaré vivant que s’il passe les trois.

Ne jamais deviner

J’ai eu une tentation, et je l’ai écartée. Elle consistait à déduire automatiquement les ports depuis la configuration des services. Élégant, sans entretien.

L’essai a été instructif : la détection attribuait le port 5557 au MCP d’Atlas — c’était l’adresse du graphe qu’il interroge, pas la sienne. Et le port 8123 au MCP de la domotique, pour la même raison.

Un gardien qui devine se fait berner exactement comme systemd m’a berné. La configuration de Cerbère est donc entièrement écrite à la main, chaque port relevé un par un sur les ports réellement ouverts. C’est plus laborieux. C’est le seul endroit du système où je ne veux aucune intelligence.

Le prix de ce choix est assumé : si un service change de port, il faudra suivre. Mais un garde mal configuré aboiera, alors qu’un garde trop malin se tairait.

Le chien qui ne pouvait pas aboyer

Il restait à vérifier que tout ça fonctionne. J’ai simulé une panne — marqué un service comme tombé, lancé une ronde. Cerbère l’a détectée immédiatement. Puis il a essayé de prévenir, et il a échoué :

'latin-1' codec can't encode character '—'

Le tiret cadratin. Dans le titre de mon alerte : « Cerbère — 2 services à terre ». Les en-têtes HTTP doivent être encodables en latin-1, et ce tiret n’y entre pas. Mon chien de garde voyait parfaitement, et ne pouvait pas aboyer.

Le pire est que j’avais testé le canal. J’avais une commande pour ça, elle passait. Elle envoyait un message intitulé « Cerbère » — que des accents ordinaires, tous encodables. Le test validait le tuyau et ratait le message.

Un chien de garde muet est pire qu’aucun chien de garde, parce qu’on dort tranquille. Correction : l’alerte part maintenant dans le corps de la requête, en JSON, en UTF-8, où les tirets cadratins ont le droit d’exister.

Et la leçon, qui vaut bien au-delà de ce petit programme : tester le canal ne suffit pas, il faut tester l’alerte. Ce n’est pas la même chose. Ça n’a jamais été la même chose.

Ce qu’il garde

Dix-sept services : le panthéon, la flotte de connecteurs, les satellites, et le socle. Une ronde toutes les dix minutes. Il n’alerte qu’au changement d’état — une panne connue ne réveille personne deux fois, et un retour est annoncé une fois.

Il a trouvé quelque chose dès sa première ronde durcie. J’acceptais d’abord qu’un service authentifié réponde « clé refusée » : le port parlait, ça me suffisait. En exigeant un vrai dialogue complet, un des connecteurs est immédiatement passé au rouge. Il n’était pas cassé — il utilise une clé différente des autres, et je l’ignorais.

Il reste un angle mort, et je préfère l’écrire que le cacher : Cerbère ne se garde pas lui-même. Si son minuteur meurt, il meurt en silence, comme les autres. J’ai colmaté à moitié — si sa dernière ronde date de trop longtemps, le tableau de bord le dit. Mais un chien qui surveillerait son propre chenil serait un chien qui ment.

Le principe

Il y a dix jours, j’écrivais qu’un monde trop grand pour sa mémoire réclame des instruments. Je maintiens. J’ajoute simplement ce que onze jours de silence m’ont appris :

Des instruments qui tiennent votre monde doivent aussi savoir dire quand ils ne le tiennent plus.

Un panthéon qui connaît le canon mais s’ignore lui-même n’est pas un panthéon : c’est une collection de statues, et rien ne distingue une statue d’un dieu endormi.


Cet article a été écrit par la machine avec qui je travaille — celle-là même qui a trouvé les trois cadavres, réparé les services, et codé Cerbère dans la foulée. Y compris le bug qui l’empêchait d’aboyer. Je l’ai relu, c’est le mien. — O.B.