APM で不要なリソースを無視する

サービスは様々なリクエストを扱うことができますが、その中にはトレースから除外したい、またはトレースメトリクスに含めたくないものがあるかもしれません。例としては、Web アプリケーションのヘルスチェックなどが挙げられます。

次の 2 つの方法で、このようなエンドポイントをトレースせず、トレースメトリクスから除外するよう指定することができます。

: 以下のいずれかのオプションを使用してトレースをフィルタリングすると、トレースメトリクスからこれらのリクエストが削除されます。トレースメトリクスに影響を与えずに取り込み量を削減する方法については、取り込みコントロールを参照してください。

ヘルプが必要な場合は、Datadog のサポートチームまでお問合せください。

Trace Agent のコンフィギュレーションオプション

Datadog Agent 内の Trace Agent コンポーネントには、特定のトレースを除外するために「スパンタグの無視」と「リソースの無視」という 2 つのメソッドが用意されています。これらの設定によりトレースが取り込まれなかった場合、トレースメトリクスはこれらのリクエストを除外します。

特定のスパンやリソースを無視するよう Trace Agent を設定すると、この特定の Datadog Agent にトレースを送信するすべてのサービスに適用されます。アプリケーション固有の要件がある場合は、代わりにトレーサーのコンフィギュレーションメソッドを使用してください。

スパンタグに基づいて無視する

Datadog Agent 6.27.0/7.27.0 より、filter tags オプションは、指定されたスパンタグにマッチするルートスパンを持つトレースを無視します。このオプションは、この特定の Datadog Agent にトレースを送信するすべてのサービスに適用されます。フィルタータグが原因で無視されたトレースは、トレースメトリクスに含まれません。

Datadog に送信したくないトレースのセットをプログラムで特定でき、このガイドの他のオプションで要件を解決することができない場合は、カスタムスパンタグを追加してトレースを除外することを検討できます。サポートにお問い合わせいただき、この機能を継続的に拡張するためのユースケースについてご相談ください。

フィルタータグオプションでは、文字列の完全一致が必要です。正規表現により除外したい場合は、「リソースに基づいて無視する」を参照してください。

環境変数でキーと値をスペースで区切ったリストを使うことで、require または reject するスパンタグを指定することができます。

DD_APM_FILTER_TAGS_REQUIRE
指定されたスパンタグとその値が完全に一致する root スパンを持つトレースのみを収集します。このルールに一致しないトレースは破棄されます。例えば、DD_APM_FILTER_TAGS_REQUIRE="key1:value1 key2:value2" です。Datadog Agent 7.49 以降では、正規表現は DD_APM_FILTER_TAGS_REGEX_REQUIRE で指定できます。
DD_APM_FILTER_TAGS_REJECT
指定されたスパンタグとその値が完全に一致する root スパンを持つトレースを拒否します。このルールに一致するトレースは破棄されます。例えば、DD_APM_FILTER_TAGS_REJECT="key1:value1 key2:value2" です。Datadog Agent 7.49 以降では、正規表現は DD_APM_FILTER_TAGS_REGEX_REJECT で指定できます。

代わりに、Agent 構成でカンマ区切りのリストで設定することもできます。

datadog.yaml

apm_config:
  filter_tags:
    require: ["db:sql", "db.instance:mysql"]
    reject: ["outcome:success", "key2:value2"]

たとえば、http.url がこのエンドポイントに一致するヘルスチェックを無視するには次のようにします。

datadog.yaml

apm_config:
  filter_tags:
    reject: ["http.url:http://localhost:5050/healthcheck"]

Datadog Operator

datadog-agent.yaml

apiVersion: datadoghq.com/v2alpha1
kind: DatadogAgent
metadata:
  name: datadog
spec:
  override:
    nodeAgent:
      containers:
        trace-agent:
          env:
            - name: DD_APM_FILTER_TAGS_REJECT
              value: tag_key1:tag_val2 tag_key2:tag_val2

