すべてのプロダクト
Search
ドキュメントセンター

Application Real-Time Monitoring Service:カスタムサンプラーによる特定スパンのフィルタリング

最終更新日:Mar 11, 2026

ヘルスチェック、readiness プローブ、その他の定期的なリクエストは、トレースにノイズを加え、コストを増加させるスパンを生成します。カスタムの OpenTelemetry サンプラーを使用して、これらのスパンがアプリケーションから送信される前にドロップします。

OpenTelemetry 向けマネージドサービスは、Java および Node.js アプリケーションのスパンフィルタリングをサポートしています。

仕組み

OpenTelemetry は、サンプラーを使用して各スパンをレコードおよびエクスポートするかどうかを決定します。カスタムサンプラーは、スパン名や HTTP ターゲットパスなどのスパンのプロパティを検査し、次の 2 つの決定のいずれかを返します:

  • DROP (SamplingDecision.DROP) -- スパンは破棄されます。レコードもエクスポートもされません。

  • RECORD_AND_SAMPLE (SamplingDecision.RECORD_AND_SAMPLE) -- スパンは保持され、通常どおりレコードおよびエクスポートされます。

不要なスパンに一致し、DROP を返すサンプラーを作成することで、ソースでノイズを除去します。

メソッドの選択

適切なアプローチは、インストルメンテーションのセットアップとプログラミング言語によって異なります。

Java

メソッド使用する状況必要なコード変更
エージェント拡張OpenTelemetry Java エージェントによる自動インストルメンテーション。アプリケーションコードの変更は不要です別の JAR をビルド
SDK サンプラーOpenTelemetry SDK for Java による手動インストルメンテーションサンプラークラスをアプリケーションコードに追加

Node.js

メソッド使用する状況必要なコード変更
作成時にフィルタリング特定の HTTP リクエストに対してスパンが作成されないようにするHttpInstrumentationignoreIncomingRequestHook
エクスポート時にフィルタリングスパン作成後に評価される属性に基づいてスパンをドロップカスタムサンプラークラスを実装

Java

OpenTelemetry Java エージェント用のエージェント拡張の作成

Java エージェント拡張としてカスタムサンプラーをビルドします。このアプローチにより、フィルタリングロジックをアプリケーションコードから分離できます。

前提条件

開始する前に、以下を確認してください:

ステップ 1: Maven プロジェクトの作成

エージェント拡張をビルドするための新しい Maven プロジェクトを作成します。

ステップ 2: 依存関係の追加

次の依存関係を pom.xml ファイルに追加します。

重要

すべての OpenTelemetry 依存関係は、使用する OpenTelemetry Java エージェントのバージョンと一致する必要があります。次の例では、バージョン 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>
  <!--スコープを 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>

ステップ 3: サンプラーの実装

io.opentelemetry.sdk.trace.samplers.Sampler インターフェイスを実装するクラスを作成します。shouldSample メソッドでフィルタリングルールを定義し、getDescription からサンプラー名を返します。

  • shouldSample -- 各スパンを評価し、破棄するスパンには SamplingResult.create(SamplingDecision.DROP) を、保持するスパンには SamplingResult.create(SamplingDecision.RECORD_AND_SAMPLE) を返します。

  • getDescription -- サンプラー名を返します。

次の例では、spanName1 または spanName2 という名前のスパン、および http.target 属性が /api/checkHealth または /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 {

    // ドロップするスパン名
    private static List<String> EXCLUDED_SPAN_NAMES = Collections.unmodifiableList(
        Arrays.asList("spanName1", "spanName2")
    );

    // ドロップする HTTP ターゲットパス
    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";
    }
}

ステップ 4: サンプラープロバイダーの実装

io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSamplerProvider を実装するクラスを作成します。このプロバイダーは、Java エージェントの自動構成メカニズムにサンプラーを登録します。

  • createSampler -- サンプラーのインスタンスを返します。

  • getName -- サンプラー名を返します。Java エージェントはこの名前を使用してサンプラーを特定します。

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";
    }
}

ステップ 5: 拡張 JAR のビルド

プロジェクトを JAR ファイルにパッケージ化します:

mvn clean package

JAR ファイルは target ディレクトリに生成されます。

ステップ 6: 起動時に拡張をロード

アプリケーションの起動時にカスタムサンプラーを指定します。JVM システムプロパティまたは環境変数のいずれかを使用します。

オプション A: JVM システムプロパティ

-Dotel.traces.sampler=<your-sampler-name> を JVM 起動パラメーターに追加します。<your-sampler-name>getName メソッドから返される値に置き換えます。

完全な起動コマンド:

java -javaagent:path/to/opentelemetry-javaagent.jar \
  -Dotel.javaagent.extensions=path/to/opentelemetry-java-agent-extension.jar \
  -Dotel.traces.sampler=<your-sampler-name> \
  -Dotel.exporter.otlp.headers=Authentication=<token> \
  -Dotel.exporter.otlp.endpoint=<endpoint> \
  -Dotel.metrics.exporter=none \
  -jar yourapp.jar

オプション B: 環境変数

OTEL_TRACES_SAMPLER 環境変数をサンプラー名に設定します:

起動コマンドの完全な例を表示するには、クリックしてください

