Jaeger 入門:用 OpenTelemetry 串起分散式追蹤
Jaeger 入門:用 OpenTelemetry 串起分散式追蹤
一個請求打進來,經過 gateway、好幾個 service、資料庫,最後回應。哪一段慢了?log 散在各台機器很難拼。分散式追蹤把這條請求的每一段串成一棵 span 樹,Jaeger 就是拿來收集與檢視這棵樹的工具。這篇講 Jaeger 是什麼、OpenTelemetry 為什麼是關鍵、gortex 的 Tracer 介面怎麼接上,以及怎麼用 Docker 在本機快速跑起來。
分散式追蹤要解什麼
微服務下,一個外部請求會散成內部好幾個呼叫,出問題時看單台的 log 只看到片段。分散式追蹤的單位是 span:一段有名字、有起訖時間的工作,像一次 HTTP handler、一次 DB query。span 之間有 parent / child 關係,串起來就是一個 trace,一棵完整的請求樹,看這棵樹就知道時間花在哪、哪一段報錯。
關鍵是 trace context 要能跨服務傳遞:上游把 trace ID 放進 header,下游接著用,這條鏈路才接得起來。gortex 在程式內部用 context 傳 span(見可觀測性那篇),跨服務則靠 OTel 的 propagation。
Jaeger 是什麼
Jaeger 是 CNCF 的分散式追蹤平台,負責收集、儲存、查詢 span,並提供一個 Web UI 把 trace 畫成時間軸瀑布圖。正式部署會拆成幾個角色:collector 收 span、儲存後端存資料、query 加 UI 給你查。
開發階段不用拆這麼細,官方有一個 all-in-one image,把 collector、query、UI 包在一個 container 裡、用記憶體存資料,起來就能用,重開就清空,正好適合本機開發。
OpenTelemetry:共通語言
這裡的關鍵字是 OpenTelemetry(OTel)。它是一套廠商中立的可觀測性標準:一組 instrumentation 的 API / SDK,加上一個傳輸協定 OTLP。你的程式只對 OTel 產生 span,要送去哪個後端是另一回事。
意義在於 instrumentation 與後端解耦。今天送 Jaeger,明天想換 Grafana Tempo 或 Zipkin,改的是 exporter 設定,不是你滿地的 instrumentation 程式。
gortex 把這個解耦做進框架:它只依賴一個 Tracer 介面,附一個 OTelTracerAdapter 把 gortex span 轉成 OTel span(severity 對映、tags、status 都搬過去)。所以「gortex → OTel → Jaeger」這條路是現成的,你的業務碼只看到 Tracer 介面。設定大致長這樣:
import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
gotel "github.com/yshengliao/gortex/observability/otel"
"github.com/yshengliao/gortex/observability/tracing"
)
// 標準 OTel SDK:OTLP exporter 指到 Jaeger 的 4317
exp, _ := otlptracegrpc.New(ctx,
otlptracegrpc.WithEndpoint("localhost:4317"),
otlptracegrpc.WithInsecure(),
)
otel.SetTracerProvider(sdktrace.NewTracerProvider(sdktrace.WithBatcher(exp)))
// gortex 端:包一層 adapter,span 就會流進 OTel → Jaeger
tracer := gotel.NewOTelTracerAdapter(tracing.NewSimpleTracer(), "gortex")
exporter 是標準 OTel SDK 的東西,不是 gortex 自己發明的;gortex 只負責把自家 span 轉成 OTel span。
用 Docker 在 OrbStack 上快速起
最快的方式是 compose,用現成範本(jaeger,跑 jaegertracing/all-in-one:latest)。在 OrbStack 上 docker compose up -d,幾秒就好:
git clone https://github.com/yshengliao/docker-compose-templates
cd docker-compose-templates/jaeger
docker compose up -d
幾個會用到的 port:
16686:Jaeger UI,瀏覽器開http://localhost:16686就能查 trace。4317:OTLP gRPC、4318:OTLP HTTP,你的程式 exporter 指這裡。9411:Zipkin 相容端點。
範本已經設了 COLLECTOR_OTLP_ENABLED=true,OTLP 收 trace 預設開著。把上面那段的 exporter 指到 localhost:4317,發幾個請求,UI 上就能看到 trace 一條條進來。
換成 Grafana 也一樣
不想用 Jaeger UI,想統一在 Grafana 看?同一套 OTel instrumentation 不用動。Grafana 這邊用 Tempo 當 trace 後端,Tempo 一樣收 OTLP:把 exporter 的 endpoint 從 Jaeger 改成 Tempo,再在 Grafana 接 Tempo data source,trace 就出現在 Grafana 裡,還能跟 metrics、log 並排看。
換句話說,後端是可以挑的,Jaeger、Grafana Tempo、Zipkin 都行。能這樣挑,靠的就是 OTel 這層標準加上 gortex 的 adapter,程式對介面寫,後端隨你換。這正是介面驅動設計在維運面的回報。
重點整理
- 分散式追蹤的單位是 span,串成 trace(請求樹);要靠 trace context 跨服務傳遞才接得起來。
- Jaeger 是 CNCF 的追蹤平台,all-in-one image 把 collector / query / UI 包成一個 container,最適合本機開發。
- OpenTelemetry 是廠商中立標準(API/SDK 加 OTLP),讓 instrumentation 與後端解耦;gortex 用
Tracer介面加OTelTracerAdapter接上。 - 用 jaeger 範本
docker compose up -d:UI 在16686,OTLP 在4317/4318,exporter 指過去即可。 - 後端可換成 Grafana Tempo(一樣收 OTLP),instrumentation 一行不動,這是 OTel 標準加 adapter 模式的好處。
原始碼與更多框架細節:yshengliao/gortex。
內文由 Claude 協助整理 · 環境 Jaeger all-in-one + OpenTelemetry + Docker(OrbStack) · 列入 20260613 blog 翻新計劃,新漆未乾。