Tempo 是 Grafana Labs 在 2020 年 10 月推出的 Tracing Backend,主打高效、易用與低成本。它的核心策略是把 Trace 落地到 Object Storage(如 Google Cloud Storage、Amazon S3),既享受物件儲存的低單位成本,又免去維護 Cassandra、Elasticsearch 這類儲存服務的負擔,讓團隊有條件保留更多 Trace、避免「出事卻找不到 Trace」的窘境。

Tempo 在資料流中的位置#

Tempo 主要處理收集與儲存兩個階段:

  • 接收:支援多種 Tracing Protocol,包括 Jaeger、Zipkin 與 OpenTelemetry Protocol(OTLP)。
  • 儲存:以 Object Storage 為主要落地位置。
  • 使用:UI 端透過 Grafana 查詢,Tempo 自身只透過 API 提供資料,不另外維護一套 UI。

整體架構相對單純,定位接近一個「專注接收與儲存 Trace」的後端。

核心概念#

TraceQL#

Grafana Labs 在 2023 年 2 月隨 Tempo 2.0 發佈 TraceQL,這是專為 Trace 設計的查詢語言,靈感來自 PromQL,並沿用 LogQL 的 Pipeline 設計。透過 TraceQL,可以更精準地查詢 Span,並支援 count()avg()min()max()sum() 等聚合函數。常見查詢範例:

  • 查詢 HTTP 狀態碼為 2xx 的 Span:
{ .http.status_code >= 200 && .http.status_code < 300 }
  • 查詢執行時間介於 0.5 到 1 秒之間的 Span:
{ duration >= 0.5s && duration < 1s }
  • 以正規表達式查詢 URL:
{ .http.url =~ "/api/v1/.*" }
  • 找出 Trace 中包含 INSERT 開頭 SQL 且該類 Span 平均耗時超過 1 秒的:
{ .db.statement =~ "INSERT.*" } | avg(duration) > 1s
  • 同時組合多個條件:
{
    .http.status_code = 500   &&
    .http.url =~ "/api/v1/.*" &&
    (.http.method = "POST" || .http.method = "PUT")
}

儲存格式#

從 2.0 開始,Tempo 預設使用 Apache Parquet 作為儲存格式。Parquet 是一種 Column-based 的開源資料格式,壓縮率高、查詢效率佳,並且擁有 Java、Python、Go 等多語言生態。改採 Parquet 的另一個動機是讓使用者能跳脫 Tempo 的查詢能力限制,使用其他工具直接分析儲存層的資料;TraceQL 也是基於 Parquet 設計,因此能享受同樣的查詢效率。

Metrics-generator#

Metrics-generator 是 Tempo 的可選元件,需要手動啟用,主要用途是依 Trace 即時生成 Request 相關的 Metrics,目前提供兩個方向:

  • Span Metrics:根據 Span 屬性生成 Metrics。
  • Service Graphs:依 Trace 中的呼叫關係建立服務拓撲圖與 RED Metrics(Request Rate、Request Errors、Request Duration)。

要啟用時可在 Tempo 設定檔中加入:

metrics_generator:
  storage:
    path: "/tmp/metrics"
    remote_write:
      - url: "http://prometheus:9090/api/v1/write"
overrides:
  metrics_generator_processors:
    - service-graphs
    - span-metrics

由於 Tempo 本身不存 Metrics,必須透過 Prometheus Remote Write 將 Metrics 寫入 Prometheus、Mimir、Cortex 等服務;storage.path 則是用於暫存產生中的 Metrics。Span Metrics 與 Service Graphs 透過 overrides.metrics_generator_processors 個別啟用。

Span Metrics 預設會輸出以下指標:

  • traces_spanmetrics_latency:Histogram,紀錄 Span 執行時間,可推導 P99、P95 等。
  • traces_spanmetrics_calls_total:Counter,紀錄 Span 數量。
  • traces_spanmetrics_size_total:Counter,紀錄 Span 大小。

預設 Label 包含 servicespan_namespan_kindstatus_code,若要加入更多 Label,可透過 metrics_generator.processor.span_metrics.dimensions 設定,例如加上 http.status_code

Service Graphs 則是把服務間關係寫成 Prometheus Metrics,因此使用時需要在 Tempo 的 Data Source 設定 Metrics 來源的 Prometheus,並在 Grafana 啟用 tempoServiceGraph feature toggle(可寫進 grafana.ini[feature_toggles],或透過環境變數 GF_FEATURE_TOGGLES_ENABLE=tempoServiceGraph)。

小結#

Tempo 把 Trace 後端的設計大幅簡化:用 Object Storage 解決儲存成本問題,用 Grafana 解決 UI 問題,再用 TraceQL 與 Metrics-generator 補上查詢與衍生指標的能力。對於已經採用 Grafana Stack 的團隊來說,是阻力最小的 Tracing Backend 選項。

原文出處#

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