Une requête qui traverse dix microservices et devient lente quelque part ne dit rien de sa position dans les métriques agrégées (elles montrent une latence moyenne en hausse, jamais quelle requête précise ni où) ni dans les logs (chaque service écrit les siens, sans lien explicite avec les autres). Le tracing distribué existe pour répondre à une question que ni l’un ni l’autre ne peut poser : cette requête précise, où a-t-elle passé son temps ?
Un trace, des spans
Une trace représente le parcours complet d’une requête à travers un système. Elle se compose de spans, chacun représentant une unité de travail : un appel HTTP, une requête base de données, un traitement interne. Chaque span porte un début, une durée, et un lien vers son span parent, ce qui reconstitue la hiérarchie complète de la requête.
Trace: a3f9c2e1...
├── span: API Gateway (45ms)
│ └── span: payment-service (38ms)
│ ├── span: fraud-check (12ms)
│ └── span: db-query INSERT (20ms)
Cette structure répond directement à la question initiale : sur 45ms de latence totale, 20ms viennent d’une requête base de données précise, pas d’un ralentissement diffus impossible à localiser.
Le contexte doit voyager avec la requête
Le mécanisme qui rend tout ça possible est la propagation de contexte : chaque service qui reçoit une requête doit transmettre l’identifiant de trace au service suivant qu’il appelle, généralement via un header HTTP standardisé (traceparent, défini par le standard W3C Trace Context). Un service qui oublie de propager ce header casse la chaîne : les spans en aval démarrent une trace complètement nouvelle, sans lien visible avec l’amont, ce qui rend le problème invisible précisément là où il serait le plus utile de le voir.
traceparent: 00-a3f9c2e1b8d4f012-9c2e1b8d4f012a3f-01
│ └─ trace-id ─────┘└─ span-id ────┘ │
version flags
Ce qu’OpenTelemetry standardise
Avant OpenTelemetry, chaque backend de tracing (Jaeger, Zipkin, des solutions propriétaires) imposait son propre SDK d’instrumentation, ce qui verrouillait le code applicatif à un choix de fournisseur. OpenTelemetry sépare l’instrumentation (le SDK qui génère les spans dans le code) du backend qui les stocke et les affiche : un OTel Collector reçoit les traces au format standard OTLP et peut les router vers Jaeger, Tempo, ou un backend commercial, sans jamais toucher au code applicatif instrumenté.
# Exemple minimal : exporter les traces vers un Collector local
exporters:
otlp:
endpoint: "otel-collector:4317"
Le piège du sampling
Tracer chaque requête individuellement, avec le volume complet de spans que ça représente, devient rapidement coûteux en stockage et en traitement à grande échelle. Le sampling réduit ce volume en ne conservant qu’une fraction des traces, mais un sampling naïf (garder une requête sur cent, au hasard) a une conséquence contre-intuitive : les requêtes les plus intéressantes, celles qui échouent ou qui sont anormalement lentes, sont statistiquement les plus susceptibles d’être écartées, puisqu’elles sont rares par définition.
Le tail-based sampling corrige ce problème en décidant de garder ou non une trace après l’avoir vue complète, pas au hasard à son démarrage : une trace qui contient une erreur ou dépasse un seuil de latence est systématiquement conservée, tandis que le trafic normal reste échantillonné pour maîtriser le volume. Le compromis : ça demande de bufferiser les traces en cours avant de décider, ce qui coûte plus de ressources au niveau du Collector qu’un sampling à l’entrée.
Où ça se range
Le tracing complète les golden signals et les logs centralisés plutôt qu’il ne les remplace : les métriques disent qu’un problème existe, les logs disent ce qui s’est passé à un instant précis, les traces disent où le temps a été perdu dans un parcours complet. Mettre en place cette troisième couche fait partie de ce qui se traite dans une mission de fiabilité et observabilité.
À retenir
Une trace se compose de spans hiérarchiques qui reconstituent le parcours complet d’une requête ; le contexte doit être propagé explicitement d’un service à l’autre, sans quoi la chaîne se casse silencieusement. OpenTelemetry standardise l’instrumentation indépendamment du backend de stockage. Le sampling naïf écarte statistiquement les traces les plus utiles (erreurs, latence anormale) ; le tail-based sampling corrige ce biais au prix de ressources de traitement supplémentaires.