変更後、以下のコマンドを使用して新しい構成を適用します。

kubectl apply -n $DD_NAMESPACE -f datadog-agent.yaml

Helm

datadog-values.yaml

agents:
  containers:
    traceAgent:
      env:
        - name: DD_APM_FILTER_TAGS_REJECT
          value: tag_key1:tag_val2 tag_key2:tag_val2

After making your changes, upgrade your Datadog Helm chart using the following command:

helm upgrade -f datadog-values.yaml <RELEASE NAME> datadog/datadog

この方法でトレースをフィルターすると、トレースメトリクスからこれらのリクエストが削除されます。トレースメトリクスに影響を与えずに取り込みを減らす方法については、Ingestion Controls を参照してください。

バックエンドでは、Datadog は取り込み後に以下のスパンタグを作成し、スパンに追加します。これらのタグは、Datadog Agent レベルでトレースをドロップするために使用することはできません。

名前説明
http.path_grouphttp.url タグからの完全な URL パス。
http.url_details.hosthttp.url タグのホスト名部分。
http.url_details.pathHTTP リクエスト行で渡された完全なリクエスト対象、またはそれに相当するもの。
http.url_details.schemehttp.url タグからのリクエストスキーム。
http.url_details.queryStringhttp.url タグからのクエリ文字列部分。
http.url_details.porthttp.url タグからの HTTP ポート。
http.useragent_details.os.familyUser-Agent によって報告された OS ファミリー。
http.useragent_details.browser.familyUser-Agent によって報告されたブラウザファミリー。
http.useragent_details.device.familyUser-Agent によって報告されたデバイスファミリー。
: 2022 年 10 月 1 日以降、Datadog バックエンドは、取り込まれたすべてのスパンについてトレーサー間でスパンタグのセマンティクスを適用するためにリマッピングを適用します。Datadog Agent レベルでタグに基づいてスパンをドロップしたい場合、Remap from 列でタグを使用します。

ネットワーク通信

名前Remap from
network.host.iptcp.local.address - Node.js
network.destination.ipout.host - すべての言語
network.destination.portgrpc.port - Python
tcp.remote.port - Node.js
out.port - すべての言語

HTTP リクエスト

名前Remap from
http.routeaspnet_core.route - .NET
aspnet.route - .NET
laravel.route - PHP
symfony.route - PHP
http.useragentuser_agent - Java, C++
http.url_details.queryStringhttp.query.string - Python

データベース

名前Remap from
db.systemdb.type - Java、Python、Node.js、Go
active_record.db.vendor - Ruby
sequel.db.vendor - Ruby
db.instancemongodb.db - Python
sql.db - Python
db.name - すべての言語
db.statementcassandra.query - Go
consul.command - Python
memcached.query - Python
mongodb.query - Python、.NET、Go
redis.command - Python
redis.raw_command - Python
sql.query - Python、PHP、Node.js、Java
db.row_countcassandra.row_count - Python
db.rowcount - Python、PHP
mongodb.rows - Python
sql.rows - Python
db.cassandra.clustercassandra.cluster - Python、Go
db.cassandra.consistency_levelcassandra.consistency_level - Python、Go
db.cassandra.tablecassandra.keyspace - Python、Go
db.redis.database_indexdb.redis.dbIndex - Java
out.redis_db - Python、Ruby
db.mongodb.collectionmongodb.collection - Python、.NET、Ruby、PHP
db.cosmosdb.containercosmosdb.container - .NET

メッセージキュー

