El agente de Application Real-Time Monitoring Service (ARMS) instrumenta automáticamente los frameworks comunes de Java para recopilar datos de trazas sin modificar el código. Para capturar datos de trazas que reflejen su lógica de negocio específica, agregue instrumentación personalizada mediante el SDK de OpenTelemetry para Java. En este tema se describe cómo usar el SDK de OpenTelemetry para Java para agregar instrumentación personalizada, acceder al contexto de traza, definir Baggage personalizado y establecer atributos personalizados.
Para obtener información sobre los componentes y frameworks compatibles con el agente de ARMS, consulte Java components and frameworks supported by ARMS.
Requisitos previos
Conectó su aplicación a Application Real-Time Monitoring Service (ARMS). Para obtener más información, consulte Application Monitoring integration overview.
La versión de su agente de ARMS es 2.9.1.2 o posterior. Para actualizar el agente, consulte Upgrade the ARMS agent.
Agregar dependencias
Agregue las siguientes dependencias de Maven a su proyecto. Para obtener más información, consulte la documentación oficial de 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>
Compatibilidad del agente de ARMS con la instrumentación de OpenTelemetry
Conceptos clave
Esta sección describe únicamente los términos comunes. Para obtener más información sobre otros términos, consulte la especificación de OpenTelemetry.
span: una operación específica dentro de una solicitud, como un punto de entrada de llamada remota o una llamada a método interno.
SpanContext: el contexto de una traza, que incluye información como el ID de traza y el ID de span.
atributo: un campo adicional en un span que registra información clave.
Baggage: pares clave-valor que se propagan a lo largo de toda la traza.
Usar el SDK de OpenTelemetry para Java
Con el SDK de OpenTelemetry puede ejecutar las siguientes operaciones:
Agregar instrumentación para generar spans.
Agregar atributos a los spans.
Propagar Baggage en el contexto de traza.
Obtener el contexto de traza actual e imprimir información como el ID de traza y el ID de span.
A continuación se muestra un ejemplo de código que indica cómo usar el SDK de OpenTelemetry para ejecutar estas operaciones.
Importante: debe obtener la instancia de OpenTelemetry mediante la llamada a GlobalOpenTelemetry.get(). No use una instancia que haya compilado manualmente con el SDK de OpenTelemetry. De lo contrario, en el agente de ARMS v4.x, los spans generados por la instrumentación del SDK no serán visibles.
@RestController
@RequestMapping("/ot")
public class OpenTelemetryController {
private Tracer tracer;
private ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
@PostConstruct
public void init() {
OpenTelemetrySdk.builder()
.setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
.buildAndRegisterGlobal();
tracer = GlobalOpenTelemetry.get().getTracer("manual-sdk", "1.0.0");
ses.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
Span span = tracer.spanBuilder("schedule")
.setAttribute("schedule.time", System.currentTimeMillis())
.startSpan();
try (Scope scope = span.makeCurrent()) {
System.out.println("scheduled!");
Thread.sleep(500L);
span.setAttribute("schedule.success", true);
System.out.println(Span.current().getSpanContext().getTraceId()); // Get the trace ID
} catch (Throwable t) {
span.setStatus(StatusCode.ERROR, t.getMessage());
} finally {
span.end();
}
}
}, 10, 30, TimeUnit.SECONDS);
}
@ResponseBody
@RequestMapping("/parent")
public String parent() {
Span span = tracer.spanBuilder("parent").setSpanKind(SpanKind.SERVER).startSpan();
try (Scope scope = span.makeCurrent()) {
// Use Baggage to propagate custom business tags.
Baggage baggage = Baggage.current().toBuilder()
.put("user.id", "1")
.put("user.name", "name")
.build();
try (Scope baggageScope = baggage.storeInContext(Context.current()).makeCurrent()) {
child();
}
span.setAttribute("http.method", "GET");
span.setAttribute("http.uri", "/parent");
} finally {
span.end();
}
return "parent";
}
private void child() {
Span span = tracer.spanBuilder("child").startSpan();
try (Scope scope = span.makeCurrent()) {
System.out.println("current traceId = " + Span.current().getSpanContext().getTraceId());
System.out.println("userId in baggage = " + Baggage.current().getEntryValue("user.id"));
Thread.sleep(1000);
} catch (Throwable e) {
span.setStatus(StatusCode.ERROR, e.getMessage());
} finally {
span.end();
}
}
}
Explicación del ejemplo:
En el método
initdeOpenTelemetryController, se inicia una tarea programada. Se crea un span al inicio de cada ejecución y finaliza cuando esta termina.-
En el método
parentdeOpenTelemetryController, se llaman varios métodos del SDK de OpenTelemetry.Cada vez que se llama al método, se crea un span llamado
parent, el cual finaliza cuando el método termina.Se usa el SDK de Baggage para agregar dos elementos de Baggage:
user.idyuser.name. Estos elementos se propagan a las aplicaciones descendentes.Se agregan dos atributos al span creado en el paso 2.a.
-
El método
childdeOpenTelemetryControllerejecuta las siguientes operaciones:
Diferencias entre versiones del agente de ARMS
La compatibilidad con las operaciones del código anterior varía según la versión del agente de ARMS.
|
Paso |
Agente de ARMS v4.x y posteriores |
Agente de ARMS v3.x y anteriores |
|
1 |
Compatible. Se genera un nuevo span. |
Compatible. Se genera un nuevo span. |
|
2.a |
Compatible |
Compatible |
|
2.b |
Compatible |
No compatible |
|
2.c |
Compatible |
Compatible |
|
3.a |
Compatible |
Compatible. Este span aparece como una pila de métodos dentro del span creado en el paso 2.a. |
|
3.b |
Compatible. El ID de traza impreso coincide con el ID de traza en ARMS. |
No compatible. El ID de traza impreso difiere del ID de traza del agente de ARMS. |
|
3.c |
Compatible |
Compatible |
Resultados de la instrumentación
v4.x y posteriores
-
Resultado de la instrumentación del paso 1:
Es posible ver el span generado por el SDK de OpenTelemetry.
En Span Details de una traza en la consola de ARMS, consulte información básica como el nombre de la aplicación (por ejemplo,
elastic-search-8), el nombre de la operación (por ejemplo,schedule), el tipo de span (INTERNAL) y la duración. En la pestaña Attributes, consulte los atributos de OpenTelemetry, comootel.scope.name=manual-sdkyotel.scope.version=1.0.0, así como los atributos de negocio personalizados, comoschedule.success=true. Esto confirma que la instrumentación funciona correctamente. -
Resultados de la instrumentación de los pasos 2.x y 3.x:
Los spans generados por el SDK de OpenTelemetry aparecen en la misma traza que los spans de Tomcat generados por el agente. Además, los atributos relacionados con los spans generados por el SDK se establecen según lo esperado.
En los detalles de la traza, el nombre de la operación del span generado por la instrumentación del agente de Tomcat es
/opentelemetry/parent. Los spans generados por el SDK de OpenTelemetry se denominanparenty su span hijochild. En los atributos del span,http.methodesGET,http.uries/parenty el atributo personalizadootel.scope.nameesmanual-sdk.
v3.x y anteriores
-
Resultado de la instrumentación del paso 1:
En la página de detalles de la traza en la consola de ARMS, consulte los datos de traza recopilados por la instrumentación. El gráfico de cascada de la izquierda muestra las relaciones de llamadas entre spans. Por ejemplo, el método
schedulede la aplicaciónelastic-search-9se captura como un span con un tipo de componenteuser_methody un tiempo de respuesta total de 567 ms. El panel Span Details de la derecha muestra información básica como el nombre de la aplicación, el nombre del span, la dirección IP, el ID de span y el código de estado. La sección Attributes, ubicada debajo, muestra atributos adicionales agrupados, como HTTP Information (http.path,http.status_code), RPC Information (rpc.type) y Built-in Information (component.name=user_method,slow=1). -
Resultados de la instrumentación de los pasos 2.x y 3.x:
El span
childse muestra dentro de la pila de métodos del spanparent. Además, los atributos de los spans generados por el SDK se establecen según lo esperado.En la vista de method stack, la jerarquía de la traza muestra que OpenTelemetry Entry Span llama al span parent, el cual a su vez llama al span child. Estas tres llamadas anidadas tardan aproximadamente 1.01 segundos cada una. Los atributos del método child incluyen
line=-1yrpc.type=98.
Documentos relacionados
Correlacionar la información del ID de traza con los registros de negocio de su aplicación le permite encontrar rápidamente los registros asociados para solucionar problemas cuando ocurre un error. Para obtener más información, consulte Associate trace IDs with business logs for Java applications.