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_count
と target_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.name
、service.namespace
、service.instance.id
自体は target_info
に追加されません。これらは job
と instance
に変換されるためです。ただし、次の構成パラメータを有効にすると、job
と instance
への変換に加えて、それらを直接 target_info
に追加できます (otlp.translation_strategy
が UnderscoreEscapingWithSuffixes
の場合、ドットをアンダースコアに置き換える正規化が行われます)。
otlp:
keep_identifying_resource_attributes: true
残りのリソース属性も、otlp.translation_strategy
が UnderscoreEscapingWithSuffixes
の場合、Prometheus 形式 (例: ドットがアンダースコアに変換される) に名前が変換されて target_info
シリーズにラベルとして追加されます。リソースに service.instance.id
と service.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 デルタをより効率的に処理する方法に取り組んでいます。