名前Remap from
messaging.destinationamqp.destination - Node.js
amqp.queue - .NET
msmq.queue.path - .NET
aws.queue.name - .NET
messaging.urlaws.queue.url - .NET、Java
messaging.message_idserver_id - Go
messaging.message_payload_sizemessage.size - .NET、Java
messaging.operationamqp.command - .NET
msmq.command - .NET
messaging.rabbitmq.routing_keyamqp.routing_key - Java
amqp.routingKey - Nodes.js
messaging.rabbitmq.delivery_modemessaging.rabbitmq.exchange - .NET
messaging.msmq.message.transactionalmsmq.message.transactional - .NET
messaging.msmq.queue.transactionalmsmq.queue.transactional - .NET
messaging.kafka.consumer_groupkafka.group - Java
messaging.kafka.tombstonekafka.tombstone - .NET
tombstone - Java
messaging.kafka.partitionkafka.partition - .NET
partition - Node.js、Go、Java
messaging.kafka.offsetkafka.offset - .NET
messaging.msmq.message.transactionalmsmq.message.transactional - .NET

リモートプロシージャコール

名前Remap from
rpc.servicegrpc.method.service - Python、.NET
rpc.methodgrpc.method.name - Python、.NET、Go
rpc.grpc.packagegrpc.method.package - Python、.NET、Go
rpc.grpc.status_codegrpc.code - Go
status.code - Python、.NET、Node.js
grpc.status.code - Python、.NET、Node.js
rpc.grpc.kindgrpc.method.kind - Python、Node.js、Go、.NET
rpc.grpc.pathrpc.grpc.path - Python、Node.js、Go、.NET
rpc.grpc.request.metadata.*grpc.request.metadata.* - Python、Node.js
rpc.grpc.request.metadata - Go
rpc.grpc.response.metadata.*grpc.response.metadata.* - Python、Node.js

エラー

名前Remap from
error.messageerror.msg - すべての言語

リソースに基づいて無視する

ignore resources オプションを使用すると、トレースのグローバルルートスパンが特定の基準に一致する場合にリソースを除外することができます。リソースを収集から除外を参照してください。このオプションは、この特定の Datadog Agent にトレースを送信するすべてのサービスに適用されます。ignore resources により無視されたトレースは、トレースメトリクスに含まれません。

無視するリソースは、Agent のコンフィギュレーションファイル、datadog.yaml、または DD_APM_IGNORE_RESOURCES 環境変数で指定します。以下の例を参照してください。

datadog.yaml

apm_config:
## @param ignore_resources - list of strings - optional
## 正規表現のリストを提供し、リソース名に基づいて特定のトレースを除外することができます。
## すべての入力項目は二重引用符で囲み、カンマ区切りにする必要があります。

  ignore_resources: ["(GET|POST) /healthcheck","API::NotesController#index"]

:

  • Trace Agent が許容する正規表現の構文は、Go の regexp によって評価されます。
  • デプロイ戦略によっては、特殊文字をエスケープして正規表現を調整しなければならない場合もあります。
  • Kubernetes で専用コンテナを使用している場合は、ignore resource オプションの環境変数が trace-agent コンテナに適用されていることを確認してください。

トレースを必要としない /api/healthcheck の呼び出しを含むトレースを考えてみましょう。

トレーサーに無視させたいリソースのフレームグラフ

グローバルルートスパンのリソース名に注意してください。

  • オペレーション名: rack.request
  • リソース名: Api::HealthchecksController#index
  • Http.url: /api/healthcheck

ignore resource オプションを正しく使用するためには、記述された正規表現ルールがリソース名 Api::HealthchecksController#index に一致している必要があります。いくつかの正規表現オプションが利用できますが、このリソースからのトレースをそのままフィルタリングする場合は `Api::HealthchecksController#index{TX-PL-LABEL}#x60; を使用するのが良いでしょう。

デプロイ方法に応じて、構文は少しずつ異なります。

datadog.yaml

apm_config:
  ignore_resources: Api::HealthchecksController#index$

複数の値の場合

apm_config:
  ignore_resources: ["value1","Api::HealthchecksController#index$"]

Datadog Agent コンテナの環境変数のリストに、以下の例のようなパターンで DD_APM_IGNORE_RESOURCES を追加します。Docker Compose には、独自の変数の置換機能があり、$ などの特殊文字を使用する場合に考慮する必要があります。

    environment:
      // その他の Datadog Agent の環境変数
      - DD_APM_IGNORE_RESOURCES=Api::HealthchecksController#index$$

