Les vérifications de santé (health checks), les sondes de disponibilité (readiness probes) et autres requêtes routinières génèrent des spans qui ajoutent du bruit à vos traces et augmentent les coûts. Utilisez un sampler OpenTelemetry personnalisé pour supprimer ces spans avant qu'elles ne quittent votre application.
Managed Service for OpenTelemetry prend en charge le filtrage des spans pour les applications Java et Node.js.
Fonctionnement
OpenTelemetry utilise des samplers pour décider s'il faut enregistrer et exporter chaque span. Un sampler personnalisé inspecte les propriétés de la span, telles que son nom ou le chemin cible HTTP, et renvoie l'une des deux décisions suivantes :
DROP (
SamplingDecision.DROP) : la span est ignorée. Elle n'est ni enregistrée ni exportée.RECORD_AND_SAMPLE (
SamplingDecision.RECORD_AND_SAMPLE) : la span est conservée, enregistrée et exportée normalement.
Écrivez un sampler qui identifie les spans indésirables et renvoie DROP pour éliminer le bruit à la source.
Choisir une méthode
L'approche appropriée dépend de votre configuration d'instrumentation et de votre langage de programmation.
Java
| Méthode | Cas d'utilisation | Modifications de code requises |
|---|---|---|
| Extension de l'agent | Instrumentation automatique avec OpenTelemetry Java Agent ; aucune modification du code applicatif n'est nécessaire | Générer un JAR distinct |
| Sampler SDK | Instrumentation manuelle avec OpenTelemetry SDK for Java | Ajouter la classe du sampler au code de votre application |
Node.js
| Méthode | Cas d'utilisation | Modifications de code requises |
|---|---|---|
| Filtrage à la création | Empêcher la création de spans pour des requêtes HTTP spécifiques | Configurer ignoreIncomingRequestHook dans HttpInstrumentation |
| Filtrage à l'exportation | Supprimer des spans en fonction d'attributs évalués après leur création | Implémenter une classe de sampler personnalisée |
Java
Créer une extension d'agent pour OpenTelemetry Java Agent
Générez un sampler personnalisé sous forme d'extension Java Agent. Cette approche permet de séparer la logique de filtrage du code de votre application.
Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants :
Une application instrumentée automatiquement avec OpenTelemetry Java Agent. Pour les instructions de configuration, consultez Utiliser OpenTelemetry pour soumettre les données de trace des applications Java
Apache Maven installé pour générer le JAR de l'extension
Étape 1 : Créer un projet Maven
Créez un nouveau projet Maven pour générer l'extension de l'agent.
Étape 2 : Ajouter les dépendances
Ajoutez les dépendances suivantes à votre fichier pom.xml.
Toutes les dépendances OpenTelemetry doivent correspondre à la version de l'OpenTelemetry Java Agent que vous utilisez. L'exemple suivant utilise la version 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>
Étape 3 : Implémenter le sampler
Créez une classe qui implémente l'interface io.opentelemetry.sdk.trace.samplers.Sampler. Définissez vos règles de filtrage dans la méthode shouldSample et renvoyez un nom de sampler depuis getDescription.
shouldSample: évaluez chaque span et renvoyezSamplingResult.create(SamplingDecision.DROP)pour les spans à ignorer, ouSamplingResult.create(SamplingDecision.RECORD_AND_SAMPLE)pour les spans à conserver.getDescription: renvoyez le nom du sampler.
L'exemple suivant ignore les spans nommées spanName1 ou spanName2, ainsi que les spans dont l'attribut http.target a pour valeur /api/checkHealth ou /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";
}
}
Étape 4 : Implémenter le fournisseur de sampler
Créez une classe qui implémente io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSamplerProvider. Ce fournisseur enregistre votre sampler auprès du mécanisme de configuration automatique du Java Agent.
createSampler: renvoyez une instance de votre sampler.getName: renvoyez le nom du sampler. Le Java Agent utilise ce nom pour localiser le 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";
}
}
Étape 5 : Générer le JAR de l'extension
Empaquetez le projet dans un fichier JAR :
mvn clean package
Le fichier JAR est généré dans le répertoire target.
Étape 6 : Charger l'extension au démarrage
Spécifiez votre sampler personnalisé lors du démarrage de l'application. Utilisez soit une propriété système JVM, soit une variable d'environnement.
Option A : Propriété système JVM
Ajoutez -Dotel.traces.sampler=<your-sampler-name> aux paramètres de démarrage de la JVM. Remplacez <your-sampler-name> par la valeur renvoyée par la méthode getName.
Option B : Variable d'environnement
Définissez la variable d'environnement OTEL_TRACES_SAMPLER avec le nom de votre sampler :
Remplacez les espaces réservés suivants par vos valeurs réelles :
| Espace réservé | Description |
|---|---|
<your-sampler-name> |
Nom du sampler renvoyé par getName |
<token> |
Jeton d'authentification pour l'endpoint OTLP |
<endpoint> |
URL de l'endpoint de l'exportateur OTLP |
Enregistrer un sampler personnalisé avec OpenTelemetry SDK for Java
Pour les applications utilisant une instrumentation manuelle, ajoutez le sampler directement au code de votre application.
Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants :
Une application instrumentée manuellement avec OpenTelemetry SDK for Java. Pour les instructions de configuration, consultez Utiliser OpenTelemetry pour soumettre les données de trace des applications Java
Étape 1 : Créer la classe du sampler
Créez une classe SpanFilterSampler qui implémente l'interface Sampler. L'implémentation est identique à celle du sampler de l'extension d'agent décrite à l'étape Étape 3 : Implémenter le sampler. Adaptez les listes EXCLUDED_SPAN_NAMES et EXCLUDED_HTTP_REQUEST_TARGETS pour qu'elles correspondent aux spans que vous souhaitez ignorer.
Étape 2 : Enregistrer le sampler avec SdkTracerProvider
Appelez .setSampler(new SpanFilterSampler()) lors de la construction de l'instance 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();
Étape 3 : Redémarrer l'application
Redémarrez votre application. Le sampler évalue chaque nouvelle span et ignore celles qui correspondent aux règles de filtrage.
Node.js
Projet de démonstration : opentelemetry-nodejs-demo
Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants :
Une application instrumentée avec l'API Managed Service for OpenTelemetry pour JavaScript. Pour les instructions de configuration, consultez Utiliser OpenTelemetry pour soumettre les données de trace d'une application Node.js
Filtrer les spans à la création
Empêchez la génération de spans pour des requêtes HTTP spécifiques en configurant ignoreIncomingRequestHook dans HttpInstrumentation. Le hook s'exécute avant le traitement de la requête et contrôle uniquement la création de la span ; la requête elle-même est traitée normalement.
L'exemple suivant ignore la création de span pour les requêtes vers /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],
});
Démarrez l'application après avoir mis à jour la configuration de l'instrumentation.
Filtrer les spans à l'exportation
Supprimez les spans en fonction de leurs attributs après leur création en implémentant un sampler personnalisé.
Étape 1 : Créer une classe de sampler
Créez une classe qui implémente l'interface Sampler. Définissez votre logique de filtrage dans shouldSample :
const opentelemetry = require('@opentelemetry/api');
class SpanFilterSampler {
shouldSample(spanContext, parentContext) {
// Implement your custom sampling logic here.
}
}
Étape 2 : Enregistrer le sampler avec NodeTracerProvider
Passez l'instance du sampler au constructeur 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>",
}),
});
Remplacez <your-service-name> par le nom de votre service, par exemple my-node-app.
Démarrez l'application après avoir mis à jour la configuration du fournisseur.
Vérifier que le filtrage fonctionne
Après avoir configuré et déployé un sampler personnalisé, vérifiez que les spans sont correctement filtrées :
Générez du trafic correspondant à vos règles de filtrage. Par exemple, envoyez des requêtes vers
/api/checkHealthou d'autres endpoints filtrés.Ouvrez la console Managed Service for OpenTelemetry. Les spans filtrées ne devraient plus apparaître dans vos traces.
Comparez le nombre de spans avant et après le filtrage. Une réduction du volume de spans pour les endpoints filtrés confirme que le sampler fonctionne.
Si les spans filtrées apparaissent toujours, vérifiez les points suivants :
| Symptôme | Cause possible | Résolution |
|---|---|---|
| Les spans sont toujours exportées | Le sampler n'est pas enregistré | Vérifiez que OTEL_TRACES_SAMPLER ou -Dotel.traces.sampler est défini avec le nom de votre sampler |
| Erreur « Sampler not found » au démarrage | Incohérence de nom | Assurez-vous que getName() dans le fournisseur renvoie le même nom que celui utilisé dans le paramètre de démarrage |
| Le JAR de l'extension n'est pas chargé | Chemin incorrect | Vérifiez que le chemin dans OTEL_JAVAAGENT_EXTENSIONS ou -Dotel.javaagent.extensions pointe vers le bon fichier JAR |
| Mauvaises spans filtrées | Erreur de logique dans la règle de filtrage | Examinez les conditions dans shouldSample et confirmez que les noms de spans et les valeurs d'attributs correspondent à vos attentes |