Un appareil Linux posé sur un bureau donne une fausse impression de confort. On peut ouvrir un terminal, lancer journalctl, relire le démarrage, ajouter quelques messages et recommencer. Le même appareil installé dans une armoire électrique, une caméra, une borne ou un instrument de mesure devient beaucoup moins bavard. Sa mémoire est comptée. Son stockage peut être lent ou absent. Son réseau peut disparaître au moment précis où le bug apparaît.

Le billet de Memfault part de cette différence, mais sa vraie question est plus exigeante qu’« où écrire les logs ? » : que doit-il rester de l’incident lorsque personne ne peut toucher la machine pendant plusieurs semaines ?1 Un système de logs embarqué n’est pas un flux de texte. C’est une politique de mémoire, de preuve et de perte acceptable.

Le journal commence par un trou

Sur un serveur, on peut augmenter le disque ou envoyer les événements vers une autre machine. Sur un appareil, chaque octet réservé aux logs concurrence le système, les données utilisateur, les mises à jour et parfois la durée de vie de la flash. Memfault décrit donc le buffer tournant comme une contrainte structurante : lorsque le tampon est plein, les événements les plus anciens sont écrasés.1

Ce mécanisme est brutal, mais il est lisible. Il oblige à choisir une fenêtre : dix minutes de détail, deux heures de résumé, ou seulement le dernier démarrage. La bonne réponse dépend du temps entre l’apparition d’un défaut et la collecte. Un routeur qui redémarre toutes les trente secondes n’a pas le même besoin qu’un appareil industriel qui tombe une fois par mois.

Le premier calcul à faire n’est donc pas « combien de logs par seconde ? », mais « quand saurai-je que quelque chose s’est mal passé ? ». Si l’équipe découvre la panne lorsqu’un client appelle, le dispositif doit retenir assez de contexte avant l’appel. Si un heartbeat permet de déclencher une collecte immédiatement, un buffer plus court peut suffire. L’observabilité est déjà une architecture de diagnostic avant d’être une syntaxe d’API.

La RAM est souvent le meilleur endroit pour le détail récent : elle évite les écritures permanentes et peut fonctionner sur des appareils dépourvus de stockage non volatil. Mais un crash ou une coupure l’efface. La flash conserve l’histoire, au prix de l’usure, de la latence et d’une gestion plus délicate des coupures de courant. La remontée réseau offre un autre type de mémoire, extérieure à l’appareil, mais elle échoue précisément dans les pannes de connectivité.7

Il n’existe donc pas de « log complet ». Il existe une composition de pertes : perdre les informations les plus anciennes, perdre les messages de faible priorité, perdre la fin d’un événement lors d’une coupure, ou perdre l’incident entier parce qu’on a voulu tout expédier en continu.

Trois couches que l’on confond souvent

Dans un Linux embarqué, plusieurs journaux coexistent. Le noyau écrit dans un ring buffer lu depuis /dev/kmsg ou avec dmesg; la documentation Linux présente printk comme le mécanisme standard de messages du noyau.4 Les services utilisateurs peuvent écrire sur stderr, dans syslog, ou dans journald. Un agent de télémétrie peut enfin lire l’un de ces flux et l’envoyer vers un backend.

Ces couches ne sont pas interchangeables. Un message dans le ring buffer du noyau n’est pas une garantie de persistance. Un service qui écrit dans journald n’est pas automatiquement visible après redémarrage si la configuration reste volatile. Un agent qui lit le journal doit mémoriser sa position pour ne pas retraiter les mêmes événements; la documentation Linux de Memfault décrit cette reprise par curseur pour memfaultd.2

La confusion coûte cher lors d’une panne. Une équipe croit avoir « activé les logs » parce que journalctl montre quelque chose sur son banc de test. En production, Storage=auto peut rester en mémoire si le répertoire persistant n’existe pas. La documentation systemd distingue explicitement les modes volatile, persistent, auto et none, ainsi que les conditions de bascule vers le stockage persistant.5

Le test utile n’est donc pas de démarrer un service et de voir une ligne apparaître. Il faut couper le courant, redémarrer, remplir le disque presque complètement, perdre le réseau, lancer une rafale d’erreurs et vérifier ce que le dispositif permet encore de récupérer. Le chemin de preuve doit être testé comme le chemin nominal.

Journald n’est pas un disque magique

Journald apporte une structure intéressante pour les systèmes qui utilisent systemd : champs indexés, sélection par unité, boot, priorité ou identifiant, formats d’export et possibilité de compresser les objets plus importants.5 Le format de fichier est binaire, principalement append-only, indexé par champs et conçu pour rester consultable; systemd documente aussi la compression en ligne et le scellement cryptographique optionnel.6

Ces propriétés sont utiles lorsque le problème est de retrouver un événement dans un système complexe. Elles ne suppriment pas la contrainte matérielle. Il faut toujours décider où le journal vit, quelle taille il peut prendre, quels messages sont conservés et comment on le transfère. La structure ajoute même un choix: quelques champs bien nommés peuvent rendre une recherche possible, tandis qu’un texte très long peut consommer beaucoup d’espace sans devenir plus explicatif.

La limitation de débit est un autre point où la lisibilité du système rencontre sa brutalité. Journald applique par défaut une limite par service et peut supprimer les messages au-delà du burst configuré, en signalant qu’une quantité a été perdue.5 Sur un serveur, perdre une partie d’une rafale est parfois raisonnable. Sur un appareil où la rafale est elle-même le symptôme — une liaison qui boucle, un capteur qui renvoie une valeur impossible — supprimer le début ou la fin peut rendre l’incident illisible.

La bonne question n’est pas « faut-il désactiver la rate limit ? ». C’est « quel événement mérite de survivre à la rate limit ? ». Un compteur de répétition, un changement d’état, la première occurrence et la dernière occurrence sont souvent plus utiles qu’un millier de lignes identiques. L’application peut également ralentir sa propre émission, agréger les répétitions ou changer de niveau de détail quand elle détecte qu’elle est dans une boucle.

Écrire pour une machine et pour quelqu’un

Les logs destinés à un humain ont tendance à devenir des phrases. Les logs destinés à un programme deviennent des objets structurés. L’opposition est paresseuse. Il faut souvent les deux : un identifiant d’événement stable, une priorité, un timestamp fiable, un sous-système, un code d’erreur et quelques valeurs qui expliquent le contexte, plus une phrase courte qui aide l’ingénieur à comprendre le mécanisme.

Les champs sont une forme d’interface publique. Changer wifi_error en network_problem entre deux versions rend les comparaisons plus difficiles, même si le logiciel fonctionne. Supprimer un code parce qu’il semblait redondant casse les scripts d’analyse. L’équipe doit donc versionner le vocabulaire, documenter les valeurs et éviter d’envoyer des données qu’elle ne saura pas interpréter six mois plus tard.

Le choix du format dépend de la couche. JSON est lisible, mais ses clés répétées et ses chaînes peuvent être coûteuses sur une petite machine. Un format binaire compact peut économiser de l’espace, mais exige un décodeur qui survive aux versions. Les systèmes de logging spécialisés proposent parfois des logs compacts où le firmware conserve des identifiants et où le texte est enrichi côté serveur. Ce découplage est puissant, mais il déplace la dépendance vers la conservation du dictionnaire de symboles et des versions de build.

La source du message fait aussi partie du contexte. Un « timeout » ne dit rien sans savoir quelle opération, quel périphérique, quel firmware, quelle durée et quel état d’alimentation étaient concernés. À l’inverse, un log qui capture systématiquement SSID, identifiants, contenu utilisateur ou coordonnées transforme un outil de réparation en export de données personnelles. L’observabilité ne suspend pas la confidentialité.

Le réseau n’est pas une sortie, c’est une hypothèse

Memfault décrit les deux situations classiques : récupérer les logs sur place, avec un câble ou un accès local, et les récupérer à distance, ce qui suppose un transport, un stockage et des règles de confidentialité.1 Dans un produit réel, il faut prévoir les deux. Le mode local sauve les appareils isolés; le mode distant évite de demander une intervention à chaque client.

La collecte distante devrait avoir un budget clair. Envoyer tout le journal en continu augmente la consommation et la facture. Attendre un crash signifie parfois perdre l’instant qui l’a précédé. Un compromis consiste à conserver un buffer local, à déclencher une collecte sur un événement et à ne transmettre qu’une fenêtre autour de celui-ci. La détection peut venir d’un crash, d’un watchdog, d’un heartbeat absent ou d’un changement de métrique.

Les métriques et les logs se complètent. Memfault recommande de ne pas traiter les logs comme le seul outil de suivi de connectivité : les métriques peuvent montrer une tendance de flotte, alors que les logs expliquent un cas individuel.3 Cent appareils qui perdent chacun une fois le Wi-Fi donnent peu de matière à lire; une courbe de fréquence par version peut révéler une régression avant qu’un log particulier soit regardé.