複数の値の場合

    environment:
      // その他の Datadog Agent の環境変数
      - DD_APM_IGNORE_RESOURCES="value1","Api::HealthchecksController#index$$"

Datadog Agent をスピンアップするための docker run コマンドに、DD_APM_IGNORE_RESOURCES を追加します。

docker run -d --name datadog-agent \
              --cgroupns host \
              --pid host \
              -v /var/run/docker.sock:/var/run/docker.sock:ro \
              -v /proc/:/host/proc/:ro \
              -v /sys/fs/cgroup/:/host/sys/fs/cgroup:ro \
              -e DD_API_KEY=<> \
              -e DD_APM_IGNORE_RESOURCES="Api::HealthchecksController#index$" \
              -e DD_APM_ENABLED=true \
              -e DD_APM_NON_LOCAL_TRAFFIC=true \
              gcr.io/datadoghq/agent:latest

複数の値の場合

              -e DD_APM_IGNORE_RESOURCES=["value1","Api::HealthchecksController#index$"] \

trace-agent 専用コンテナに、環境変数 DD_APM_IGNORE_RESOURCES を追加します。

    - name: trace-agent
        image: "gcr.io/datadoghq/agent:latest"
        imagePullPolicy: IfNotPresent
        command: ["trace-agent", "-config=/etc/datadog-agent/datadog.yaml"]
        resources: {}
        ports:
        - containerPort: 8126
          hostPort: 8126
          name: traceport
          protocol: TCP
        env:
        - name: DD_API_KEY
          valueFrom:
            secretKeyRef:
              name: "datadog-secret"
              key: api-key
        - name: DD_KUBERNETES_KUBELET_HOST
          valueFrom:
            fieldRef:
              fieldPath: status.hostIP
        - name: KUBERNETES
          value: "yes"
        - name: DOCKER_HOST
          value: unix:///host/var/run/docker.sock
        - name: DD_LOG_LEVEL
          value: "INFO"
        - name: DD_APM_ENABLED
          value: "true"
        - name: DD_APM_NON_LOCAL_TRAFFIC
          value: "true"
        - name: DD_APM_RECEIVER_PORT
          value: "8126"
        - name: DD_KUBELET_TLS_VERIFY
          value: "false"
        - name: DD_APM_IGNORE_RESOURCES
          value: "Api::HealthchecksController#index$"

複数の値の場合

        - name: DD_APM_IGNORE_RESOURCES
          value: '"value1","Api::HealthchecksController#index$"'

values.yaml ファイルの traceAgent セクションで、env セクションに DD_APM_IGNORE_RESOURCES を追加し、通常通りに Helm をスピンアップします。

values.yaml

    traceAgent:
      # agents.containers.traceAgent.env -- trace-agent コンテナ向けの追加の環境変数
      env:
        - name: DD_APM_IGNORE_RESOURCES
          value: Api::HealthchecksController#index$

複数の値の場合

        - name: DD_APM_IGNORE_RESOURCES
          value: value1, Api::HealthchecksController#index$

代わりに、helm install コマンドで agents.containers.traceAgent.env を設定することもできます。 

helm install dd-agent -f values.yaml \
  --set datadog.apiKeyExistingSecret="datadog-secret" \
  --set agents.containers.traceAgent.env[0].name=DD_APM_IGNORE_RESOURCES, \
    agents.containers.traceAgent.env[0].value="Api::HealthchecksController#index$" \
  datadog/datadog

Amazon ECS を使用している場合 (例えば、EC2 上で)、Datadog Agent のコンテナ定義に環境変数 DD_APM_IGNORE_RESOURCES を追加し、その値が次のような JSON に評価されるようにします。

    "environment": [
    // Datadog Agent 向けのその他の環境変数
        {
          "name": "DD_APM_IGNORE_RESOURCES",
          "value": "Api::HealthchecksController#index$"
        }
     ]