export OTEL_JAVAAGENT_EXTENSIONS="path/to/opentelemetry-java-agent-extension.jar"
export OTEL_TRACES_SAMPLER="<your-sampler-name>"
export OTEL_EXPORTER_OTLP_HEADERS="Authentication=<token>"
export OTEL_EXPORTER_OTLP_ENDPOINT="<endpoint>"
export OTEL_METRICS_EXPORTER="none"

java -javaagent:path/to/opentelemetry-javaagent.jar \
  -jar yourapp.jar

次のプレースホルダーを実際の値に置き換えてください:

プレースホルダー説明
<your-sampler-name>getName
<token>OTLP エンドポイントの認証トークン
<endpoint>OTLP エクスポーターのエンドポイント URL

OpenTelemetry SDK for Java へのカスタムサンプラーの登録

手動でインストルメンテーションを行うアプリケーションの場合は、サンプラーを直接アプリケーションコードに追加します。

前提条件

開始する前に、以下を確認してください:

ステップ 1: サンプラークラスの作成

SpanFilterSampler クラスを作成し、Sampler インターフェイスを実装します。実装は、「ステップ 3: サンプラーの実装」のエージェント拡張サンプラーと同じです。ドロップしたいスパンに合わせて EXCLUDED_SPAN_NAMES および EXCLUDED_HTTP_REQUEST_TARGETS リストを調整します。

ステップ 2: SdkTracerProvider へのサンプラーの登録

SdkTracerProvider インスタンスをビルドする際に .setSampler(new SpanFilterSampler()) を呼び出します:

SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
    .setSampler(new SpanFilterSampler())  // カスタムサンプラーの登録
    .addSpanProcessor(BatchSpanProcessor.builder(OtlpGrpcSpanExporter.builder()
        .setEndpoint("<endpoint>")
        .addHeader("Authentication", "<token>")
        .build()).build())
    .setResource(resource)
    .build();

ステップ 3: アプリケーションの再起動

アプリケーションを再起動します。サンプラーはすべての新しいスパンを評価し、フィルターのルールに一致するものをドロップします。


Node.js

デモプロジェクト: opentelemetry-nodejs-demo

前提条件

開始する前に、以下を確認してください:

作成時のスパンのフィルタリング

HttpInstrumentationignoreIncomingRequestHook を構成することで、特定の HTTP リクエストがスパンを生成しないようにします。このフックはリクエスト処理の前に実行され、スパンが作成されるかどうかのみを制御します。リクエスト自体は通常どおり処理されます。

次の例では、/api/checkHealth へのリクエストのスパン作成をスキップします:

const httpInstrumentation = new HttpInstrumentation({
  ignoreIncomingRequestHook: (request) => {
    // ヘルスチェックリクエストのスパン作成をスキップ
    if (request.url === '/api/checkHealth') {
      return true;
    }
    return false;
  },
});

registerInstrumentations({
  tracerProvider: provider,
  instrumentations: [httpInstrumentation, ExpressInstrumentation],
});

インストルメンテーションの構成を更新した後、アプリケーションを起動します。

エクスポート時のスパンのフィルタリング

カスタムサンプラーを実装することで、作成後に属性に基づいてスパンをドロップします。

ステップ 1: サンプラークラスの作成

Sampler インターフェイスを実装するクラスを作成します。shouldSample でフィルタリングロジックを定義します:

const opentelemetry = require('@opentelemetry/api');

class SpanFilterSampler {
  shouldSample(spanContext, parentContext) {
    // ここにカスタムサンプリングロジックを実装します。
  }
}

ステップ 2: NodeTracerProvider へのサンプラーの登録

サンプラーインスタンスを NodeTracerProvider コンストラクターに渡します:

const provider = new NodeTracerProvider({
  sampler: new SpanFilterSampler(),  // カスタムサンプラーの登録
  resource: new Resource({
    [SemanticResourceAttributes.HOST_NAME]: require("os").hostname(),
    [SemanticResourceAttributes.SERVICE_NAME]: "<your-service-name>",
  }),
});

<your-service-name> を、my-node-app のように、ご利用のサービス名に置き換えます。

プロバイダーの構成を更新した後、アプリケーションを起動します。


フィルタリングが機能することの確認

カスタムサンプラーを構成してデプロイした後、スパンが正しくフィルタリングされていることを確認します:

  1. フィルターのルールに一致するトラフィックを生成します。たとえば、/api/checkHealth やその他のフィルタリングされたエンドポイントにリクエストを送信します。

  2. OpenTelemetry 向けマネージドサービスのコンソールを開きます。フィルタリングされたスパンは、トレースに表示されなくなります。

  3. フィルタリング前後のスパン数を比較します。フィルタリングされたエンドポイントのスパンボリュームが減少していれば、サンプラーが機能していることが確認できます。

フィルタリングされたスパンがまだ表示される場合は、以下を確認してください:

現象考えられる原因解決策
スパンがまだエクスポートされるサンプラーが登録されていないOTEL_TRACES_SAMPLER または -Dotel.traces.sampler がサンプラー名に設定されていることを確認します
起動時にサンプラーが見つからないエラー名前の不一致プロバイダーの getName() が、起動パラメーターで使用されているのと同じ名前を返すことを確認します
拡張 JAR がロードされないパスが正しくないOTEL_JAVAAGENT_EXTENSIONS または -Dotel.javaagent.extensions のパスが正しい JAR ファイルを指していることを確認します
誤ったスパンがフィルタリングされるフィルターのルールの論理エラーshouldSample の条件を確認し、スパン名と属性値が期待どおりであることを確認します