Quando threads ou processos se comunicam por meio de intermediários, como filas de mensagens ou bancos de dados, o agente do ARMS não consegue propagar automaticamente o contexto de rastreamento. O consumidor inicia um novo rastreamento desconectado em vez de continuar o rastreamento do produtor. Use o OpenTelemetry SDK para Java para capturar e restaurar manualmente o contexto de rastreamento nesses limites assíncronos, mantendo todos os spans correlacionados em um único rastreamento.
Quando a propagação manual é necessária
O agente do ARMS propaga automaticamente o contexto de rastreamento para os seguintes padrões assíncronos, sem necessidade de alterações no código:
Pools de threads criados com JDK, Spring ou Netty
Programação reativa com Reactor ou RxJava
Anotações
@Asyncdo SpringFrameworks reativos, como Spring Webflux e Spring Gateway
Para obter a lista completa de frameworks compatíveis, consulte Java components and frameworks supported by ARMS.
A propagação manual é necessária quando threads ou processos se comunicam por meio de intermediários que o agente do ARMS não instrumenta. Dois exemplos comuns:
|
Cenário |
Descrição |
|
Fila produtor-consumidor |
A thread T1 coloca uma mensagem em uma fila e a thread T2 a retira para processamento. Sem propagação manual, a T2 inicia um novo rastreamento em vez de continuar o rastreamento da T1. |
|
Transferência mediada por banco de dados |
O processo P1 grava um lote de registros em um banco de dados e o processo P2 os lê e processa. Sem propagação manual, o rastreamento do processamento fica desconectado do rastreamento de gravação. |
Pré-requisitos
Antes de começar, certifique-se de ter:
Application Monitoring do ARMS integrado. Para mais informações, consulte Application Monitoring overview.
Agente do ARMS V4.x ou posterior instalado. Para verificar ou atualizar a sua versão, consulte Atualize o agente do ARMS.
Adicione dependências
Adicione as seguintes dependências do Maven ao seu projeto. Para mais informações, consulte a official OpenTelemetry documentation.
<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>
Propague o contexto entre limites assíncronos
Este padrão tem duas partes:
Captura: no lado do remetente, chame
Context.current()para capturar o contexto de rastreamento ativo e armazená-lo junto com os dados transmitidos.Restauração: no lado do receptor, chame
context.makeCurrent()para restaurar o contexto capturado antes do processamento.
Exemplo: Produtor-consumidor com uma fila bloqueante
O código a seguir propaga o contexto de rastreamento por meio de uma LinkedBlockingQueue. O produtor captura o contexto atual ao enfileirar uma mensagem, e o consumidor o restaura antes do processamento.
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.
}
Pontos principais
|
Conceito |
Descrição |
|
|
Captura o contexto de rastreamento ativo no momento da chamada. Armazene-o junto com os dados transmitidos entre as threads. |
|
|
Restaura o contexto capturado na thread consumidora. Spans, logs e métricas criados dentro do bloco |
|
|
Implementa |
Próximos passos
Associe os IDs de rastreamento aos logs da aplicação para agilizar a análise de erros. Consulte Associate trace IDs with logs for a Java application.