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

OpenTelemetry Collector : les Processors (transformer, filtrer et protéger la télémétrie)

Maîtriser les processors du Collector OpenTelemetry : batch, memory_limiter, attributes, resource, filter, tr…

OpenTelemetry Collector : les Exporters (envoyer la télémétrie vers les backends)

Configurer les exporters du Collector OpenTelemetry : OTLP gRPC/HTTP, Prometheus, prometheusremotewrite, Loki…

Architecture OpenTelemetry : Comprendre les 3 niveaux

Plongée au cœur de l'architecture OpenTelemetry. Apprenez comment les données circulent de l'application au b…

Pour aller plus loin