PrometheusとしてのOpenTelemetryバックエンドの使用
Prometheusは、OTLP (「OpenTelemetry Protocol」とも呼ばれます) の取り込みをHTTP経由でサポートしています。
OTLPレシーバーの有効化
デフォルトでは、OTLPレシーバーはRemote Writeレシーバーと同様に無効になっています。これは、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およびインストルメンテーションライブラリは、通常標準環境変数で設定できます。以下は、localhost上のPrometheusサーバーにOpenTelemetryメトリックを送信するために必要な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ラベルは、http_server_request_duration_seconds_countとtarget_infoの間で共有され、SQLの外部キーに似ています。一方、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に変換されるためです。ただし、以下の設定パラメータを有効にすると、(otlp.translation_strategyがUnderscoreEscapingWithSuffixesの場合) 正規化を通過して、jobおよびinstanceへの変換に加えて、これらを直接target_infoに追加できます。
otlp:
keep_identifying_resource_attributes: true
残りのリソース属性も、Prometheus形式の名前 (たとえば、otlp.translation_strategyがUnderscoreEscapingWithSuffixesの場合にドットをアンダースコアに変換) に変換されて、target_infoシリーズのラベルとして追加されます。リソースにservice.instance.idとservice.name属性の両方が欠落している場合、対応するtarget_infoシリーズは生成されません。
リソースのOTelメトリックごとに、PrometheusはそれをPrometheus時系列に変換し、(target_infoが生成される場合) 正しいinstanceおよびjobラベルを追加します。
UTF-8
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仕様ではDeltaテンポラリティとCumulativeテンポラリティの両方がサポートされていると述べています。Deltaテンポラリティはstatsdやgraphiteなどのシステムで一般的ですが、CumulativeテンポラリティはPrometheusのデフォルトです。
現在、Prometheusはデルタから累積へのプロセッサをOpenTelemetry-Collector-contribから組み込んでおり、これはデルタを取り込み、PrometheusのTSDBに保存する前に同等の累積表現に変換できます。
この機能は実験的です。そのため、機能フラグotlp-deltatocumulativeを有効にしてPrometheusを開始して使用してください。
チームは、OTLPデルタをより効率的に処理する方法をまだ検討中です。