OpenTelemetry バックエンドとして Prometheus を使用する

Prometheus は OTLP (別名 "OpenTelemetry Protocol") を HTTP 経由で取り込みをサポートしています。

OTLP レシーバーを有効にする

デフォルトでは、OTLP レシーバーは、リモート書き込みレシーバーと同様に無効になっています。これは、Prometheus が認証なしで動作できるため、明示的に設定しない限り、受信トラフィックを受け入れるのは安全ではないためです。

レシーバーを有効にするには、CLI フラグ --web.enable-otlp-receiver を切り替える必要があります。これにより、Prometheus は HTTP /api/v1/otlp/v1/metrics パスで OTLP メトリックの受信を開始します。

$ prometheus --web.enable-otlp-receiver

OpenTelemetry メトリックを Prometheus サーバーに送信する

通常、OTLP メトリックトラフィックの送信元に Prometheus エンドポイントと、OTLP の HTTP モードを使用する必要があることを伝える必要があります (gRPC が通常デフォルトです)。

OpenTelemetry SDK と計測ライブラリは、通常、標準環境変数 を介して設定できます。以下は、OpenTelemetry メトリックをローカルホスト上の Prometheus サーバーに送信するために必要な OpenTelemetry 変数です。

export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=https://:9090/api/v1/otlp/v1/metrics

トレースとログをオフにする

export OTEL_TRACES_EXPORTER=none
export OTEL_LOGS_EXPORTER=none

OpenTelemetry メトリックのデフォルトのプッシュ間隔は 60 秒です。以下は、15 秒のプッシュ間隔を設定します。

export OTEL_METRIC_EXPORT_INTERVAL=15000

計測ライブラリが service.name および service.instance.id をすぐに提供しない場合でも、それらを設定することを強くお勧めします。

export OTEL_SERVICE_NAME="my-example-service"
export OTEL_RESOURCE_ATTRIBUTES="service.instance.id=$(uuidgen)"

上記は、uuidgen コマンドがシステムで利用可能であることを前提としています。service.instance.id が各インスタンスで一意であり、リソース属性が変更されるたびに新しい service.instance.id が生成されることを確認してください。推奨される 方法は、インスタンスが起動するたびに新しい UUID を生成することです。

Prometheus の設定

このセクションでは、OpenTelemetry フローを有効にして調整するために推奨される Prometheus サーバーのさまざまな構成側面について説明します。

以下のセクションで使用する例の Prometheus 構成ファイル を参照してください。

順不同の取り込みを有効にする

順不同の取り込みを有効にしたい理由はいくつかあります。

たとえば、OpenTelemetry コレクターはバッチ処理を推奨しており、複数のコレクターのレプリカが Prometheus にデータを送信している可能性があります。これらのサンプルを順序付けるメカニズムがないため、順不同になる可能性があります。

順不同の取り込みを有効にするには、Prometheus 構成ファイルを次のように拡張する必要があります。

storage:
  tsdb:
    out_of_order_time_window: 30m

30 分の順不同でほとんどのケースで十分でしたが、ニーズに合わせてこの値を調整することをためらわないでください。

リソース属性の昇格

経験とコミュニティとの会話に基づいて、一般的に見られるすべてのリソース属性のうち、すべての OTLP メトリックに含める価値のあるものがあることがわかりました。

デフォルトでは、Prometheus は属性を昇格させません。属性を昇格させたい場合は、Prometheus 構成ファイルのこのセクションで行うことができます。以下のスニペットは、昇格させる属性のベストプラクティスセットを共有しています。

otlp:
  # Recommended attributes to be promoted to labels.
  promote_resource_attributes:
    - service.instance.id
    - service.name
    - service.namespace
    - service.version
    - cloud.availability_zone
    - cloud.region
    - container.name
    - deployment.environment
    - deployment.environment.name
    - k8s.cluster.name
    - k8s.container.name
    - k8s.cronjob.name
    - k8s.daemonset.name
    - k8s.deployment.name
    - k8s.job.name
    - k8s.namespace.name
    - k8s.pod.name
    - k8s.replicaset.name
    - k8s.statefulset.name

クエリ時にリソース属性を含める

昇格されていない、より冗長な、または一意のすべてのラベルは、特別な target_info にアタッチされます。

このメトリックを使用して、クエリ時に一部のラベルを結合できます。

そのようなクエリの例は次のようになります。

rate(http_server_request_duration_seconds_count[2m])
* on (job, instance) group_left (k8s_cluster_name)
target_info

このクエリでは、rate(http_server_request_duration_seconds_count[2m]) から得られる時系列に、同じ job および instance ラベルを共有する target_info シリーズから k8s_cluster_name ラベルが追加されます。言い換えれば、job および instance ラベルは、SQL の外部キーと同様に、http_server_request_duration_seconds_counttarget_info の間で共有されます。一方、k8s_cluster_name ラベルは OTel リソース属性 k8s.cluster.name に対応します (Prometheus はドットをアンダースコアに変換します)。

