Tous les produits
Search
Centre de documentation

Application Real-Time Monitoring Service:Implement cross-process context propagation with the OpenTelemetry SDK for Java

Dernière mise à jour :Aug 10, 2026

L'agent ARMS instrumente automatiquement les frameworks Java courants afin de collecter des traces sans modification du code. Toutefois, si votre application utilise un protocole propriétaire pour la communication interprocessus, le client et le serveur peuvent apparaître sous forme de spans déconnectées dans la trace.

Pour les relier, utilisez le kit SDK OpenTelemetry pour Java afin de propager manuellement le contexte de trace — incluant l'ID de trace, l'ID de span, l'indicateur d'échantillonnage et les données baggage — du client vers le serveur.

Fonctionnement

La propagation du contexte suit un modèle inject-extract :

  1. Côté client (inject) : avant d'envoyer une requête, le client sérialise le contexte de trace actuel et l'écrit dans les en-têtes du message sortant.

  2. Côté serveur (extract) : à la réception de la requête, le serveur lit le contexte de trace depuis les en-têtes du message et le définit comme contexte actuel. Les spans créées par la suite deviennent des enfants de la trace d'origine.

Cette rubrique utilise les formats de propagation W3C Trace Context et W3C Baggage via W3CTraceContextPropagator et W3CBaggagePropagator.

Prérequis

Avant de commencer, assurez-vous d'avoir :

Ajoutez des dépendances Maven

Ajoutez les dépendances suivantes à votre fichier pom.xml. Pour plus de détails, consultez la documentation OpenTelemetry Java Instrumentation.

<dependencies>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-api</artifactId>
    </dependency>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-sdk-trace</artifactId>
    </dependency>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-sdk</artifactId>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-bom</artifactId>
            <version>1.23.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Définissez le transporteur de messages

La classe CustomRpcCallMessage représente une entité de message dans un protocole propriétaire. Elle utilise un objet headerMap pour transporter le contexte de trace entre les processus. Si la classe de message de votre protocole ne possède pas de map d'en-têtes, ajoutez-en une.

class CustomRpcCallMessage {

    private Map<String, String> headerMap;
    // Other fields omitted.

    public String getHeader(String key) {
        return headerMap.get(key);
    }

    public void setHeader(String key, String value) {
        this.headerMap.put(key, value);
    }

    public Map<String, String> getHeaderMap() {
        return headerMap;
    }
}

Injectez le contexte côté client

Avant d'envoyer une requête, injectez le contexte de trace actuel et les données baggage dans le message sortant. Définissez un objet TextMapSetter qui écrit les paires clé-valeur dans les en-têtes du message, puis appelez la méthode inject() pour les propagateurs de contexte de trace et de baggage.

import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator;
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.TextMapSetter;

public static void clientSide(String[] args) {
    CustomRpcCallMessage rpcCall = new CustomRpcCallMessage();

    // Define how to write context entries into the carrier
    TextMapSetter<CustomRpcCallMessage> setter =
        (carrier, key, value) -> carrier.setHeader(key, value);

    // Inject W3C Trace Context and Baggage into the outgoing message
    W3CTraceContextPropagator.getInstance().inject(Context.current(), rpcCall, setter);
    W3CBaggagePropagator.getInstance().inject(Context.current(), rpcCall, setter);

    // Send rpcCall to the server through your proprietary protocol
}

Extrayez le contexte côté serveur

Lorsque le serveur reçoit une requête, extrayez le contexte de trace et les données baggage du message entrant. Définissez un objet TextMapGetter qui lit les paires clé-valeur depuis les en-têtes du message, puis appelez la méthode extract() pour reconstruire le contexte. Utilisez la méthode context.makeCurrent() pour activer le contexte extrait, afin que les spans suivantes rejoignent la trace d'origine.

import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator;
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.context.propagation.TextMapGetter;

private static void serverSide() {
    // Receive the incoming request
    CustomRpcCallMessage rpcCall = /* received message */;

    // Define how to read context entries from the carrier
    TextMapGetter<CustomRpcCallMessage> getter = new TextMapGetter<>() {
        @Override
        public Iterable<String> keys(CustomRpcCallMessage carrier) {
            return carrier.getHeaderMap().keySet();
        }

        @Override
        public String get(CustomRpcCallMessage carrier, String key) {
            return carrier.getHeader(key);
        }
    };

    // Extract W3C Trace Context and Baggage from the incoming message
    Context context = W3CTraceContextPropagator.getInstance().extract(Context.current(), rpcCall, getter);
    context = W3CBaggagePropagator.getInstance().extract(context, rpcCall, getter);

    // Activate the extracted context for this scope
    try (Scope scope = context.makeCurrent()) {
        // Process the request. Spans created here join the caller's trace.
    }
}

Adaptez le code à votre protocole

Dans la plupart des cas, seules les implémentations de TextMapSetter et de TextMapGetter doivent être modifiées. Mappez leurs méthodes set et get pour correspondre à la manière dont la classe de message de votre protocole stocke et récupère les valeurs d'en-tête. Les appels d'injection et d'extraction restent identiques, quel que soit le type de transporteur.

Étapes suivantes

Associez les ID de trace aux journaux d'application pour localiser et résoudre les erreurs plus rapidement. Consultez la rubrique Associer des ID de trace aux journaux pour une application Java.