收齊 Metrics、Logs 與 Traces 之後,下一個關卡是「資料散落各處」。本章整理如何透過 Trace ID 與時間軸串起三種訊號,把 Data Silo 推平,讓 Signal Correlation(訊號關聯)真的在排查現場發揮綜效。

為何需要訊號關聯#

2018 年 DevOpsDays India 上,Goutham Veeramachaneni 在「Loki, Prometheus but for logs」中描繪了一張排查流程圖:先由 Alert 觸發,接著反覆在不同訊號間切換以定位問題,最後才動手修復。中段的「跨工具切換」往往最痛——資訊不足之外,工具彼此沒有共同語言,這正是 Observability 想要解決的兩大目標:補足資訊、消除 Data Silo。

CNCF 的 Observability Whitepaper 把這件事抽象成兩條線索:

  • 以 Trace ID 在 Logs 與 Traces 之間建立交叉引用。
  • 以時間軸把 Metrics 與其他訊號對齊。

實務上要做到這件事,需要工具配合。Grafana 在介紹 Exemplar(範例點)的文章中,示範了如何讓 Metrics、Logs、Traces 在同一個介面互相跳轉,下面以 Grafana 為主軸介紹四種常見組合。

Metrics and Logs:以時間對齊#

Grafana 的 Explore 支援同時開啟兩個 Panel,並把時間軸鎖在一起:

  • 左側 Panel 顯示 Metrics,右側 Panel 顯示 Logs(或反之)。
  • 在 Metrics 圖表上拖曳框選時間區段,可以快速縮小 Logs 的查詢範圍。

這條路線不需要在資料中埋特殊欄位,純粹靠時間就能成立,是最低成本的關聯方式。

Metrics to Traces:靠 Exemplar 接上 Trace ID#

Exemplar 是 OpenMetrics 提出的新資料型別,會在某筆 Metrics 樣本旁邊額外掛上一個觀測值與 Trace ID。Prometheus 與 Grafana 都已支援,啟用後在圖表上點選 Exemplar 點,即可跳轉到對應的 Trace。

要走通 Trace-to-Metrics(反向)與 Metrics-to-Traces 路徑前,先把 Exemplar 鋪好。

應用端產生 Exemplar#

Python 端可以改用 prometheus_client.openmetrics.exposition 輸出 OpenMetrics 格式,並在 Histogram.observe(...) 呼叫時透過 exemplar={"trace_id": trace_id} 帶入當下的 Trace ID(從 opentelemetry.trace.get_current_span() 取得):

trace_id = trace.format_trace_id(span.get_span_context().trace_id)
REQUESTS_PROCESSING_TIME.labels(...).observe(
    duration, exemplar={"trace_id": trace_id}
)

Java Spring Boot 端則建議搭配 Spring Boot 2.7、Micrometer 1.10 以上版本,並透過 Exemplar Sampler 注入 OpenTelemetry 的 Span Context;設定上只需開啟 management.metrics.distribution.percentiles-histogram.http.server.requests=true 即可。注意 /actuator/prometheus 預設輸出 Prometheus 格式,若要改抓 OpenMetrics,需要帶上對應的 Accept Header;但 Prometheus 抓取設定本身不必額外調整。

Prometheus 與 Grafana 設定#

  • Prometheus 啟動時加上 --enable-feature=exemplar-storage,否則 Exemplar 會被丟棄。
  • Grafana 中 Prometheus Data Source 要指定 Exemplar 對應的 Trace Backend(例如 Tempo 或 Jaeger),並對齊 Trace ID 的 label 名稱(如 trace_id)。
  • 查詢 Metrics 時要在 Options 中啟用 Exemplar,圖表才會出現 Exemplar 點。

OpenMetrics 是基於 Prometheus Metrics 設計、廠商中立的標準格式,誕生背景一部分是為了讓非雲原生(如 SNMP)的傳統監控生態也願意採用。Prometheus 與 OpenMetrics 創立者 Richard Hartmann 直言過:「會做 OpenMetrics,主要是因為政治。」名稱中立,其他公司才比較願意把它包進產品線。

Traces and Logs:靠 Trace ID 雙向跳轉#

Logs 與 Traces 之間以 Trace ID 為共同鍵,可以做雙向跳轉:Trace-to-Logs 與 Logs-to-Traces。

要做到這件事,需要:

  • 應用端的 Log 必須包含 Trace ID。Python 可使用 OpenTelemetry logging integration,自動或手動把 Trace ID 注入 Log 格式;Java 端則可透過 Logger MDC auto-instrumentation 把 trace_idspan_id 寫進 Log Pattern。
  • Logs-to-Traces:Loki Data Source 設定要連結的 Tracing Backend,並用正規表達式從 Log 抓取 Trace ID(例如 (?:trace_id)=(\w+)),設定畫面提供 Log 樣本驗證抓取效果。
  • Trace-to-Logs:Tracing Backend 的 Data Source 設定要連結的 Loki Data Source,並挑一組 Span Attribute(例如 compose_service)作為 Loki 查詢時的 Label。

Traces to Metrics:以 Span Attribute 帶入 PromQL#

Grafana 9.1 起支援 Trace-to-Metrics:在 Trace 詳情中,可以基於預先設定的 PromQL 跳轉到對應 Metrics 圖表,常見搭配是 Tempo Metrics-generator 產生的 Span Metrics。

設定步驟:

  • Grafana 啟用 traceToMetrics 功能旗標:
grafana:
  image: grafana/grafana:10.1.0
  environment:
    GF_FEATURE_TOGGLES_ENABLE: "traceToMetrics"
  • Tracing Backend Data Source 連結到對應的 Prometheus Data Source,並設定要查詢的 PromQL 模板。
  • 動態條件透過 $__tags 變數帶入:在設定中挑選 Span Attribute(例如 service.namehttp.target),Grafana 會把它們轉成 PromQL 的 Label-Value Pair,例如映射為 servicehttp_target

Lab:把四種跳轉走過一輪#

範例專案以 Docker Compose 起一組可實驗的環境,建議流程:

  • 安裝 Loki Docker Driver,方便 Loki 直接從 Container 收 Log:
docker plugin install grafana/loki-docker-driver:latest \
  --alias loki --grant-all-permissions
  • docker-compose up -d 啟動 FastAPI 兩個服務(app-a、app-b)、Spring Boot 服務(app-c)、Tempo、Loki、Prometheus、Grafana。
  • 用 k6 持續打流量:
k6 run --vus 1 --duration 300s k6-script.js
  • 在 Grafana Explore 中依序體驗:
    • Metrics 與 Logs 並排、時間同步檢視。
    • 在 Histogram 圖表上開啟 Exemplar,點 Exemplar 進 Tempo。
    • 從 Loki Log 詳情點 Trace ID 跳到 Tempo。
    • 從 Tempo Span 點 Related logs 跳到 Loki,或點 Request Duration PR95Request Rate Per Min 跳到 Prometheus。

這組 Lab 的價值不在示範程式本身,而在讓四條跳轉路徑都被實際走過一次,之後在生產環境設定時不容易漏掉細節。

小結#

把 Metrics、Logs、Traces 三條訊號縫起來後,排查問題的流程從「在多個工具之間 copy-paste」變成「在同一個介面持續鑽下去」。Grafana 在這條路徑上提供了相對完整的拼圖:時間同步、Exemplar、Trace 與 Log 的雙向連結、Trace-to-Metrics。背後的關鍵設計都很單純——以 Trace ID 與時間為共同語言——但要落實到生產環境,得在應用端、收集端、後端與 UI 端逐一把設定鋪好。1 + 1 + 1 能不能大於 3,差別就在這些細節上。

原文出處#

  • 原書/iThome:https://ithelp.ithome.com.tw/articles/10336629