OpenTelemetry 分散式追蹤
Vibe Prompt
「幫我在 FastAPI 中加上 OpenTelemetry 追蹤,將 trace 匯出到 Jaeger。」
安裝
pip install opentelemetry-distro opentelemetry-exporter-otlp
FastAPI 整合
from opentelemetry import trace
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
provider = TracerProvider()
processor = BatchSpanProcessor(OTLPSpanExporter(endpoint="http://jaeger:4317"))
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)
app = FastAPI()
FastAPIInstrumentor.instrument_app(app)
@app.get("/api/items/{item_id}")
async def get_item(item_id: int):
with trace.get_tracer(__name__).start_as_current_span("get_item") as span:
span.set_attribute("item_id", item_id)
result = await db.query("SELECT * FROM items WHERE id = ?", item_id)
span.set_attribute("db.query", "true")
return result
Jaeger 部署
services:
jaeger:
image: jaegertracing/all-in-one:latest
ports:
- "16686:16686" # UI
- "4317:4317" # OTLP gRPC
- "4318:4318" # OTLP HTTP
environment:
COLLECTOR_OTLP_ENABLED: "true"
Span 結構
Trace ID: abc123def456
├── Span: /api/checkout (HTTP POST)
│ ├── Span: validate_cart (0.2ms)
│ ├── Span: process_payment (342ms) ← 瓶頸在這裡!
│ │ ├── Span: stripe.api.charge (310ms)
│ │ └── Span: db.update_order (28ms)
│ └── Span: send_email (45ms)
└──
常見使用場景
- 找出跨服務的效能瓶頸
- 追蹤錯誤的真實根源
- 視覺化微服務呼叫關係