🍮

Otel にてヘルスチェックを Trace の sample 対象から外す

2024/04/18に公開

はじめに

OpenTelemetry Collector (以下, Otel Collector) で Trace を送信する場合、特に何も設定しないと、ヘルスチェックのためのリクエストもバックエンドに送信されてしまいます。基本的にヘルスチェックのトレースは不要ですし、AP 数が多かったり、ヘルスチェックの間隔が短かったりする場合、ダッシュボードがごちゃごちゃして大変です。また、Cloud Trace quota において、BatchWriteSpans の上限は 4,800 per 60 seconds であり、(Batchサイズ等の設定にもよりますが)AP数が多い・高RPS(10000rpsなど)・AP間でSpan連携等しておらずAPそれぞれがTraceを送信するような場合、簡単に超え得る値かなと思います。そのため、今回は Tail Sampling Processor を使って、ヘルスチェックを Trace 送信対象から除外します。

設定

基本的に Google Cloud 向け Otel Collector カスタムビルドについては 公式のサンプル があるのでこれを利用します。

ここでは builder-config.yaml (otel-collector に含める components の設定) と otel-config.yaml ( otel collector の設定ファイル)の設定例を記載します。コンポーネントについて,今回特に Pub/Sub, Cloud Spanner は利用しないので省いています。
また、APは Spring Boot でヘルスチェックに actuator (liveness, readiness) を利用することとしています。(参考: Kubernetes Probes) Otel については java-agent で自動計装としています。

builder-config.yaml
dist:
  name: otelcol-custom
  output_path: ./bin

receivers:
  - import: go.opentelemetry.io/collector/receiver/otlpreceiver
    gomod: go.opentelemetry.io/collector/receiver/otlpreceiver v0.96.0

processors:
  - import: github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor
    gomod: github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor v0.96.0
  - import: github.com/open-telemetry/opentelemetry-collector-contrib/processor/redactionprocessor
    gomod: github.com/open-telemetry/opentelemetry-collector-contrib/processor/redactionprocessor v0.96.0
  - import: github.com/open-telemetry/opentelemetry-collector-contrib/processor/tailsamplingprocessor
    gomod: github.com/open-telemetry/opentelemetry-collector-contrib/processor/tailsamplingprocessor v0.96.0
    ↑ ここ
  - import: go.opentelemetry.io/collector/processor/memorylimiterprocessor
    gomod: go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.96.0
  - import: go.opentelemetry.io/collector/processor/batchprocessor
    gomod: go.opentelemetry.io/collector/processor/batchprocessor v0.96.0

exporters:
  - import: go.opentelemetry.io/collector/exporter/loggingexporter
    gomod: go.opentelemetry.io/collector/exporter/loggingexporter v0.96.0
  - import: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/googlecloudexporter
    gomod: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/googlecloudexporter v0.96.0

extensions:
  - import: github.com/open-telemetry/opentelemetry-collector-contrib/extension/healthcheckextension
    gomod: github.com/open-telemetry/opentelemetry-collector-contrib/extension/healthcheckextension v0.96.0
    ↑ ちなみにこちらは Otel Collector 自体を死活監視するための extension です。特に理由がなければ導入することをお勧めします。
otel-config.yaml
receivers:
  otlp:
    protocols:
      grpc:

exporters:
  googlecloud:
    log:
      default_log_name: opentelemetry.io/collector-exported-log

processors:
  memory_limiter:
    check_interval: 1s
    limit_percentage: 65
    spike_limit_percentage: 20
  batch:
  resourcedetection:
    detectors: [gcp]
    timeout: 10s
  tail_sampling: ## ここ
    policies: [
      {
        name: filter_url_path,
        type: string_attribute,
        string_attribute: {
          key: url.path,
          values: [ /actuator/health/* ],
          enabled_regex_matching: true,
          invert_match: true
        }
      }
    ]

extensions:
  health_check:

service:
  extensions: [health_check]
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter,batch,resourcedetection,tail_sampling]
      exporters: [googlecloud]

細かいですが、今回は spring-boot-starter-web を利用したので Semantic Conversation (otelにおいてどういった操作でどういったattributesを付与するかということ標準化したもの) として HTTP Server Spansが利用されました。よって、url.path が attribute に入ってくるのでこれを除外対象を指定する際に利用しました。利用するフレームワークやクライアントによっては異なるフィールドで連携される可能性があるので、一度、送信されたトレースのフィールドを確認することをお勧めします。

Before / After

上記設定をした Before / After です。(少し見づらいですが、After は 12:55:30 以降です。)設定前は大量のヘルスチェック Trace が表示されていて、かなりノイズになっていますね。 After ではかなりすっきりしました。

Discussion