Las comprobaciones de estado, las pruebas de disponibilidad y otras solicitudes rutinarias generan spans que añaden ruido a sus trazas e incrementan los costos. Utilice un sampler personalizado de OpenTelemetry para descartar estos spans antes de que salgan de su aplicación.
Managed Service for OpenTelemetry admite el filtrado de spans para aplicaciones Java y Node.js.
Funcionamiento
OpenTelemetry utiliza samplers para decidir si se registra y exporta cada span. Un sampler personalizado inspecciona las propiedades del span, como el nombre o la ruta de destino HTTP, y devuelve una de dos decisiones:
DROP (
SamplingDecision.DROP): El span se descarta. No se registra ni se exporta.RECORD_AND_SAMPLE (
SamplingDecision.RECORD_AND_SAMPLE): El span se conserva, se registra y se exporta con normalidad.
Escriba un sampler que identifique los spans no deseados y devuelva DROP para eliminar el ruido desde el origen.
Elegir un método
El enfoque adecuado depende de su configuración de instrumentación y del lenguaje de programación.
Java
|
Método |
Cuándo utilizarlo |
Cambios de código obligatorios |
|
Instrumentación automática con OpenTelemetry Java Agent; no requiere cambios en el código de la aplicación |
Compilar un JAR independiente |
|
|
Instrumentación manual con OpenTelemetry SDK for Java |
Agregar la clase del sampler al código de su aplicación |
Node.js
|
Método |
Cuándo utilizarlo |
Cambios de código obligatorios |
|
Evitar que se creen spans para solicitudes HTTP específicas |
Configurar |
|
|
Descartar spans según atributos evaluados después de su creación |
Implementar una clase de sampler personalizada |
Java
Crear una extensión de agente para OpenTelemetry Java Agent
Compile un sampler personalizado como extensión de Java Agent. Este enfoque mantiene la lógica de filtrado separada del código de su aplicación.
Requisitos previos
Antes de empezar, asegúrese de contar con lo siguiente:
Una aplicación instrumentada automáticamente con OpenTelemetry Java Agent. Para consultar las instrucciones de configuración, revise Use OpenTelemetry to submit the trace data of Java applications
Apache Maven instalado para compilar el JAR de la extensión
Paso 1: Crear un proyecto Maven
Cree un nuevo proyecto Maven para compilar la extensión del agente.
Paso 2: Agregar dependencias
Agregue las siguientes dependencias a su archivo pom.xml.
Todas las dependencias de OpenTelemetry deben coincidir con la versión de OpenTelemetry Java Agent que utilice. El siguiente ejemplo usa la versión 1.28.0.
<dependency>
<groupId>com.google.auto.service</groupId>
<artifactId>auto-service</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>io.opentelemetry.javaagent</groupId>
<artifactId>opentelemetry-javaagent</artifactId>
<version>1.28.0</version>
<!--Set the scope to compile.-->
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-trace</artifactId>
<version>1.28.0</version>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-extension-autoconfigure</artifactId>
<version>1.28.0</version>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-semconv</artifactId>
<version>1.28.0-alpha</version>
</dependency>
Paso 3: Implementar el sampler
Cree una clase que implemente la interfaz io.opentelemetry.sdk.trace.samplers.Sampler. Defina sus reglas de filtrado en el método shouldSample y devuelva un nombre de sampler desde getDescription.
shouldSample: Evalúa cada span y devuelveSamplingResult.create(SamplingDecision.DROP)para los spans que se deban descartar, oSamplingResult.create(SamplingDecision.RECORD_AND_SAMPLE)para los que se deban conservar.getDescription: Devuelve el nombre del sampler.
El siguiente ejemplo descarta los spans llamados spanName1 o spanName2, así como aquellos con un atributo http.target igual a /api/checkHealth o /health/checks:
package org.example;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.sdk.trace.data.LinkData;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import io.opentelemetry.sdk.trace.samplers.SamplingDecision;
import io.opentelemetry.sdk.trace.samplers.SamplingResult;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.util.*;
public class SpanFilterSampler implements Sampler {
// Span names to drop
private static List<String> EXCLUDED_SPAN_NAMES = Collections.unmodifiableList(
Arrays.asList("spanName1", "spanName2")
);
// HTTP target paths to drop
private static List<String> EXCLUDED_HTTP_REQUEST_TARGETS = Collections.unmodifiableList(
Arrays.asList("/api/checkHealth", "/health/checks")
);
@Override
public SamplingResult shouldSample(Context parentContext, String traceId, String name,
SpanKind spanKind, Attributes attributes, List<LinkData> parentLinks) {
String httpTarget = attributes.get(SemanticAttributes.HTTP_TARGET) != null
? attributes.get(SemanticAttributes.HTTP_TARGET) : "";
if (EXCLUDED_SPAN_NAMES.contains(name)
|| EXCLUDED_HTTP_REQUEST_TARGETS.contains(httpTarget)) {
return SamplingResult.create(SamplingDecision.DROP);
}
return SamplingResult.create(SamplingDecision.RECORD_AND_SAMPLE);
}
@Override
public String getDescription() {
return "SpanFilterSampler";
}
}
Paso 4: Implementar el proveedor del sampler
Cree una clase que implemente io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSamplerProvider. Este proveedor registra su sampler con el mecanismo de autoconfiguración de Java Agent.
createSampler: Devuelve una instancia de su sampler.getName: Devuelve el nombre del sampler. Java Agent utiliza este nombre para localizar el sampler.
package org.example;
import com.google.auto.service.AutoService;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSamplerProvider;
import io.opentelemetry.sdk.trace.samplers.Sampler;
@AutoService(ConfigurableSamplerProvider.class)
public class SpanFilterSamplerProvider implements ConfigurableSamplerProvider {
@Override
public Sampler createSampler(ConfigProperties configProperties) {
return new SpanFilterSampler();
}
@Override
public String getName() {
return "SpanFilterSampler";
}
}
Paso 5: Compilar el JAR de la extensión
Empaquete el proyecto en un archivo JAR:
mvn clean package
El archivo JAR se genera en el directorio target.
Paso 6: Cargar la extensión al iniciar
Especifique su sampler personalizado al iniciar la aplicación. Puede usar una propiedad del sistema JVM o una variable de entorno.
Opción A: Propiedad del sistema JVM
Agregue -Dotel.traces.sampler=<your-sampler-name> a los parámetros de inicio de la JVM. Reemplace <your-sampler-name> con el valor que devuelve el método getName.
Opción B: Variable de entorno
Establezca la variable de entorno OTEL_TRACES_SAMPLER con el nombre de su sampler:
Reemplace los siguientes marcadores de posición con sus valores reales:
|
Marcador de posición |
Descripción |
|
|
Nombre del sampler devuelto por |
|
|
Token de autenticación para el endpoint OTLP |
|
|
URL del endpoint del exportador OTLP |
Registrar un sampler personalizado con OpenTelemetry SDK for Java
Para aplicaciones con instrumentación manual, agregue el sampler directamente al código de su aplicación.
Requisitos previos
Antes de empezar, asegúrese de contar con lo siguiente:
Una aplicación instrumentada manualmente con OpenTelemetry SDK for Java. Para consultar las instrucciones de configuración, revise Use OpenTelemetry to submit the trace data of Java applications
Paso 1: Crear la clase del sampler
Cree una clase SpanFilterSampler que implemente la interfaz Sampler. La implementación es idéntica a la del sampler de extensión de agente descrita en Paso 3: Implementar el sampler. Adapte las listas EXCLUDED_SPAN_NAMES y EXCLUDED_HTTP_REQUEST_TARGETS para que coincidan con los spans que desea descartar.
Paso 2: Registrar el sampler con SdkTracerProvider
Llame a .setSampler(new SpanFilterSampler()) al construir la instancia de SdkTracerProvider:
SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
.setSampler(new SpanFilterSampler()) // Register the custom sampler
.addSpanProcessor(BatchSpanProcessor.builder(OtlpGrpcSpanExporter.builder()
.setEndpoint("<endpoint>")
.addHeader("Authentication", "<token>")
.build()).build())
.setResource(resource)
.build();
Paso 3: Reiniciar la aplicación
Reinicie su aplicación. El sampler evaluará cada nuevo span y descartará aquellos que coincidan con las reglas de filtrado.
Node.js
Proyecto de demostración: opentelemetry-nodejs-demo
Requisitos previos
Antes de empezar, asegúrese de contar con lo siguiente:
Una aplicación instrumentada con la API de Managed Service for OpenTelemetry para JavaScript. Para consultar las instrucciones de configuración, revise Use OpenTelemetry to submit the trace data of a Node.js application
Filtrar spans durante la creación
Evite que ciertas solicitudes HTTP generen spans mediante la configuración de ignoreIncomingRequestHook en HttpInstrumentation. El hook se ejecuta antes del procesamiento de la solicitud y solo controla si se crea un span; la solicitud en sí se maneja con normalidad.
El siguiente ejemplo omite la creación de spans para solicitudes a /api/checkHealth:
const httpInstrumentation = new HttpInstrumentation({
ignoreIncomingRequestHook: (request) => {
// Skip span creation for health check requests
if (request.url === '/api/checkHealth') {
return true;
}
return false;
},
});
registerInstrumentations({
tracerProvider: provider,
instrumentations: [httpInstrumentation, ExpressInstrumentation],
});
Inicie la aplicación después de actualizar la configuración de instrumentación.
Filtrar spans durante la exportación
Descarte spans según sus atributos después de la creación mediante la implementación de un sampler personalizado.
Paso 1: Crear una clase de sampler
Cree una clase que implemente la interfaz Sampler. Defina su lógica de filtrado en shouldSample:
const opentelemetry = require('@opentelemetry/api');
class SpanFilterSampler {
shouldSample(spanContext, parentContext) {
// Implement your custom sampling logic here.
}
}
Paso 2: Registrar el sampler con NodeTracerProvider
Pase la instancia del sampler al constructor de NodeTracerProvider:
const provider = new NodeTracerProvider({
sampler: new SpanFilterSampler(), // Register the custom sampler
resource: new Resource({
[SemanticResourceAttributes.HOST_NAME]: require("os").hostname(),
[SemanticResourceAttributes.SERVICE_NAME]: "<your-service-name>",
}),
});
Reemplace <your-service-name> con el nombre de su servicio, por ejemplo, my-node-app.
Inicie la aplicación después de actualizar la configuración del proveedor.
Comprobar que el filtrado funciona
Después de configurar y desplegar un sampler personalizado, compruebe que los spans se filtran correctamente:
Genere tráfico que coincida con sus reglas de filtrado. Por ejemplo, envíe solicitudes a
/api/checkHealthu otros endpoints filtrados.Abra la consola de Managed Service for OpenTelemetry. Los spans filtrados ya no deberían aparecer en sus trazas.
Compare el recuento de spans antes y después del filtrado. Una reducción en el volumen de spans para los endpoints filtrados confirma que el sampler funciona correctamente.
Si los spans filtrados siguen apareciendo, revise lo siguiente:
|
Síntoma |
Posible causa |
Solución |
|
Los spans se siguen exportando |
El sampler no está registrado |
Compruebe que |
|
Error de sampler no encontrado al iniciar |
Discrepancia de nombres |
Asegúrese de que |
|
El JAR de extensión no se carga |
Ruta incorrecta |
Verifique que la ruta en |
|
Se filtran los spans equivocados |
Error lógico en la regla de filtrado |
Revise las condiciones en |