Cela change la manière de concevoir le logiciel. Un événement rare mérite un contexte riche. Un état fréquent mérite une métrique. Une séquence répétitive mérite un compteur et éventuellement un échantillon. Les mêmes mots « loguer l’erreur » cachent ces trois décisions très différentes.

Le crash n’est pas la fin du récit

Un appareil qui plante produit souvent moins d’informations au moment où l’on en aurait le plus besoin. Le processus peut mourir avant de vider son buffer. Le kernel peut redémarrer. Une coupure peut laisser un fichier partiellement écrit. Les logs doivent donc être pensés avec les coredumps, les traces de boot, les raisons de reset et les compteurs de watchdog, même si chacun relève d’un outil différent.

Le ring buffer du kernel est un bon exemple de mémoire temporaire utile : les messages restent disponibles dans une structure circulaire et sont exposés à l’espace utilisateur.4 La taille elle-même est configurable; le paramètre log_buf_len définit la taille du buffer du kernel.8 Mais agrandir ce buffer ne transforme pas un journal en archive. Cela retarde seulement l’écrasement, et occupe de la RAM.

La réponse robuste est une chronologie à plusieurs résolutions : raison du dernier reset, quelques secondes de logs détaillés, compteurs agrégés sur les dernières heures, version logicielle et état de la mise à jour. On ne demande pas à chaque couche de tout retenir. On leur demande de se recouvrir juste assez pour rendre l’incident reconstruisible.

Une petite méthode de conception

Avant de choisir la bibliothèque, écrire cinq scénarios : panne réseau, crash applicatif, corruption de stockage, boucle de logs et appareil totalement inaccessible. Pour chacun, préciser ce que l’on veut savoir, quel est le dernier moment où l’on peut collecter, quelle mémoire est disponible et quelle information est acceptable à transmettre.

Ensuite, définir les événements qui changent réellement une décision. « La température est 42 °C » toutes les secondes n’est pas forcément utile; « le capteur a dépassé le seuil pendant 18 secondes puis le système a redémarré » l’est davantage. Le log doit capturer les transitions, les raisons et les versions, pas transformer le produit en imprimante.

Enfin, tester la perte. Remplir la flash. Couper pendant une écriture. Générer dix mille erreurs. Effacer le réseau. Monter un firmware ancien avec un décodeur nouveau. Vérifier qu’un opérateur sans accès physique peut distinguer une panne du périphérique d’une panne du transport. Un système de logs n’est pas fiable parce qu’il écrit beaucoup; il est fiable parce que ses pertes sont prévues.

Le choix du collecteur est déjà un choix de produit

Entre le service qui produit un événement et le backend qui le reçoit, il y a souvent un agent : journald, syslogd, rsyslog, Fluent Bit ou un composant maison. On les présente comme des tuyaux. Ce sont plutôt des régulateurs : ils décident quand lire, quand attendre, quand écrire, quoi compresser, quoi abandonner et quelle panne ils doivent eux-mêmes survivre.

Fluent Bit documente cette réalité sous les noms de mémoire, chunks, fichiers et backpressure.9 En mode mémoire, une limite peut suspendre une entrée lorsque le consommateur est trop lent. Cela protège le processus contre l’explosion de RAM, mais une rotation de fichier pendant la pause peut perdre des lignes. Le buffer filesystem apporte une reprise et une capacité de stockage; il ne transforme pas le disque en ressource infinie. Il faut un chemin, une limite par destination et une politique lorsque cette limite est atteinte.

Le détail le plus utile est peut-être celui que les logiciels de collecte cachent d’habitude : « fiable » a plusieurs sens. Un chunk écrit sur disque mais pas synchronisé n’a pas la même garantie qu’un chunk durable après une coupure. Une file qui reprend après un redémarrage ordonné ne garantit rien contre une panne d’alimentation. Une limite qui conserve les événements les plus récents peut être parfaite pour le diagnostic et mauvaise pour l’audit.

Rsyslog rend ces différences explicites. Ses files peuvent être en mémoire, sur disque ou disk-assisted. Dans ce dernier mode, la mémoire reste le chemin rapide et le disque intervient lorsque la file dépasse un seuil; la partie restée en mémoire peut être sauvée lors d’un arrêt propre, mais pas après un kill, un OOM ou une coupure.10 Une file purement disque est plus robuste mais plus lente et plus coûteuse en écritures. Le choix n’est pas une préférence de configuration : il décrit quel type de perte le produit accepte.

