APM에서 원하지 않는 리소스 무시하기

서비스에서는 다양한 요청을 처리합니다. 이 중에는 추적하거나 트레이스 메트릭에 포함될 필요가 없는 것도 있습니다. 예를 들어 웹 애플리케이션 상태 점검은 포함될 필요가 없습니다.

이와 같은 엔드포인트를 추적하지 않고 트레이스 메트릭에서 제외하는 방법에는 두 가지가 있습니다.

참고: 다음 옵션으로 트레이스를 필터링하면 트레이스 메트릭에서 이 해당 요청을 삭제합니다. 트레이스 메트릭에 영향을 주지 않고 수집 데이터를 줄이는 방법을 알아보려면 수집 통제를 참고하세요.

도움이 필요하면 Datadog 지원팀에 문의하세요.

트레이스 에이전트 구성 옵션

트레이스 에이전트는 Datadog 에이전트의 구성 요소이며, 두 가지 방법으로 특정 트레이스가 수집되는 것을 방지할 수 있습니다. 스팬 태그를 무시하거나 리소스를 무시하는 방법입니다. 이와 같은 설정으로 트레이스가 수집되지 않으면 트레이스 메트릭에서 이 요청을 제외합니다.

트레이스 에이전트에서 특정 스팬이나 리소스를 무시하도록 구성하면 이 특정 Datadog 에이전트로 트레이스를 전송하는 서비스 전체에 적용됩니다. 애플리케이션 지정 필수 조건이 있을 경우에는 대신 트레이서 구성 방법을 사용하세요.

스팬 태그 기반 무시

Datadog 에이전트 6.27.0/7.27.0부터 태그 필터 옵션을 사용해 특정 스팬 태그와 일치하는 루트 스팬의 트레이스를 제외할 수 있습니다. 이 옵션은 특정 Datadog 에이전트에 트레이스를 보내는 모든 서비스에 적용됩니다. 필터 태그 때문에 제외된 트레이스는 트레이스 메트릭에 포함되지 않습니다.

Datadog에 보내고 싶지 않은 트레이스 세트를 프로그램적인 방법으로 파악할 수 있고, 이 가이드에 안내된 내용으로 필요한 조건을 충족할 수 없을 경우, 커스텀 스팬 태그를 추가해 트레이스를 제외하는 것을 권고합니다. 사례에 맞는 방법이 무엇인지 논의하고 Datadog에서 이 기능을 계속해서 확장할 수 있도록 지원팀에 문의해 주시면 감사하겠습니다.

필터 태그 옵션을 사용하려면 문자열이 정확하게 일치해야 합니다. regex 무시 방법이 필요한 사용 사례일 경우에는 리소스 기반 무시 방법을 사용하세요

환경 변수에서 띄어쓰기로 구분된 키와 값의 목록을 사용하여 포함하거나 거부할 스팬 태그를 지정할 수 있습니다.

DD_APM_FILTER_TAGS_REQUIRE
특정 스팬 태그와 값에 완전히 일치하는 루트 스팬 트레이스만 수집합니다. 이 규칙과 일치하지 않으면 트레이스가 제외됩니다(예: DD_APM_FILTER_TAGS_REQUIRE="key1:value1 key2:value2"). Datadog 에이전트 7.49+의 경우 정규식을 DD_APM_FILTER_TAGS_REGEX_REQUIRE로 제공할 수 있습니다.
DD_APM_FILTER_TAGS_REJECT
특정 스팬 태그 및 값과 완전히 일치하는 루트 스팬 트레이스를 거부합니다. 이 규칙과 일치하면 트레이스가 제외됩니다(예: DD_APM_FILTER_TAGS_REJECT="key1:value1 key2:value2"). Datadog 에이전트 7.49+의 경우 정규식을 DD_APM_FILTER_TAGS_REGEX_REJECT로 제공할 수 있습니다.

또는 에이전트 구성에서 쉼표로 구분된 목록으로 설정할 수 있습니다.

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 연산자

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

이 방법으로 트레이스를 필터링하면 트레이스 메트릭에서 요청을 제거합니다. 트레이스 메트릭에 영향을 주지 않으면서 데이터 수집을 줄이는 방법을 알아보려면 수집 통제를 참고하세요.

Datadog는 데이터 수집 후 백엔드에서 다음 스팬 태그를 생성합니다. 이 태그를 사용해 Datadog 에이전트 수준에서 트레이스를 제외할 수 없습니다.

이름설명
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 에이전트 수준에서 태그 기반 스팬을 모두 제외하고 싶으면 리맵 열에 있는 태그를 사용하세요.

네트워크 통신

이름리맵
network.host.iptcp.local.address - Node.js
network.destination.ipout.host - 모든 언어
network.destination.portgrpc.port - Python
tcp.remote.port - Node.js
out.port - 모든 언어

HTTP 요청

이름리맵
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

데이터베이스

이름리맵
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

메시지 대기열

이름리맵
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

원격 프로시저 호출

이름리맵
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

오류

이름리맵
error.messageerror.msg - 모든 언어

리소스 기반 무시

