Verificações de saúde, probes de prontidão e outras requisições rotineiras geram spans que adicionam ruído aos seus traces e aumentam os custos. Utilize um sampler personalizado do OpenTelemetry para descartar esses spans antes que eles saiam da sua aplicação.
O Managed Service for OpenTelemetry oferece suporte à filtragem de spans para aplicações Java e Node.js.
Como funciona
O OpenTelemetry utiliza samplers para decidir se deve gravar e exportar cada span. Um sampler personalizado inspeciona as propriedades do span — como o nome do span ou o caminho de destino HTTP — e retorna uma das duas decisões:
DROP (
SamplingDecision.DROP) — O span é descartado. Ele não é gravado nem exportado.RECORD_AND_SAMPLE (
SamplingDecision.RECORD_AND_SAMPLE) — O span é mantido, gravado e exportado normalmente.
Escreva um sampler que identifique os spans indesejados e retorne DROP para eliminar o ruído na source.
Escolha um método
A abordagem ideal depende da sua configuração de instrumentação e da linguagem de programação.
Java
|
Método |
Quando usar |
Alterações de código necessárias |
|
Instrumentação automática com OpenTelemetry Java Agent; sem necessidade de alterar o código da aplicação |
Construa um JAR separado |
|
|
Instrumentação manual com OpenTelemetry SDK for Java |
Adicione a classe do sampler ao código da sua aplicação |
Node.js
|
Método |
Quando usar |
Alterações de código necessárias |
|
Evite a criação de spans para requisições HTTP específicas |
Configure |
|
|
Descarte spans com base em atributos avaliados após a criação do span |
Implemente uma classe de sampler personalizada |
Java
Crie uma extensão de agent para OpenTelemetry Java Agent
Construa um sampler personalizado como uma extensão do Java Agent. Essa abordagem mantém a lógica de filtragem separada do código da sua aplicação.
Pré-requisitos
Antes de começar, certifique-se de ter:
Uma aplicação instrumentada automaticamente com OpenTelemetry Java Agent. Para instruções de configure, consulte Use OpenTelemetry to submit the trace data of Java applications
Apache Maven instalado para construir o JAR da extensão
Etapa 1: Crie um projeto Maven
Crie um novo projeto Maven para construir a extensão do agent.
Etapa 2: Adicione dependências
Adicione as seguintes dependências ao seu arquivo pom.xml.
Todas as dependências do OpenTelemetry devem corresponder à versão do OpenTelemetry Java Agent que você utiliza. O exemplo a seguir usa a versão 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>
Etapa 3: Implemente o sampler
Crie uma classe que implemente a interface io.opentelemetry.sdk.trace.samplers.Sampler. Defina suas regras de filtragem no método shouldSample e retorne um nome de sampler a partir de getDescription.
shouldSample— Avalie cada span e retorneSamplingResult.create(SamplingDecision.DROP)para spans a serem descartados, ouSamplingResult.create(SamplingDecision.RECORD_AND_SAMPLE)para spans a serem mantidos.getDescription— Retorne o nome do sampler.
O exemplo a seguir descarta spans chamados spanName1 ou spanName2, além de spans com um atributo http.target igual a /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";
}
}
Etapa 4: Implemente o provedor do sampler
Crie uma classe que implemente io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSamplerProvider. Este provedor registra seu sampler no mecanismo de autoconfiguração do Java Agent.
createSampler— Retorne uma instância do seu sampler.getName— Retorne o nome do sampler. O Java Agent usa esse nome para localizar o 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";
}
}
Etapa 5: Construa o JAR da extensão
Empacote o projeto em um arquivo JAR:
mvn clean package
O arquivo JAR é gerado no diretório target.
Etapa 6: Carregue a extensão na inicialização
Especifique seu sampler personalizado ao iniciar a aplicação. Use uma propriedade de sistema JVM ou uma variável de ambiente.
Opção A: Propriedade de sistema JVM
Adicione -Dotel.traces.sampler=<your-sampler-name> aos parâmetros de inicialização da JVM. Substitua <your-sampler-name> pelo valor retornado pelo método getName.
Opção B: Variável de ambiente
Defina a variável de ambiente OTEL_TRACES_SAMPLER com o nome do seu sampler:
Substitua os seguintes placeholders pelos seus valores reais:
|
Placeholder |
Descrição |
|
|
Nome do sampler retornado por |
|
|
Token de autenticação para o endpoint OTLP |
|
|
URL do endpoint do exportador OTLP |
Registre um sampler personalizado com OpenTelemetry SDK for Java
Para aplicações com instrumentação manual, adicione o sampler diretamente ao código da sua aplicação.
Pré-requisitos
Antes de começar, certifique-se de ter:
Uma aplicação instrumentada manualmente com OpenTelemetry SDK for Java. Para instruções de configure, consulte Use OpenTelemetry to submit the trace data of Java applications
Etapa 1: Crie a classe do sampler
Crie uma classe SpanFilterSampler que implemente a interface Sampler. A implementação é a mesma do sampler de extensão do agent na Etapa 3: Implemente o sampler. Adapte as listas EXCLUDED_SPAN_NAMES e EXCLUDED_HTTP_REQUEST_TARGETS para corresponder aos spans que você deseja descartar.
Etapa 2: Registre o sampler com SdkTracerProvider
Chame .setSampler(new SpanFilterSampler()) ao construir a instância 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();
Etapa 3: Reinicie a aplicação
Reinicie sua aplicação. O sampler avalia cada novo span e descarta aqueles que correspondem às regras de filtro.
Node.js
Projeto de demonstração: opentelemetry-nodejs-demo
Pré-requisitos
Antes de começar, certifique-se de ter:
Uma aplicação instrumentada com a API do Managed Service for OpenTelemetry para JavaScript. Para instruções de configure, consulte Use OpenTelemetry to submit the trace data of a Node.js application
Filtre spans no momento da criação
Evite que requisições HTTP específicas gerem spans configurando ignoreIncomingRequestHook em HttpInstrumentation. O hook é executado antes do processamento da requisição e controla apenas se um span é criado — a requisição em si é tratada normalmente.
O exemplo a seguir ignora a criação de span para requisições 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 a aplicação após atualizar a configuração de instrumentação.
Filtre spans no momento da exportação
Descarte spans com base em seus atributos após a criação implementando um sampler personalizado.
Etapa 1: Crie uma classe de sampler
Crie uma classe que implemente a interface Sampler. Defina sua lógica de filtragem em shouldSample:
const opentelemetry = require('@opentelemetry/api');
class SpanFilterSampler {
shouldSample(spanContext, parentContext) {
// Implement your custom sampling logic here.
}
}
Etapa 2: Registre o sampler com NodeTracerProvider
Passe a instância do sampler para o construtor 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>",
}),
});
Substitua <your-service-name> pelo nome do seu service, por exemplo, my-node-app.
Inicie a aplicação após atualizar a configuração do provedor.
Verifique se a filtragem funciona
Após configurar e implantar um sampler personalizado, verifique se os spans estão sendo filtrados corretamente:
Gere tráfego que corresponda às suas regras de filtro. Por exemplo, envie requisições para
/api/checkHealthou outros endpoints filtrados.Abra o console do Managed Service for OpenTelemetry. Os spans filtrados não devem mais aparecer nos seus traces.
Compare a contagem de spans antes e depois da filtragem. Uma redução no volume de spans para os endpoints filtrados confirma que o sampler está funcionando.
Se os spans filtrados ainda aparecerem, verifique o seguinte:
|
Sintoma |
Possível causa |
Resolução |
|
Spans ainda exportados |
Sampler não registrado |
Verifique se |
|
Erro de sampler não encontrado na inicialização |
Incompatibilidade de nome |
Certifique-se de que |
|
JAR da extensão não carregado |
Caminho incorreto |
Verifique se o caminho em |
|
Spans errados filtrados |
Erro de lógica na regra de filtro |
Revise as condições em |