Sur un appareil contraint, il faut souvent une hiérarchie. Garder les événements critiques en RAM et les vider vers la flash seulement lors d’un changement d’état. Conserver un résumé persistant plutôt que chaque ligne. Réserver une petite zone de récupération au démarrage. Faire remonter une fenêtre autour d’un crash. Chaque niveau possède sa propre promesse, et l’ensemble doit rester compréhensible lorsqu’un développeur revient sur le produit deux ans plus tard.

La flash n’est pas une feuille de papier

Écrire un log donne l’impression d’ajouter de l’information sans modifier le reste. Sur de la NAND ou de la flash embarquée, chaque écriture participe à une histoire d’usure, de traduction d’adresses, d’effacement par blocs et de garbage collection. Le détail dépend du composant, du contrôleur, du système de fichiers et du workload; il serait faux de donner un nombre universel de cycles.

Il est en revanche raisonnable de traiter la fréquence d’écriture comme une contrainte de conception. Les travaux de mesure comme Flashmon ont précisément pour but d’observer les requêtes d’I/O NAND d’un système Linux embarqué, parce que le volume logique écrit par un service ne suffit pas à décrire le travail réel du support.11 Une petite ligne répétée chaque seconde peut entraîner des écritures et des effacements bien plus larges selon la manière dont le système de fichiers et le contrôleur regroupent les données.

Cela ne signifie pas « ne jamais écrire ». Une flash utilisée correctement peut conserver des journaux utiles pendant la durée de vie du produit. Cela signifie qu’il faut mesurer au lieu de supposer. Quelle quantité de données est produite par heure ? Quel est le comportement en incident, quand la fréquence peut être dix fois plus forte ? Où sont les compteurs de santé du support ? Quelle partie du journal vaut une écriture persistante et quelle partie peut disparaître au reboot ?

La compression ajoute un compromis. Elle réduit le volume écrit et transmis, mais consomme du CPU et peut retarder la disponibilité du message. Journald compresse en ligne les objets qui dépassent un seuil configuré.5 Fluent Bit peut conserver des chunks en mémoire et sur fichier, avec des modes de synchronisation qui favorisent soit la performance soit la durabilité.9 Le choix doit tenir compte de l’énergie et de la température autant que de la place gagnée.

Un produit alimenté par batterie peut préférer cent événements structurés à une compression lourde. Un appareil branché mais difficile d’accès peut préférer réduire les écritures en regroupant. Une passerelle avec un disque eMMC n’a pas la même marge qu’une carte de développement équipée d’un SSD. Le mot « embedded » ne donne pas la réponse; le profil de support et de panne la donnent.

Rate limit : perdre intelligemment

Une boucle de logs est une forme de panne secondaire. Un pilote qui répète une erreur à haute fréquence consomme CPU, remplit le journal, réveille le modem, accélère l’usure et peut empêcher le message important de passer. La limitation de débit est donc une protection du produit, pas seulement une réduction de bruit.

Journald applique un burst par service et supprime les messages au-delà du seuil pendant l’intervalle, en produisant un message sur la perte.5 Rsyslog peut ralentir une file, appliquer des limites aux entrées et choisir entre bloquer le producteur fiable ou jeter les messages lorsque l’espace manque.10 Fluent Bit peut mettre en pause certaines entrées lorsque la mémoire dépasse sa limite, avec le risque associé pour les sources qui continuent à écrire.9

Ces comportements posent une question de hiérarchie. Si une caméra envoie les mêmes erreurs de connexion mille fois, on veut peut-être garder la première erreur, le compteur, la dernière erreur et l’état du réseau. Si un watchdog redémarre la machine, la raison du reset est plus importante que les derniers messages de debug. Si un utilisateur signale un défaut intermittent, une fenêtre détaillée autour du changement d’état vaut mieux qu’une archive de toute la journée.

Le logiciel qui émet les logs peut aider. Il peut agréger les répétitions, ajouter une durée, marquer une transition, passer temporairement en mode diagnostic ou prendre un échantillon. Cette intelligence locale évite de demander au collecteur de deviner le sens de dix mille lignes identiques. Elle rend aussi le contrat plus clair : le producteur sait ce qui est important, le transport sait ce qu’il peut perdre.

Crash context : le dernier instant est le plus cher

