透過前篇,我們了解了 OpenTelemetry 的三大主要功能:Trace、Metric 和 Log。今天,我們將專注於 Trace,並展示如何在 Node.js 和 Python FastAPI 中集成 OpenTelemetry,將追蹤數據(Tracing Data)導出到 Jaeger,並在 Jaeger 中進行可視化。
Jaeger 是 CNCF(Cloud Native Computing Foundation) 項目之一,是 User 公司開源的一個用於監控和診斷微服務的分布式系統。當時是基於 OpenTracing 的標準來開發,現在可以無縫接入到 Opentelemetry 標準中。
Jaeger 的架構相對簡單,且支持多種協議,如 HTTP、gRPC 及 OTLP,因此在本地或雲端進行部署和使用都相對便捷。在這篇文章中,我們將利用 Docker 來本地運行 Jaeger。
要在本地運行 Jaeger,可以使用 Docker 快速啟動一個包含 OpenTelemetry 支持和可視化界面的 Jaeger
使用 Jaeger docker image,設定如下:
docker-composer.yml
:
version: '3'
services:
self-jaeger-otel:
image: jaegertracing/all-in-one:latest
container_name: self-jaeger-otel
environment:
- COLLECTOR_ZIPKIN_HTTP_PORT=9411
- COLLECTOR_OTLP_ENABLED=true
- SAMPLING_STRATEGIES_FILE=/etc/jaeger/sampling_strategies.json
ports:
- '14250:14250'
- '14268:14268'
- '16686:16686'
- '4317:4317'
- '4318:4318'
- '5775:5775'
- '5778:5778'
- '6831:6831'
- '6832:6832'
- '9411:9411'
http://localhost:16686/search
,如果有Jaeger的可視化頁面,代表運行成功接著,我們將展示如何在 Node.js Express 應用中集成 OpenTelemetry,並將追蹤數據導出到 Jaeger。
pnpm add
安裝 otel 相關依賴:
@opentelemetry/sdk-node
---主要 Otel NodeJS SDK@opentelemetry/auto-instrumentations-node
---用於自動嵌入、運行常用的 instrumentation 模塊@opentelemetry/exporter-trace-otlp-http
---利用 HTTP 傳送 tracing data 到指定服務endpoint(例如本篇的 Jaeger)@opentelemetry/resources
和 @opentelemetry/semantic-conventions
---用於服務命名和標準化資料結構。在專案中新增一個 otel.js
,配置 SDK 以便將追蹤數據導出到 Jaeger:
const { NodeSDK } = require('@opentelemetry/sdk-node');
const {
OTLPTraceExporter,
} = require('@opentelemetry/exporter-trace-otlp-http');
const {
getNodeAutoInstrumentations,
} = require('@opentelemetry/auto-instrumentations-node');
const {
ATTR_SERVICE_VERSION,
ATTR_SERVICE_NAME,
} = require('@opentelemetry/semantic-conventions');
const { Resource } = require('@opentelemetry/resources');
const { JAEGER_URL } = require('./config');
// 自定義服務的名稱以及版本號
const resource = new Resource({
[ATTR_SERVICE_NAME]: 'nodejs-service-01',
[ATTR_SERVICE_VERSION]: '1.0.0',
});
// 設定trace data要傳到哪裡
const traceExporter = new OTLPTraceExporter({
url: JAEGER_URL,
});
const otelSdk = new NodeSDK({
traceExporter: traceExporter,
instrumentations: [getNodeAutoInstrumentations()],
resource: resource,
});
module.exports = {
otelSdk,
};
在 main.js
或其他主要入口文件中引入和初始化 OpenTelemetry SDK。如同之前提到的 Sentry SDK,也是為了全局覆蓋請求
const { otelSdk } = require('./utils/otel');
otelSdk.start();
const express = require('express');
const cors = require('cors');
const app = express();
const PORT = 3030;
...
運行後,可以先call看看自己寫好的api,然後去Jaeger中查看是否有相關的 tracing data
為了展示跨服務的追蹤,我們將新增一個 Python FastAPI 服務,並集成 OpenTelemetry。
在 Python FastAPI 專案中安裝 OpenTelemetry SDK 和 FastAPI 的自動化 instrumentation 依賴:
opentelemetry-api
opentelemetry-sdk
opentelemetry-instrumentation-fastapi
以下是如何將 OpenTelemetry 集成到 FastAPI 應用中,並將追蹤數據發送到 Jaeger:
from fastapi import FastAPI, Request
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor, OpenTelemetryMiddleware
import uvicorn
from config import JAEGER_URL, PORT
app = FastAPI()
# 設置服務名稱和追蹤數據的資源
resource = Resource(attributes={
"service.name": "python-fastapi-01",
"service.version": "1.0.0",
})
# 配置 TracerProvider 和 OTLPSpanExporter
trace.set_tracer_provider(TracerProvider(resource=resource))
tracer_provider = trace.get_tracer_provider()
# 使用 OTLP 導出器將追蹤數據發送到 Jaeger
otlp_exporter = OTLPSpanExporter(endpoint=JAEGER_URL)
span_processor = BatchSpanProcessor(otlp_exporter)
tracer_provider.add_span_processor(span_processor)
# 自動追蹤 FastAPI 應用
FastAPIInstrumentor.instrument_app(app)
@app.get("/")
async def read_root():
return {"message": "Hello World"}
在 Node.js 應用中新增一個端點來呼叫 Python 服務,以產生跨服務的 Trace:
app.get('/api/demo-multi', async (req, res) => {
const data = await axios.get(`${PYTHON_SERVICE_URL}/api/demo-01`);
res.json({ message: `demo api success, python service: ${data.message}` });
});
成功呼叫後,可以在 Jaeger 中查看跨服務的 Trace 連線,觀察每個服務之間的依賴關係。
今天,我們通過 OpenTelemetry SDK 和 Jaeger,實現了分散式追蹤數據的本地可視化。接下來,我們將深入探討 Opentelemetry 是如何產生 Trace。
完整程式碼可以查看此 Github repository