: このようにトレースをフィルタリングすると、トレースメトリクスからこれらのリクエストが削除されます。トレースメトリクスに影響を与えずに取り込み量を削減する方法については、取り込みコントロールを参照してください。

トレーサーのコンフィギュレーションオプション

言語固有のトレーサーの中には、Datadog Agent に送信する前にスパンを修正するオプションがあります。アプリケーション固有の要件があり、以下の言語を使用している場合にはこのオプションを使用してください。

重要: リクエストが分散されたトレースに関連付けられている場合、これらのフィルタリングルールを通じて部分的に除外すると、結果として得られるトレースのサンプリングが不正確になる場合があります。

Ruby トレーサーには、特定の条件を満たすトレースを除去する後処理パイプラインがあります。詳しい情報や例はトレースの後処理を参照してください。

たとえば、リソース名が Api::HealthchecksController#index である場合、そのリソース名を含むトレースを除去するために Datadog::Tracing::Pipeline::SpanFilter クラスを使用します。このフィルターは、スパンオブジェクトで利用可能な他のメタデータを照合するためにも使用できます。

Datadog::Tracing.before_flush(
   Datadog::Tracing::Pipeline::SpanFilter.new { |span| span.resource =~ /Api::HealthchecksController#index/ }
)

Pythonトレーサーには、特定のエンドポイントからのトレースを削除するように設定できる FilterRequestsOnUrl フィルターがあります。また、カスタムフィルターを書くこともできます。詳細はトレースフィルター を参照してください。

ルートスパンの http.url スパンタグの値が http://<domain>/healthcheck の場合の例を考えます。healthcheck で終わるすべてのエンドポイントに一致するよう、次の正規表現を使用します。

from ddtrace import tracer
from ddtrace.filters import FilterRequestsOnUrl
tracer.configure(settings={
    'FILTERS': [
        FilterRequestsOnUrl(r'http://.*/healthcheck$'),
    ],
})

Http プラグインにブロックリストを設定します。ブロックリストが一致する対象については API ドキュメントを参照してください。例えば、受信 Http リクエストは URL パスに一致するため、トレースの http.url スパンタグが http://<domain>/healthcheck であれば、healthcheck URL に一致するルールを記述します。

const tracer = require('dd-trace').init();
tracer.use('http', {
  // 受信 http リクエストはパスに一致する
  server: {
    blocklist: ['/healthcheck']
  },
  // 発信 http リクエストは完全な URL で一致する
  client: {
    blocklist: ['https://telemetry.example.org/api/v1/record']
  }
})

//import http
: インテグレーションのためのトレーサーコンフィギュレーションは、インスツルメントされたモジュールがインポートされる前に行う必要があります。

Java トレーサーには、カスタム TraceInterceptor で特定のスパンをフィルタリングするオプションがあります。トレーサーの拡張を参照してください。

例えば、リソース名が GET /healthcheck であれば、このリソース名を含むトレースを無視するトレースインターセプターを記述します。ユースケースに合わせてロジックを調整してください。

public class GreetingController {
   static {
       // クラスの static ブロックで複数回の初期化を回避。
       GlobalTracer.get().addTraceInterceptor(new TraceInterceptor() {
           @Override
           public Collection<? extends MutableSpan> onTraceComplete(Collection<? extends MutableSpan> trace) {
               for (MutableSpan span : trace) {
                   if ("GET /healthcheck".contentEquals(span.getResourceName())) {
                       return Collections.emptyList();
                   }
               }
               return trace;
           }
           @Override
           public int priority() {
               return 200;  // Some unique number
           }
       });
   }
}
: このようにトレースをフィルタリングすると、トレースメトリクスからこれらのリクエストが削除されます。トレースメトリクスに影響を与えずに取り込み量を削減する方法については、取り込みコントロールを参照してください。