Le diagnostic d’un appareil ne commence pas au moment où l’équipe ouvre le ticket. Il commence avant le crash. Une architecture utile conserve la raison du dernier reset, la version logicielle, le temps depuis le boot, l’état de l’alimentation, les compteurs de watchdog et quelques secondes d’événements détaillés.

Le ring buffer du kernel est bon pour une mémoire volatile de ce type. printk écrit dans le buffer circulaire exporté vers l’espace utilisateur; dmesg lit ce que le redémarrage n’a pas encore effacé.4 Le paramètre log_buf_len peut agrandir cette zone.8, mais il consomme de la RAM et ne garantit aucune persistance. Le but n’est pas de garder tout le boot; c’est de garder les transitions qui permettent de comprendre pourquoi le boot suivant a eu lieu.

Les logs ne suffisent pas toujours. Un coredump donne une photographie du processus, un compteur de reset donne une cause grossière, une métrique de heartbeat donne une absence, et un événement de version donne le contexte du déploiement. L’article Memfault sur les logs insiste sur les décisions de collecte et de déclenchement; sa documentation Linux décrit comment memfaultd reprend la lecture d’un journal depuis son curseur après redémarrage.12

La collecte sur incident doit éviter deux extrêmes. Si elle attend que le réseau revienne, elle peut rater le contexte qui a disparu lors du reboot. Si elle envoie tout avant de connaître la cause, elle gaspille énergie et bande passante. Un buffer local, un déclencheur, un échantillon enrichi et un upload différé forment souvent un compromis plus honnête.

Le terrain change la politique

Un appareil de laboratoire peut exposer des logs par USB. Un appareil chez un client doit prévoir un export local qui ne demande pas de révéler un secret réseau, et un canal distant soumis à consentement, authentification et rétention. Un dispositif médical ou installé dans un lieu privé ajoute des obligations de minimisation qui ne se résument pas à masquer un identifiant dans le texte.

Les logs peuvent contenir des noms de réseaux, des adresses, des identifiants de compte, des chemins de fichiers, des extraits de contenu ou des horaires d’usage. Même lorsqu’un champ semble anodin, sa répétition et sa corrélation peuvent révéler une routine. Le choix « loguer pour déboguer » est donc aussi un choix de données.

Il faut décider quelles données sont nécessaires à quel niveau. Le produit peut garder localement un identifiant technique et envoyer au backend un identifiant pseudonymisé. Il peut conserver une trace détaillée après une action explicite de l’utilisateur. Il peut désactiver le contenu et garder les codes d’état. Il peut fournir un bouton « exporter le diagnostic » qui montre ce qui part réellement.

La confidentialité et la maintenance ne sont pas opposées. Une donnée non nécessaire est une mauvaise donnée de diagnostic parce qu’elle augmente le risque sans améliorer la décision. Une architecture qui explique ses événements, limite les champs et sépare les niveaux de détail est plus facile à protéger et plus facile à analyser.

Après la panne : traduire la trace en réparation

Un log n’a de valeur que s’il réduit une décision. Le mainteneur doit pouvoir répondre : faut-il remplacer le capteur, réinstaller le firmware, changer la configuration réseau, demander une action à l’utilisateur ou rappeler l’appareil ? Une suite de messages sans vocabulaire stable ne fait que déplacer le bruit dans un dashboard.

Les champs structurés sont utiles, mais ils doivent rester évolutifs. Il faut une version de schéma, un identifiant de build, une horloge dont la dérive est connue et des valeurs qui ne changent pas de sens sans migration. Les événements doivent dire si une mesure est absente, invalide, estimée ou simplement non demandée. Une valeur zéro n’est pas toujours un zéro.

La corrélation est aussi un choix de maintenance. Un identifiant de boot relie les événements d’un démarrage; un identifiant d’incident relie l’erreur, le reset et le retour en ligne; un identifiant d’appareil permet de comparer une version sans exposer nécessairement l’utilisateur. Ces relations rendent le support plus rapide, mais elles rendent aussi les données plus sensibles. La bonne pratique n’est pas d’ajouter tous les identifiants : c’est de savoir quel lien est nécessaire à quelle question.

La documentation doit enfin survivre à l’équipe qui a écrit le code. Un événement nommé recover_failed peut vouloir dire une dizaine de choses. Il faut décrire la condition, le nombre de tentatives, le résultat attendu et l’action possible. Les logs sont une interface de réparation; leur public inclut souvent quelqu’un qui n’a jamais vu le code source.

Le plan de test doit provoquer la perte

