Tous les produits
Search
Centre de documentation

Application Real-Time Monitoring Service:Pass trace context across asynchronous boundaries in Java

Dernière mise à jour :Sep 21, 2026

Lorsque des threads ou des processus communiquent via des intermédiaires tels que des files d'attente de messages ou des bases de données, l'agent ARMS ne peut pas propager automatiquement le contexte de trace. Le consommateur démarre alors une nouvelle trace déconnectée au lieu de poursuivre celle du producteur. Utilisez le SDK OpenTelemetry pour Java afin de capturer et de restaurer manuellement le contexte de trace à travers ces limites asynchrones, garantissant ainsi la corrélation de toutes les spans au sein d'une seule trace.

Quand une propagation manuelle est nécessaire

L'agent ARMS propage automatiquement le contexte de trace pour les modèles asynchrones suivants, sans modification du code :

  • Pools de threads créés avec JDK, Spring ou Netty

  • Programmation réactive avec Reactor ou RxJava

  • Annotations Spring @Async

  • Frameworks réactifs tels que Spring Webflux et Spring Gateway

Pour la liste complète des frameworks pris en charge, consultez la rubrique Composants et frameworks Java pris en charge par ARMS.

Une propagation manuelle s'impose lorsque des threads ou des processus communiquent via des intermédiaires non instrumentés par l'agent ARMS. Voici deux exemples courants :

Scénario Description
File d'attente producteur-consommateur Le thread T1 place un message dans une file d'attente et le thread T2 le récupère pour traitement. Sans propagation manuelle, T2 démarre une nouvelle trace au lieu de poursuivre celle de T1.
Transfert médiatisé par une base de données Le processus P1 écrit un lot d'enregistrements dans une base de données et le processus P2 les lit et les traite. Sans propagation manuelle, la trace de traitement est déconnectée de la trace d'écriture.

Prérequis

Avant de commencer, assurez-vous d'avoir :

Ajouter des dépendances

Ajoutez les dépendances Maven suivantes à votre projet. Pour plus d'informations, consultez la documentation officielle d'OpenTelemetry.

<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>

Propager le contexte au-delà des limites asynchrones

Ce modèle repose sur deux étapes :

  1. Capture : Côté émetteur, appelez Context.current() pour capturer le contexte de trace actif et stockez-le conjointement avec les données transmises.

  2. Restauration : Côté récepteur, appelez context.makeCurrent() pour restaurer le contexte capturé avant le traitement.

Exemple : Producteur-consommateur avec une file d'attente bloquante

Le code suivant transmet le contexte de trace via une LinkedBlockingQueue. Le producteur capture le contexte actuel lors de l'ajout d'un message à la file, et le consommateur le restaure avant le traitement.

import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import java.util.concurrent.LinkedBlockingQueue;

// Wrap both the message and its trace context
class Event {
    private final Context context;
    private final String msg;

    public Event(Context context, String msg) {
        this.context = context;
        this.msg = msg;
    }

    public Context getContext() {
        return context;
    }

    public String getMsg() {
        return msg;
    }
}

// Shared queue between producer and consumer threads
private final LinkedBlockingQueue<Event> queue = new LinkedBlockingQueue<>();

// Producer: capture the current trace context
public void produce(String msg) {
    queue.add(new Event(Context.current(), msg));
}

// Consumer: restore the trace context before processing
public void consume() throws InterruptedException {
    Event event = queue.take();
    // makeCurrent() sets the captured context as the active context.
    // The try-with-resources block ensures the context is cleaned up after processing.
    try (Scope scope = event.getContext().makeCurrent()) {
        processEvent(event);
    }
}

public void processEvent(Event event) {
    // Any spans created here automatically become children
    // of the producer's trace.
}

Points clés

Concept Description
Context.current() Capture le contexte de trace actif au moment de l'appel. Stockez-le conjointement avec les données échangées entre les threads.
context.makeCurrent() Restaure le contexte capturé sur le thread consommateur. Les spans, journaux et métriques créés dans le bloc try (Scope scope = ...) sont corrélés avec la trace d'origine.
Scope Implémente AutoCloseable. Utilisez toujours un bloc try-with-resources pour garantir le nettoyage correct du contexte.

Étapes suivantes

Associez les ID de trace aux journaux d'application pour simplifier l'analyse des erreurs. Consultez la rubrique Associer les ID de trace aux journaux d'une application Java.