RousselTMLEARNING

Observabilité

Tracing distribué : la propagation du contexte (W3C Trace Context et baggage)

Comprendre et mettre en œuvre la propagation de contexte OpenTelemetry : en-tête traceparent, tracestate, baggage, propagateurs, HTTP, messagerie asynchrone, injection/extraction manuelle et dépannage des traces coupées.

1. Le problème à résoudre #

Relier des spans créés dans des processus différents.

Pourquoi propager ? #

Chaque service crée ses propres spans, mais pour obtenir une seule trace il faut transmettre l'identité de la trace (TraceID) et du span parent à chaque appel. Cette transmission s'appelle la propagation de contexte : l'appelant injecte le contexte dans le message, l'appelé l'extrait.

Propagation du contexte entre trois services
Sans propagation, chaque service produit une trace isolée.

2. Le standard W3C Trace Context #

traceparent, tracestate et baggage.

Les en-têtes #

traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
#            |  |                                |                |
#            |  trace-id (16 octets, hex)         span-id parent   flags (01 = échantillonnée)
#            version

tracestate: vendor1=valeur,vendor2=autre          # informations propres à des fournisseurs
baggage: user.tier=gold,region=eu                 # paires clé/valeur métier propagées à tous les services
En-têteContenuAttention
traceparentTraceID, SpanID parent, flagsIndispensable pour relier les spans
tracestateDonnées spécifiques à un fournisseurPeu utilisé en pratique
baggageContexte métier (client, région...)Visible de tous les services et tiers : jamais de secret

3. Configurer les propagateurs #

Variables d'environnement.

OTEL_PROPAGATORS #

export OTEL_PROPAGATORS=tracecontext,baggage        # valeur par défaut : W3C
export OTEL_PROPAGATORS=tracecontext,baggage,b3multi  # compatibilité avec des services Zipkin/B3
export OTEL_PROPAGATORS=jaeger,tracecontext             # migration depuis Jaeger

Tous les services d'une même chaîne doivent partager au moins un format commun : c'est la première chose à vérifier quand une trace est coupée en deux.

# Tester à la main : forcer un TraceID connu et le retrouver dans Tempo
curl -H 'traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01' http://localhost:8080/commande
curl -s http://localhost:3200/api/traces/4bf92f3577b34da6a3ce929d0e0e4736 | jq '.batches | length'

4. Propager manuellement #

Messagerie, jobs et clients HTTP non instrumentés.

Injecter et extraire (Python) #

from opentelemetry import trace, propagate, context

tracer = trace.get_tracer("orders")

# Producteur : injecter le contexte dans les en-têtes du message
def publier(message):
    with tracer.start_as_current_span("publier_commande", kind=trace.SpanKind.PRODUCER):
        headers = {}
        propagate.inject(headers)                    # ajoute traceparent / baggage
        kafka_producer.send("commandes", value=message, headers=[(k, v.encode()) for k, v in headers.items()])

# Consommateur : extraire et continuer la trace
def consommer(record):
    carrier = {k: v.decode() for k, v in record.headers}
    ctx = propagate.extract(carrier)
    with tracer.start_as_current_span("traiter_commande", context=ctx, kind=trace.SpanKind.CONSUMER) as span:
        span.set_attribute("messaging.destination.name", "commandes")
        traiter(record.value)

Dépanner une trace coupée #

SymptômeCause probableAction
Deux traces au lieu d'unePropagateurs différents entre servicesAligner OTEL_PROPAGATORS
En-tête absent côté appeléProxy / gateway qui supprime les en-têtesAutoriser traceparent et baggage dans la configuration du proxy
Trace perdue après une file de messagesContexte non injecté dans les en-têtes du messageInjecter/extraire manuellement ou activer l'instrumentation du client
Spans orphelins en tâche de fondContexte perdu entre threads/coroutinesUtiliser context.attach() / run_in_executor instrumenté
Une partie seulement des traces est complèteÉchantillonnage head différent entre servicesUtiliser parentbased_traceidratio partout
# nginx : laisser passer / générer le contexte
proxy_set_header traceparent $http_traceparent;
proxy_set_header tracestate  $http_tracestate;
proxy_set_header baggage     $http_baggage;
Erreur Courante : Ne placez jamais de données sensibles dans le baggage : il est propagé à tous les services en aval, y compris les services tiers.

Articles liés

Les concepts fondamentaux d'OpenTelemetry : signaux, ressources, contexte et maturité

Le vocabulaire indispensable d'OpenTelemetry : les quatre signaux, API et SDK, ressource et instrumentation s…

Collector OpenTelemetry : connecteurs, extensions et observabilité du Collector

Aller plus loin avec le Collector : connecteurs (spanmetrics, servicegraph, count, routing, failover), extens…

Les conventions sémantiques OpenTelemetry (semconv) : nommer la télémétrie

Comprendre et appliquer les conventions sémantiques OpenTelemetry : attributs de ressource, HTTP, bases de do…

Pour aller plus loin

Soutenir

♥ SOUTENIR

Soutenez RousselTM Learning

Les formations, articles, TP et attestations restent gratuits et sans publicité intrusive. Une contribution libre, du montant de votre choix, finance l’hébergement, les environnements de TP et l’écriture de nouveaux contenus.

Contribuer avec PayPal Montant libre · carte bancaire ou compte PayPalEn savoir plus
QR code PayPal
Ou scannez ce QR code avec votre téléphone

Merci, chaque contribution compte !