Tester un système de logs consiste trop souvent à vérifier qu’une ligne apparaît. Le vrai test est de provoquer les conditions où la ligne voudrait disparaître. Remplir le disque. Couper l’alimentation pendant une écriture. Éteindre le serveur de collecte. Générer une rafale. Faire tourner l’appareil plusieurs jours sur un réseau instable. Remonter une version ancienne avec un parseur nouveau. Faire redémarrer pendant que l’agent vide son buffer.

Chaque test doit produire une réponse : quel est le plus ancien événement conservé ? Quelle perte est signalée ? Le système principal continue-t-il à fonctionner lorsque la file est pleine ? Une source fiable est-elle ralentie ou une source UDP simplement abandonnée ? Le fichier de journal est-il récupérable après une coupure ? Le prochain boot conserve-t-il la raison du reset ?

Les documentations de rsyslog et Fluent Bit montrent pourquoi les mots « disk-assisted », « filesystem buffer » ou « persistent » doivent être lus avec leur scénario d’arrêt.910 Une configuration sûre sur un serveur protégé par une alimentation stable peut être inadaptée dans une caméra qui redémarre brutalement et dont la flash est petite.

Le test doit également mesurer le coût : écritures par heure, CPU consacré au formatage et à la compression, mémoire occupée par les chunks, temps d’attente du producteur, énergie du modem et espace utilisé après une semaine d’incident simulé. Ce sont des métriques produit, pas des détails réservés à l’équipe système.

Une méthode de conception pour makers

Avant de choisir journald ou un agent, écrire cinq scénarios : panne réseau, crash applicatif, stockage corrompu, boucle de logs et appareil inaccessible. Pour chacun, écrire la question de maintenance, le dernier moment de collecte, la mémoire disponible, le niveau de confidentialité acceptable et le type de perte autorisé.

Puis séparer les événements par fonction. Les transitions critiques et raisons de reset doivent être compactes et persistantes. Les détails de débogage peuvent rester dans un buffer RAM. Les états fréquents doivent souvent devenir des métriques ou des compteurs. Les données nécessaires à un ticket doivent pouvoir être exportées sans donner accès à tout le journal.

Définir ensuite une politique de pression : ralentir, agréger, échantillonner, mettre en pause, écraser le plus ancien ou abandonner le nouveau. Il n’y a pas de solution universelle. Il y a une décision que l’on peut expliquer. Un produit qui écrase les événements les plus anciens doit l’assumer; un produit qui bloque un service lorsque le disque est plein doit vérifier que ce blocage ne crée pas une panne plus grave.

Enfin, écrire la procédure de récupération comme une partie de l’interface. Où trouver le diagnostic ? Qui peut le lire ? Comment distinguer un problème réseau d’une panne du système de collecte ? Comment installer un correctif qui ajoute les champs manquants ? Que se passe-t-il si l’équipe disparaît ? Un log qui ne peut être interprété que par son auteur n’est pas une stratégie de maintenance, c’est une note personnelle.

Les logs ne sont pas des déchets d’usine

Le mérite du dossier Memfault est de ramener l’observabilité à cette matérialité, mais il faut élargir la conclusion au-delà d’un fournisseur. Un appareil Linux embarqué n’a pas un réservoir abstrait de logs. Il a de la RAM, une flash, un réseau, une batterie, un utilisateur, un budget de support et une durée de vie attendue.

Journald montre la richesse de champs et de politiques de stockage. printk montre la valeur et la fragilité d’un ring buffer noyau. Rsyslog montre que les files et la durabilité sont des choix différents. Fluent Bit montre que la backpressure peut protéger la mémoire au prix d’une perte d’entrée, ou utiliser le filesystem au prix d’écritures et de limites à surveiller. Les outils ne donnent pas la politique à la place du fabricant.

La question décisive est celle que l’on pose à la machine après son départ du laboratoire : qu’auras-tu encore la capacité de prouver ? La réponse ne doit pas être « tout ». Elle doit dire quels événements, sous quelle forme, pendant combien de temps, avec quelle confidentialité et avec quelle dépense matérielle.

Un bon système de logs ne collecte pas le monde. Il conserve assez de contexte pour qu’une autre personne puisse choisir une réparation. C’est une pièce de produit, au même titre qu’un connecteur, un mode de récupération ou un firmware OTA. Les octets qu’il écrit façonnent la durée de vie du support; les octets qu’il n’écrit pas façonnent la qualité du diagnostic. Concevoir cette frontière avant la panne, c’est déjà concevoir l’objet après sa livraison.