Nos logs en savent peut-être un peu trop

Les logs me rassurent. Une heure exacte, un identifiant d’opération et le message qui précède une erreur peuvent faire la différence entre comprendre et deviner pendant l’après-midi. Mon réflexe est donc d’en vouloir plus. Le problème, c’est qu’une suite d’événements techniques peut reconstruire la journée d’une personne.

Une bonne ligne de journal devrait être un événement structuré, pas une phrase différente à chaque endroit :

2004-10-14T08:05:31.482 | INFO | corr=7F31A2 | user=S-1-5-...
operation=OuvrirDossier | dossier=4182 | resultat=OK | duree_ms=84

L’heure situe l’événement. Le niveau distingue diagnostic, information, avertissement et erreur. L’identifiant de corrélation suit une même opération du serveur Web au service puis à SQL. L’identité peut être un SID ou un identifiant interne stable plutôt qu’un nom tapé librement. Des champs constants permettent de filtrer sans analyser cent formulations.

Le flux doit rester simple :

application → tampon local → fichier journal en ajout
                         ↘ compteur/alerte
fichiers tournants → archive protégée → purge selon rétention

Écrire sur le réseau à chaque ligne rend l’application dépendante du serveur de logs. Un tampon local réduit ce coût, mais peut perdre les dernières traces lors d’un crash. Pour une transaction financière, le journal d’audit durable n’a pas les mêmes exigences que le log de debug. Je sépare les deux au lieu de promettre qu’un seul fichier remplit tous les rôles.

Le volume se calcule. À 250 octets par ligne, 50 événements par seconde produisent environ 1,08 Go par jour (250 × 50 × 86 400). Avec trois copies et six mois de conservation, le « petit log texte » devient des centaines de gigaoctets. La rotation par taille ou par jour, la compression des archives et une purge vérifiée font partie du feature.

Ce qu’on n’écrit pas compte encore plus. Jamais de mot de passe, numéro complet de carte, chaîne de connexion avec secret ni contenu entier d’une requête utilisateur sans nécessité. Pour diagnostiquer un échec de connexion, le nom du serveur et un code d’erreur suffisent; le mot de passe n’ajoute rien. Une valeur sensible peut être remplacée par un identifiant ou masquée avant d’atteindre l’appel de log, parce qu’une purge après coup oubliera toujours des copies.

Le portrait humain apparaît par corrélation : connexion à 8 h 03, dossiers consultés, recherches, impressions, déconnexion. Il faut donc répondre avant la collecte :

  1. quel incident ou quelle obligation cet événement aide-t-il à traiter?
  2. quels champs sont réellement nécessaires?
  3. qui peut chercher dans ces traces?
  4. combien de temps chaque catégorie demeure utile?
  5. comment une consultation du journal est-elle elle-même auditée?
  6. comment détruit-on les archives et leurs copies?

Les permissions de lecture doivent être plus serrées que « tous les développeurs ». Un attaquant aime les logs parce qu’ils contiennent noms de serveurs, chemins et comportements. Pour un audit sensible, un serveur en écriture append-only et des empreintes ou contrôles d’intégrité rendent la modification plus visible. Les horloges des machines doivent être synchronisées; sinon l’appel enfant semble précéder la requête parent.

Le logging peut lui-même tomber. Un disque plein ne devrait pas faire échouer toute lecture de dossier, mais l’application ne devrait pas non plus ignorer la perte de son audit obligatoire. Je définis la politique : continuer avec une alerte pour le diagnostic ordinaire, ou refuser l’opération si la trace réglementaire ne peut pas être garantie. Une boucle d’erreur où « impossible d’écrire le log » essaie de s’écrire dans le même log doit être évitée.

Mon test pratique sera de prendre un incident, trouver toutes ses étapes avec un seul corr, puis demander ce que ces mêmes lignes révèlent sur la personne. Si un champ n’aide ni le support, ni la sécurité, ni une obligation définie, je ne le collecte pas. Un log utile est un instrument avec une job et une date d’expiration, pas un entrepôt « au cas où ».