OpenTelemetry OpenTelemetry

receiver でログとインフラのメトリクスを収集する

filelog、hostmetrics、kubeletstats、prometheus の receiver を使い、トレースからメトリクスを導出します。

14 min learn.level.中級

OpenTelemetry の SDK を使うアプリケーションは、自分のテレメトリを自分で送りますが、観測する必要のあるものの多くは、そうではありません。ログファイル、ホストのリソース、kubelet、すでに Prometheus のメトリクスを公開しているサービスなどです。Collector は、receiver を通じてそれらを取り込みます。このガイドでは、最も有用なものを、すべて設定として示します。コンポーネントのオプション名はリリース間で変わるため、実行するバージョンの各 receiver の README を確認してください。これらはすべて、contrib と Kubernetes のディストリビューションにあります。

filelog でログファイルを扱う

filelog receiver は、ファイルを追跡し、行をログレコードに変換します。

receivers:
  filelog:
    include:
      - /var/log/myapp/*.log
    exclude:
      - /var/log/myapp/*.gz
    start_at: end            # または "beginning" で既存の内容を読む
    include_file_path: true
    operators:
      - type: json_parser
        timestamp:
          parse_from: attributes.time
          layout: '%Y-%m-%dT%H:%M:%S.%LZ'
        severity:
          parse_from: attributes.level

operator は、各エントリに対して実行される、小さなパースのパイプラインを形成します。一般的なものは、json_parser、regex_parser、move、add、remove、recombine(複数行のスタックトレースを 1 つのレコードに再結合する)です。複数行の例:

    operators:
      - type: recombine
        combine_field: body
        is_first_entry: body matches "^\\d{4}-\\d{2}-\\d{2}"
        source_identifier: attributes["log.file.path"]

再読み込みやスキップなしに再起動を乗り切るには、receiver にストレージの extension を与えます。

extensions:
  file_storage:
    directory: /var/lib/otelcol/storage

receivers:
  filelog:
    include: [/var/log/myapp/*.log]
    storage: file_storage

service:
  extensions: [file_storage]

Kubernetes では、コンテナのログは /var/log/pods/*/*/*.log にあります。Helm チャートの logsCollection の preset が、この receiver を設定し、ホストのパスをマウントし、コンテナランタイムの形式をパースしてくれるため、receiver を手作業で書くよりも、それを優先してください。

hostmetrics でホストのメトリクスを扱う

VM やノードでは、hostmetrics receiver が、オペレーティングシステムから CPU、メモリ、ディスク、ファイルシステム、ネットワークの数値を読み取ります。

receivers:
  hostmetrics:
    collection_interval: 30s
    scrapers:
      cpu:
      memory:
      load:
      disk:
      filesystem:
        exclude_mount_points:
          mount_points: [/dev/*, /proc/*, /sys/*, /run/*]
          match_type: regexp
      network:
      paging:

各ホストのエージェントで実行します。コンテナ内では、ホストのファイルシステムをマウントして root_path を設定しない限り、コンテナのビューを報告するため、そこで頼る前に receiver の README を確認してください。resourcedetection processor を追加して、メトリクスにホスト、クラウド、Kubernetes の詳細のラベルを付けます。

processors:
  resourcedetection:
    detectors: [env, system]
    timeout: 5s
    override: false

Kubernetes のメトリクス

ノードと Pod のリソース使用量は、DaemonSet として実行される kubeletstats を通じて、kubelet から得られます。

receivers:
  kubeletstats:
    collection_interval: 30s
    auth_type: serviceAccount
    endpoint: ${env:K8S_NODE_NAME}:10250
    insecure_skip_verify: true
    metric_groups: [node, pod, container]

downward API でノード名を渡します。

env:
  - name: K8S_NODE_NAME
    valueFrom:
      fieldRef:
        fieldPath: spec.nodeName

kubelet の証明書は自己署名であることが多いため、insecure_skip_verify が一般的です。可能な場合は、適切な CA の設定を使ってください。service account には nodes/stats を読む権限が必要で、Helm の preset がそれを付与します。

クラスターレベルの状態(Deployment のレプリカ、Pod のフェーズ、ノードの状態)は k8s_cluster receiver から、Kubernetes のイベントは k8sobjects から得られます。どちらもクラスターごとに 1 回だけ、単一のレプリカの Deployment で実行してください。そうしないと、重複して収集されます。どちらも Helm の preset(clusterMetrics と kubernetesEvents)として利用できます。

Prometheus のエンドポイントをスクレイプする

prometheus receiver は、標準の Prometheus のスクレイプ設定を受け付けるため、既存のターゲットを書き直さずに移行できます。

receivers:
  prometheus:
    config:
      scrape_configs:
        - job_name: node-exporter
          scrape_interval: 30s
          static_configs:
            - targets: ["node-exporter:9100"]
        - job_name: kubernetes-pods
          kubernetes_sd_configs:
            - role: pod
          relabel_configs:
            - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
              action: keep
              regex: "true"

2 つの落とし穴:Collector の設定では、Prometheus の正規表現や置換でのリテラルのドル記号を $$ と書きます。そうしないと、Collector がそれを変数として展開しようとします。また、同じターゲットをスクレイプする複数のレプリカを実行すると、重複します。OpenTelemetry Operator の Target Allocator は、Collector のレプリカ間でターゲットをシャーディングするために存在し、スクレイピングを行う単一のレプリカを実行するのも同様です。

多くの receiver、1 つのパイプライン

receiver は、同じシグナルの種類のパイプラインに供給します。

service:
  pipelines:
    metrics:
      receivers: [otlp, hostmetrics, kubeletstats, prometheus]
      processors: [memory_limiter, resourcedetection, batch]
      exporters: [otlphttp/prometheus]
    logs:
      receivers: [otlp, filelog]
      processors: [memory_limiter, batch]
      exporters: [otlphttp/loki]

シグナルごとに複数のパイプライン(metrics/infra、metrics/apps)に分割して、各ソースに異なる processor を適用することもできます。

spanmetrics connector でトレースからメトリクスを導出する

サービスがトレースを出力するがリクエストのメトリクスを出力しない場合、spanmetrics connector が、スパンから、リクエスト数、エラー数、レイテンシーのヒストグラムを導出します。connector は、あるパイプラインの exporter であり、別のパイプラインの receiver です。

connectors:
  spanmetrics:
    histogram:
      explicit:
        buckets: [10ms, 50ms, 100ms, 250ms, 500ms, 1s, 2.5s, 5s]
    dimensions:
      - name: http.request.method
      - name: http.response.status_code

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [otlp/tempo, spanmetrics]
    metrics/spanmetrics:
      receivers: [spanmetrics]
      processors: [batch]
      exporters: [otlphttp/prometheus]

各ディメンションは時系列の数を増やすため、値の集合が小さく、限定されている属性だけを追加してください。ユーザー ID や識別子を含む URL は、決して使わないでください。数値がすべてのトラフィックを反映するように、connector は、どのサンプリングよりも前に置きます(サンプリングのガイドを参照)。

確認する

パイプラインのコピーに、verbosity: detailed の debug exporter を追加し、Collector をフォアグラウンドで実行します。パースされた重大度を持つログレコードや、system.cpu.time、k8s.pod.cpu.usage、traces.span.metrics.calls のようなメトリクス名が表示されるはずです(名前はバージョンによって異なる場合があります)。何も表示されない場合は、filelog のファイルの権限、kubeletstats のノード名の変数、そしてすべての receiver がパイプラインに列挙されていることを確認してください。

人気のガイド