このトピックでは、Managed Service for OpenTelemetry を使用して、Java および Node.js アプリケーションの特定の Span を除外する方法について説明します。
Java アプリケーション
Managed Service for OpenTelemetry サンプラーを使用して、Span を除外できます。アプリケーションコードを変更したくない場合、または Managed Service for OpenTelemetry Java Agent を使用してアプリケーションデータを自動的にレポートしている場合は、エージェントの拡張機能を作成できます。カスタム OpenTelemetry サンプラーを作成し、フィルタールールを定義できます。このようにして、アプリケーションコードを変更することなく、特定の Span を除外できます。詳細については、方法 1 を参照してください。Managed Service for OpenTelemetry SDK for Java を使用してアプリケーションデータを手動でレポートしている場合は、アプリケーションコードでカスタムサンプラーを作成できます。詳細については、方法 2 を参照してください。
方法 1: Managed Service for OpenTelemetry Java Agent の拡張機能を作成する
前提条件
アプリケーションは、OpenTelemetry Java Agent を使用して自動的にインストルメント化されます。詳細については、OpenTelemetry を使用して Java アプリケーションのトレースデータをレポートする を参照してください。
プロジェクトを作成します。
Maven プロジェクトを作成します。このプロジェクトは、拡張機能を作成およびビルドするために使用されます。
pom.xml ファイルに依存関係を追加します。
重要依存関係に互換性があることを確認するために、Managed Service for OpenTelemetry に関連するすべての依存関係が、使用する OpenTelemetry Java Agent のバージョンと同じバージョンであることを確認してください。
<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> <!--scope フィールドの値を 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>
SpanFilterSampler クラスを作成します。カスタムクラス名を使用することもできます。
クラスは、io.opentelemetry.sdk.trace.samplers.Sampler インターフェースと shouldSample メソッドおよび getDescription メソッドを実装する必要があります。
shouldSample
メソッドでカスタムフィルタリングルールを定義できます。除外する Span については、
SamplingResult.create(SamplingDecision.DROP)
が返されます。保持してレポートする Span については、SamplingResult.create(SamplingDecision.RECORD_AND_SAMPLE)
が返されます。
getDescription
このメソッドは、カスタムサンプラーの名前を返します。
次の例では、SpanFilterSampler サンプラーは、名前が
spanName1
またはspanName2
である Span と、attributes.http.target が/api/checkHealth
または/health/checks
である Span を除外します。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 { /* * EXCLUDED_SPAN_NAMES に含まれる名前の Span を除外します。 */ private static List<String> EXCLUDED_SPAN_NAMES = Collections.unmodifiableList( Arrays.asList("spanName1", "spanName2") ); /* * attributes.http.target が EXCLUDED_HTTP_REQUEST_TARGETS に含まれる Span を除外します。 */ 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)) { // ルールに基づいて Span を除外します。 return SamplingResult.create(SamplingDecision.DROP); } else { return SamplingResult.create(SamplingDecision.RECORD_AND_SAMPLE); } } @Override public String getDescription() { return "SpanFilterSampler"; // SpanFilterSampler をカスタム名に置き換えることができます。 } }
SpanFilterSamplerProvider クラスを作成します。カスタムクラス名を使用することもできます。
クラスは、io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSamplerProvider インターフェースと createSampler メソッドおよび getName メソッドを実装する必要があります。
createSampler
このメソッドは、カスタムサンプラーインスタンスを作成して返します。
getName
このメソッドは、カスタムサンプラーの名前を返します。OpenTelemetry Java Agent は、名前でこのサンプラーを見つけます。
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"; // SpanFilterSampler をカスタム名に置き換えることができます。 } }
サンプラーをビルドします。
プロジェクトを Java アーカイブ (JAR) ファイルにパッケージ化し、JAR ファイルを target ディレクトリに保存します。
mvn clean package
アプリケーションの起動時に OpenTelemetry Java Agent の拡張機能を読み込みます。
方法 1: 元の VM パラメーターに otel.traces.sampler パラメーターを追加します。
-Dotel.traces.sampler=<your-sampler-name> // <your-sampler-name> をカスタムサンプラー名(getName メソッドの戻り値)に置き換えます。
方法 2: OTEL_TRACES_SAMPLER 環境変数を設定します。
export OTEL_TRACES_SAMPLER="<your-sampler-name>" // <your-sampler-name> をカスタムサンプラー名(getName メソッドの戻り値)に置き換えます。
方法 2: Managed Service for OpenTelemetry SDK for Java を使用する
前提条件
アプリケーションは、Managed Service for OpenTelemetry SDK for Java を使用して手動でインストルメント化されます。詳細については、OpenTelemetry を使用して Java アプリケーションのトレースデータをレポートする を参照してください。
アプリケーションコードでカスタムサンプラークラスを作成します。
クラスは、io.opentelemetry.sdk.trace.samplers.Sampler インターフェースと shouldSample メソッドおよび getDescription メソッドを実装する必要があります。
shouldSample
メソッドでカスタムフィルタリングルールを定義できます。除外する Span については、
SamplingResult.create(SamplingDecision.DROP)
が返されます。保持してレポートする Span については、SamplingResult.create(SamplingDecision.RECORD_AND_SAMPLE)
が返されます。
getDescription
このメソッドは、カスタムサンプラーの名前を返します。
次の例では、SpanFilterSampler サンプラーは、名前が
spanName1
またはspanName2
である Span と、attributes.http.target が/api/checkHealth
または/health/check
である Span を除外します。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 { /* * EXCLUDED_SPAN_NAMES に含まれる名前の Span を除外します。 */ private static List<String> EXCLUDED_SPAN_NAMES = Collections.unmodifiableList( Arrays.asList("spanName1", "spanName2") ); /* * attributes.http.target が EXCLUDED_HTTP_REQUEST_TARGETS に含まれる Span を除外します。 */ 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)) { // ルールに基づいて Span を除外します。 return SamplingResult.create(SamplingDecision.DROP); } else { return SamplingResult.create(SamplingDecision.RECORD_AND_SAMPLE); } } @Override public String getDescription() { return "SpanFilterSampler"; // SpanFilterSampler をカスタム名に置き換えることができます。 } }
SdkTracerProvider インスタンスを作成するときに、カスタムサンプラーを設定します。
SdkTracerProvider インスタンスを作成するときに、
setSampler(new SpanFilterSampler())
メソッドを呼び出して、カスタムサンプラーを設定します。... SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder() .setSampler(new MySampler()) // この行を追加します。 .addSpanProcessor(BatchSpanProcessor.builder(OtlpGrpcSpanExporter.builder() .setEndpoint("<endpoint>") .addHeader("Authentication", "<token>") .build()).build()) .setResource(resource) .build(); ...
アプリケーションを起動します。
Node.js アプリケーション
デモ: opentelemetry-nodejs-demo。
前提条件
アプリケーションは、Managed Service for OpenTelemetry API for JavaScript を使用してインストルメント化されます。詳細については、Managed Service for OpenTelemetry を使用して Node.js アプリケーションのトレースデータを送信する を参照してください。
方法 1: Span の作成時に Span を除外する
HttpInstrumentation を構築するときに ignoreIncomingRequestHook パラメーターを設定します。
HttpInstrumentation を構築するときに、ignoreIncomingRequestHook パラメーターを含む HttpInstrumentationConfig パラメーターを設定できます。ignoreIncomingRequestHook パラメーターを使用すると、リクエストが処理される前にアプリケーションをインストルメント化するかどうかを決定するカスタムメソッドを指定できます。カスタムメソッドは、Span が作成されないことのみを決定します。リクエストは想定どおりに処理されます。
次の例では、request.url が /api/checkHealth であるリクエストは、インストルメント化のために無視されます。
... // 置き換えるコンテンツ。 // registerInstrumentations({ // tracerProvider: provider, // instrumentations: [new HttpInstrumentation(), ExpressInstrumentation], // }); const httpInstrumentation = new HttpInstrumentation({ // ignoreIncomingRequestHook パラメーターでカスタムメソッドを指定します。 ignoreIncomingRequestHook: (request) => { // request.url が /api/checkHealth であるリクエストを無視します。 if (request.url === '/api/checkHealth') { return true; } return false; }, }); registerInstrumentations({ tracerProvider: provider, instrumentations: [httpInstrumentation, ExpressInstrumentation], }); ...
アプリケーションを起動します。
方法 2: Span のレポート時に Span を除外する
カスタムサンプラークラスを作成します。
Sampler インターフェースを実装するカスタムサンプラークラスを作成します。このインターフェースは、サンプリングルールを定義します。例:
const opentelemetry = require('@opentelemetry/api'); class SpanFilterSampler { shouldSample(spanContext, parentContext) { // ここにカスタムサンプリングロジックを実装します。 } }
NodeTracerProvider インスタンスを作成するときに、カスタムサンプラーを設定します。
... const provider = new NodeTracerProvider({ sampler: new SpanFilterSampler(), // このコード行を追加して、カスタムサンプラーを設定します。 resource: new Resource({ [SemanticResourceAttributes.HOST_NAME]: require("os").hostname(), // ホスト名 [SemanticResourceAttributes.SERVICE_NAME]: "<your-service-name>", }), }); ...