Instrumentación personalizada de Java con la API de OpenTelemetry
Overview
There are a few reasons to manually instrument your applications with the OpenTelemetry API:
- You are not using Datadog supported library instrumentation.
- You want to extend the
ddtrace
library’s functionality. - You need finer control over instrumenting your applications.
The ddtrace
library provides several techniques to help you achieve these goals. The following sections demonstrate how to use the OpenTelemetry API for custom instrumentation to use with Datadog.
Configuración
OpenTelemetry es compatible con Java a partir de la versión 1.24.0.
Para configurar OpenTelemetry para utilizar el proveedor de traza de Datadog:
Si aún no has leído las instrucciones de autoinstrumentación y configuración, comienza por las [Instrucciones de configuración de Java][1].
Asegúrate de que solo dependes de la API de OpenTelemetry (y no del SDK de OpenTelemetry).
Establece la propiedad del sistema dd.trace.otel.enabled
o la variable de entorno DD_TRACE_OTEL_ENABLED
en true
.
Añadir etiquetas al tramo
Añadir etiquetas de tramo personalizadas
Añade etiquetas personalizadas a tus tramos correspondientes a cualquier valor dinámico dentro de tu código de aplicación como customer.id
.
import io.opentelemetry.api.trace.Span;
public void doSomething() {
Span span = Span.current();
span.setAttribute("user-name", "Some User");
}
Añadir etiquetas globalmente a todos los tramos
La propiedad dd.tags
permite establecer etiquetas en todos los tramos generados para una aplicación. Esto puede ser útil para agrupar las estadísticas de las aplicaciones, los centros de datos o cualquier otra etiqueta que desees ver en la interfaz de usuario de Datadog.
java -javaagent:<DD-JAVA-AGENT-PATH>.jar \
-Ddd.tags=datacenter:njc,<TAG_KEY>:<TAG_VALUE> \
-jar <YOUR_APPLICATION_PATH>.jar
Configuración de errores en un tramo raíz desde un tramo secundario
Para establecer un error en un tramo raíz desde un tramo secundario, puedes utilizar el método setStatus
en el tramo actual de la siguiente manera:
import static io.opentelemetry.api.trace.StatusCode.ERROR;
import io.opentelemetry.api.trace.Span;
public void doSomething() {
Span span = Span.current();
span.setStatus(ERROR, "Some error details...");
}
Configuración de etiquetas y errores en un tramo raíz desde un tramo secundario
Este ejemplo muestra cómo configurar etiquetas y errores en un tramo raíz desde un tramo secundario:
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.ContextKey;
import io.opentelemetry.context.Scope;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
import io.opentelemetry.semconv.ResourceAttributes;
import java.util.concurrent.TimeUnit;
public class Example {
private final static ContextKey<Span> CONTEXT_KEY =
ContextKey.named("opentelemetry-traces-local-root-span");
public void begin() {
tracer = GlobalOpenTelemetry.getTracer("my-scope", "0.1.0");
Span parentSpan = tracer.spanBuilder("begin").startSpan();
try (Scope scope = parentSpan.makeCurrent()) {
createChildSpan();
} finally {
parentSpan.end();
}
}
private void createChildSpan() {
Span childSpan = tracer.spanBuilder("child-span").startSpan();
try {
Span rootSpan = Context.current().get(CONTEXT_KEY);
if (null != rootSpan) {
rootSpan.setAttribute("my-attribute", "my-attribute-value");
rootSpan.setStatus(StatusCode.ERROR, "Some error details...");
}
} finally {
childSpan.end();
}
}
}
Añadir tramos
Si no estás usando una instrumentación de marco compatible, o te gustaría conocer más sobre las trazas de tu aplicación, puede que quieras añadir instrumentación personalizada a tu código para obtener gráficas de llamas completas o para medir los tiempos de ejecución de fragmentos de código.
Si no es posible modificar el código de la aplicación, utiliza la variable de entorno dd.trace.methods para detallar estos métodos.
Si ya dispones de @Trace o anotaciones similares, o prefieres utilizar anotaciones para completar cualquier traza incompleta dentro de Datadog, utiliza anotaciones de traza.
Las trazas también pueden crearse mediante la anotación de OpenTelemetry @WithSpan
, como se describe en anotaciones de traza.
Anotaciones de traza
Añade @WithSpan
a los métodos para que sean rastreados cuando se ejecuta OpenTelemetry y el dd-java-agent.jar
. Si el Agent no está adjunto, esta anotación no tiene ningún efecto en tu aplicación.
La anotación @WithSpan
de OpenTelemetry es proporcionada por la dependencia opentelemetry-instrumentation-annotations
.
import io.opentelemetry.instrumentation.annotations.WithSpan;
public class SessionManager {
@WithSpan
public static void saveSession() {
// tu método de implementación aquí
}
}
Creación manual de un nuevo tramo
Para crear manualmente nuevos tramos en el contexto de traza actual:
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Scope;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
import io.opentelemetry.semconv.ResourceAttributes;
import java.util.concurrent.TimeUnit;
public class Example {
public void doSomething() {
Tracer tracer = GlobalOpenTelemetry.getTracer("my-scope", "0.1.0");
Span span = tracer.spanBuilder("my-resource").startSpan();
try (Scope scope = span.makeCurrent()) {
// haz alguna acción
} catch (Throwable t) {
span.recordException(t);
throw t;
} finally {
span.end();
}
}
}
Rastrear la configuración del cliente y el Agent
Tanto el cliente de rastreo como el Datadog Agent ofrecen opciones adicionales de configuración para la propagación de contexto. También puedes excluir recursos específicos del envío de trazas a Datadog si no deseas que esas trazas se incluyan en métricas calculadas, como trazas relacionadas con los checks de estado.
Puedes configurar la propagación de contexto para trazas distribuidas al inyectar y extraer encabezados. Consulta Propagación de contexto de traza para obtener información.
Filtrado de recursos
Las trazas se pueden excluir en función de su nombre de recurso, para eliminar el tráfico Synthetic, como los checks de estado, de la notificación de trazas a Datadog. Esta y otras configuraciones de seguridad y ajuste se pueden encontrar en la página de Seguridad o en Ignorar recursos no deseados.
Lectura adicional
Más enlaces, artículos y documentación útiles: