將 Prometheus 作為 OpenTelemetry 後端

Prometheus 透過 OTLP(又稱「OpenTelemetry 協定」)的 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 指標傳送到 localhost 上的 Prometheus 伺服器所需的 OpenTelemetry 變數

export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=https://127.0.0.1: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.nameservice.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

本節說明 Prometheus 伺服器的各種建議設定,以啟用和調整您的 OpenTelemetry 流程。

請參閱我們將在下面章節中使用的範例 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
    - cloud.availability_zone
    - cloud.region
    - container.name
    - 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]) 產生的時間序列會以 target_info 系列的 k8s_cluster_name 標籤擴增,這些系列會共用相同的 jobinstance 標籤。換句話說,jobinstance 標籤在 http_server_request_duration_seconds_counttarget_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 系列中新增標籤 instance,其值為 service.instance.id 資源屬性,並新增標籤 job,其值為 service.name 資源屬性。如果存在資源屬性 service.namespace,則會將其加上 job 標籤值的前置詞 (即 <service.namespace>/<service.name>)。

預設情況下,service.nameservice.namespaceservice.instance.id 本身不會新增到 target_info,因為它們會轉換為 jobinstance。但是,可以啟用以下設定參數,以將它們直接新增到 target_info (如果 otlp.translation_strategyUnderscoreEscapingWithSuffixes,則會經過正規化以將點取代為底線),此外還會轉換為 jobinstance

otlp:
  keep_identifying_resource_attributes: true

如果 otlp.translation_strategyUnderscoreEscapingWithSuffixes,則其餘的資源屬性也會作為標籤新增到 target_info 系列,名稱會轉換為 Prometheus 格式 (例如,將點轉換為底線)。如果資源缺少 service.instance.idservice.name 屬性,則不會產生對應的 target_info 系列。

對於資源的每個 OTel 指標,Prometheus 會將其轉換為對應的 Prometheus 時間序列,並且 (如果產生 target_info) 會新增正確的 instancejob 標籤。

UTF-8

從 3.x 版本開始,Prometheus 支援指標名稱和標籤的 UTF-8,因此可以省略來自 OpenTelemetry 的 Prometheus 正規化翻譯器套件

UTF-8 預設在 Prometheus 儲存和 UI 中啟用,但是您需要為 OTLP 指標接收器設定 translation_strategy,預設設定為舊的正規化 UnderscoreEscapingWithSuffixes

將其設定為 NoUTF8EscapingWithSuffixes (我們建議使用此選項) 會停用將特殊字元變更為 _,這允許原生使用 OpenTelemetry 指標格式,尤其是在使用 語意慣例時。請注意,會附加諸如單位和計數器的 _total 等特殊字尾。目前有 正在進行的作業是不產生字尾,敬請密切關注。

otlp:
  # Ingest OTLP data keeping UTF-8 characters in metric/label names.
  translation_strategy: NoUTF8EscapingWithSuffixes

目前在 OTLP 翻譯套件中存在一個已知限制,如果多個 UTF-8 字元在單字之間串連,則會從指標/標籤名稱中移除字元,例如 my___metric 會變成 my_metric。如需更多詳細資訊,請參閱 https://github.com/prometheus/prometheus/issues/15362

增量時間性

OpenTelemetry 規格說明支援增量時間性和累積時間性。

雖然增量時間性在 statsd 和 graphite 等系統中很常見,但累積時間性是 Prometheus 的預設時間性。

目前 Prometheus 尚不支援增量時間性 (delta temporality),但我們正從 OpenTelemetry 社群學習,並考慮未來加入對其的支援。

如果您是從增量時間性系統轉移過來,我們建議您在您的 OTel 管線中使用 增量轉累計處理器 (delta to cumulative processor)

此文件為開源。請透過提交問題或發送 Pull Request 來協助改進它。