리소스 무시 옵션의 경우 트레이스의 전역 루트 스팬이 특정 조건을 충족할 경우 무시합니다. [수집에서 특정 리소스 제외5를 참고하세요. 이 옵션은 특정 Datadog 에이전트에 트레이스를 보내는 모든 서비스에 적용됩니다. 리소스 무시 때문에 제외된 트레이스는 트레이스 메트릭에 포함되지 않습니다.

에이전트 구성 파일 datadog.yaml에서 무시할 리소스를 지정하거나 DD_APM_IGNORE_RESOURCES 환경 변수를 사용할 수 있습니다. 다음 예시를 참고하세요.

datadog.yaml

apm_config:
## @param ignore_resources - 문자열 목록 - 선택 사항
## 리소스 이름을 기반으로 특정 트레이스를 제외할 정규식을 제공할 수 있습니다.
## 모든 항목에 큰 따옴표를 사용해야 하며 쉼표로 구분해야 합니다.

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

참고:

  • 트레이스 에이전트가 수용하는 regex 구문은 Go regexp로 평가됩니다.
  • 배포 전략에 따라 특수문자를 이스케이프하여 regex를 조정해야 할 수 있습니다.
  • Kubernetes로 전용 컨테이너를 사용하는 경우 리소스 무시 옵션으로 사용하는 환경 변수가 trace-agent 컨테이너에 적용되는지 다시 확인하세요.

예시

트레이스에 포함하고 싶지 않은 /api/healthcheck 호출이 있는 트레이스 예시를 보겠습니다.

트레이서가 무시하도록 하고자 하는 리소스의 플레임 그래프

전역 루트 스팬의 리로스 이름을 기입해 두세요

  • 작업 이름: rack.request
  • 리소스 이름: Api::HealthchecksController#index
  • Http.url: /api/healthcheck

리소스 무시 옵션을 바르게 사용하려면 regex 규칙을 쓸 때 리소스 이름 Api::HealthchecksController#index와 일치하도록 써야 합니다. 사용할 수 있는 regex 옵션이 여럿 있으나 이 리소스를 정확하게 필터링하여 제외하려면 Api::HealthchecksController#index$와 같은 regex를 사용하는 것이 좋습니다.

배포 방법에 따라 구문은 조금 다를 수 있습니다.

datadog.yaml

apm_config:
  ignore_resources: Api::HealthchecksController#index$

값이 여럿일 경우:

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

Datadog 에이전트 컨테이너의 환경 변수 목록에 아래 패턴으로 DD_APM_IGNORE_RESOURCES를 추가하세요. Docker Compose에는 특수문자 $ 등을 사용할 경우에 사용할 자체 변수 대체가 있습니다.

    environment:
      // 기타 Datadog 에이전트 환경 변수
      - DD_APM_IGNORE_RESOURCES=Api::HealthchecksController#index$$

값이 여럿일 경우:

    environment:
      // 기타 Datadog 에이전트 환경 변수
      - DD_APM_IGNORE_RESOURCES="value1","Api::HealthchecksController#index$$"

Datadog 에이전트를 실행하는 docker 실행 명령에 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 -- Additional environment variables for the trace-agent container
      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 에이전트 컨테이너 정의에서 환경 변수 DD_APM_IGNORE_RESOURCES와 값을 추가하여 JSON에서 다음과 같은 결과가 나오도록 하세요.

    "environment": [
    // other environment variables for the Datadog Agent
        {
          "name": "DD_APM_IGNORE_RESOURCES",
          "value": "Api::HealthchecksController#index$"
        }
     ]
참고: 이 방법으로 트레이스를 필터링하면 트레이스 메트릭에서 이 해당 요청을 삭제합니다. 트레이스 메트릭에 영향을 주지 않고 수집 데이터를 줄이는 방법을 알아보려면 수집 통제를 참고하세요.

트레이서 구성 옵션

일부 언어 특정 트레이서에서는 Datadog 에이전트로 전송하기 전에 스팬을 수정할 수 있습니다. 애플리케이션에서 필요한 특정 요구 사항 있고 아래 언어를 사용하는 경우 이 방법을 사용할 수 있습니다.

중요: 요청이 분산된 트레이스와 연결되어 있을 경우, 이 필터링 규칙으로 트레이스 일부가 제외될 경우 결과 트레이스에 샘플링 부정확성이 있을 수 있으니 유의하세요.

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이 있다고 가정해 봅시다. 다음 regex를 사용해 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', {
  // incoming http requests match on the path
  server: {
    blocklist: ['/healthcheck']
  },
  // outgoing http requests match on a full URL
  client: {
    blocklist: ['https://telemetry.example.org/api/v1/record']
  }
})

//import http
참고: 계측된 모듈을 가져오기 전에 통합 트레이서 구성을 해야 합니다.

Java 트레이서에는 커스텀 TraceInterceptor 옵션이 있어 스팬을 필터링할 수 있습니다. 트레이서 확장을 참고하세요.

예를 들어 리소스 이름이 GET /healthcheck이면 이 리소스 이름을 제외하는 트레이스 인터셉터를 쓰세요. 내 사용 사례에 맞게 로직을 바꾸세요.

public class GreetingController {
   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
           }
       });
   }
}
참고: 이 방법으로 트레이스를 필터링하면 트레이스 메트릭에서 이 해당 요청을 삭제합니다. 트레이스 메트릭에 영향을 주지 않고 수집 데이터를 줄이는 방법을 알아보려면 수집 통제를 참고하세요.