では、target_info メトリックと OTel リソース属性の関係は何でしょうか? Prometheus が OTLP 書き込みリクエストを処理し、含まれるリソースに属性 service.instance.id および/または service.name が含まれている場合、Prometheus はすべての (OTel) リソースに対して情報メトリック target_info を生成します。各 target_info シリーズに、service.instance.id リソース属性の値を持つ instance ラベルと、service.name リソース属性の値を持つ job ラベルを追加します。リソース属性 service.namespace が存在する場合、job ラベル値のプレフィックスとして追加されます (つまり、<service.namespace>/<service.name>)。

デフォルトでは、service.nameservice.namespaceservice.instance.id 自体は target_info に追加されません。これらは jobinstance に変換されるためです。ただし、次の構成パラメータを有効にすると、jobinstance への変換に加えて、それらを直接 target_info に追加できます (otlp.translation_strategyUnderscoreEscapingWithSuffixes の場合、ドットをアンダースコアに置き換える正規化が行われます)。

otlp:
  keep_identifying_resource_attributes: true

残りのリソース属性も、otlp.translation_strategyUnderscoreEscapingWithSuffixes の場合、Prometheus 形式 (例: ドットがアンダースコアに変換される) に名前が変換されて target_info シリーズにラベルとして追加されます。リソースに service.instance.idservice.name 属性の両方がない場合、対応する target_info シリーズは生成されません。

リソースの各 OTel メトリックについて、Prometheus はそれを対応する Prometheus 時系列に変換し、(target_info が生成された場合) 適切な instance および job ラベルを追加します。

UTF-8

Prometheus の 3.x バージョンから、Prometheus はメトリック名とラベルに UTF-8 をサポートしているため、OpenTelemetry からの Prometheus 正規化トランスレーターパッケージ は省略できます。Prometheus がコンテンツネゴシエーションを通じて UTF-8 文字を許可すると宣言した場合でも、メトリック名に以前サポートされていなかった文字が含まれる必要はないことに注意してください。OTLP メトリックは、エンドポイントの構成に応じて、いくつかの異なる方法で変換される場合があります。したがって、UTF-8 は Prometheus ストレージと UI でデフォルトで有効になっていますが、OTLP メトリックレシーバーの translation_strategy を設定する必要があります。これはデフォルトでは古い正規化 UnderscoreEscapingWithSuffixes に設定されています。

変換戦略には 4 つの可能性がありますが、そのうち 2 つは Prometheus で UTF-8 サポートを有効にする必要があります。

  • UnderscoreEscapingWithSuffixes (デフォルト)。これは、従来の Prometheus メトリック名の互換性のためにメトリック名を完全にエスケープし、タイプおよび単位の接尾辞を追加します。
  • UnderscoreEscapingWithoutSuffixes。これは、UnderscoreEscapingWithSuffixes と同様にメトリック名を完全にエスケープしますが、タイプと単位の接尾辞は追加しません。このモードはいくつかの観点から望ましくなく、ユーザーは接尾辞がないとメトリック名の衝突が発生する可能性があることを認識し、慎重なテストと組み合わせてこのモードを有効にする必要があります。これは、Otel の対称性と限られた文字サポートのバランスを好む一部の組織で使用されています。
  • NoUTF8EscapingWithSuffixes は、特殊文字を _ に変更するのを無効にし、特に セマンティック規約 とともに OpenTelemetry メトリック形式をネイティブに使用できるようにします。タイプや単位が異なる複数のメトリックが同じ名前を持つことによる衝突を防ぐために、単位やカウンターの _total などの特別な接尾辞が追加されることに注意してください。このモードには UTF-8 が有効になっている必要があります。
  • NoTranslation。この戦略は、すべてのメトリック名とラベル名の変換をバイパスし、変更せずにそれらを渡します。このモードには、UTF-8 が有効になっている必要があります。接尾辞がないと、同じ名前の複数のメトリックが異なるタイプまたは単位を持つ場合に、衝突が発生する可能性があることに注意してください。
otlp:
  # Ingest OTLP data keeping UTF-8 characters in metric/label names.
  translation_strategy: NoTranslation

デルタテンポラリティ

OpenTelemetry の仕様 によると、デルタテンポラリティと累積テンポラリティの両方がサポートされています。デルタテンポラリティは statsd や graphite などのシステムでは一般的ですが、Prometheus では累積テンポラリティがデフォルトです。

現在、Prometheus は delta to cumulative プロセッサOpenTelemetry-Collector-contrib から組み込んでおり、デルタを取り込み、Prometheus の TSDB に格納する前に同等の累積表現に変換することができます。

この機能は実験的であるため、使用するには機能フラグ otlp-deltatocumulative を有効にして Prometheus を起動してください。

チームは依然として OTLP デルタをより効率的に処理する方法に取り組んでいます。

このページの内容