Un client conteste sa facture, et vos logs ne disent rien
Un client écrit au support : le volume de tokens facturé ne correspond pas à celui de son propre tableau de bord. Vous ouvrez les logs. Des millions de lignes venues de l'API Laravel, du worker de facturation Node.js et de la file d'attente, aucune n'a d'identifiant commun. Et la requête qui compte a sans doute été écartée par l'échantillonnage à 1 % activé pour réduire la facture de tracing. Rien n'est cassé : vous ne voyez simplement rien. C'est le scénario décrit dans l'article Production Observability on a Budget: OpenTelemetry Traces, Structured Logs & Tail Sampling, et voici comment s'en sortir sans budget démesuré.
Un identifiant de trace unique, de bout en bout
Le point de départ est la corrélation. Chaque requête reçoit un identifiant de trace à son entrée dans le système, et cet identifiant doit voyager partout : de l'API vers la file d'attente, puis jusqu'au worker.
OpenTelemetry standardise ce transport grâce au contexte W3C Trace Context (l'en-tête traceparent). Côté HTTP, les instrumentations le propagent en général automatiquement. Côté file d'attente, c'est là que le fil se perd : il faut injecter le contexte dans les métadonnées du message à la publication, puis l'extraire à la consommation pour que le span du worker se rattache à la trace de la requête d'origine.
Points de vigilance :
- utiliser la même convention de propagation dans tous les services, PHP comme Node.js
- vérifier que les jobs asynchrones créent bien un span enfant (ou lié) de la trace d'origine
- nommer les services de façon cohérente (
service.name) pour filtrer facilement
Des logs structurés qui portent le trace ID
Des traces seules ne suffisent pas : les logs restent l'endroit où l'on cherche en premier. Passez-les au format JSON et ajoutez systématiquement le trace_id et le span_id du contexte courant.
{"level":"info","message":"usage recorded","trace_id":"4bf92f3577b34da6a3ce929d0e0e4736","tenant":"acme","tokens":1520}
Résultat : depuis une ligne de log suspecte, vous retrouvez la trace complète. Depuis une trace, vous retrouvez tous les logs associés, quel que soit le service émetteur. Dans Laravel, un processeur Monolog qui enrichit chaque enregistrement avec le contexte de trace suffit. Côté Node.js, la plupart des bibliothèques de logs permettent le même enrichissement.
Évitez toutefois d'y mettre des données personnelles ou des secrets : un log corrélé est plus facile à exploiter, y compris par erreur.
Le tail sampling : décider après avoir vu la trace
Le piège du budget, c'est l'échantillonnage en tête (head sampling). La décision de garder ou non une trace est prise au tout début, avant de savoir si la requête sera lente ou en erreur. Avec 1 % de conservation, 99 % des incidents rares disparaissent avec le reste.
Le tail sampling inverse la logique : un collecteur OpenTelemetry reçoit les spans, attend que la trace soit complète, puis décide. On peut par exemple garder :
- toutes les traces contenant une erreur
- toutes les traces dont la durée dépasse un seuil
- un petit pourcentage aléatoire du trafic normal, pour avoir une référence
Le processeur tail_sampling du collecteur s'appuie sur des politiques combinables pour exprimer ces règles. Le compromis est réel : le collecteur doit tenir les spans en mémoire pendant la fenêtre d'attente, et toutes les spans d'une même trace doivent arriver sur la même instance du collecteur. Il faut donc dimensionner la mémoire et, dès qu'on a plusieurs collecteurs, router par identifiant de trace.
Mettre en place par étapes
Une approche réaliste, sans tout refaire d'un coup :
- instrumenter l'API et le worker avec OpenTelemetry, et vérifier la propagation à travers la file d'attente
- basculer les logs en JSON avec
trace_idetspan_id - déployer un collecteur et activer le tail sampling avec des politiques simples (erreurs, lenteur, échantillon aléatoire)
- ajuster les seuils après quelques semaines d'observation
Conclusion
L'observabilité utile ne consiste pas à tout conserver, mais à conserver ce qui permet de répondre à la prochaine question d'un client. Un identifiant partagé, des logs structurés et un échantillonnage décidé à la fin de la trace donnent cette capacité sans multiplier la facture. Pour aller plus loin, lisez l'article d'origine : Production Observability on a Budget: OpenTelemetry Traces, Structured Logs & Tail Sampling.
Et votre site, il vaut quoi ?
Vitesse, accessibilité, référencement technique. Le rapport est écrit pour un dirigeant, pas pour un développeur. Gratuit, sans inscription.