iT邦幫忙

2024 iThome 鐵人賽

DAY 16
1
DevOps

全端監控技術筆記---從Sentry到Opentelemetry系列 第 16

Day16--簡單demo看看 Opentelemetry tracing data + Jaeger

  • 分享至 

  • xImage
  •  

前言

透過前篇,我們了解了 OpenTelemetry 的三大主要功能:Trace、Metric 和 Log。今天,我們將專注於 Trace,並展示如何在 Node.js 和 Python FastAPI 中集成 OpenTelemetry,將追蹤數據(Tracing Data)導出到 Jaeger,並在 Jaeger 中進行可視化。

Jaeger簡介與運行

Jaeger是什麼

Jaeger 是 CNCF(Cloud Native Computing Foundation) 項目之一,是 User 公司開源的一個用於監控和診斷微服務的分布式系統。當時是基於 OpenTracing 的標準來開發,現在可以無縫接入到 Opentelemetry 標準中。

Jaeger 的架構相對簡單,且支持多種協議,如 HTTP、gRPC 及 OTLP,因此在本地或雲端進行部署和使用都相對便捷。在這篇文章中,我們將利用 Docker 來本地運行 Jaeger​。

在本地運行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的可視化頁面,代表運行成功

image

NodeJS Express 接入 opentelemetry

接著,我們將展示如何在 Node.js Express 應用中集成 OpenTelemetry,並將追蹤數據導出到 Jaeger。

安裝 node opentelemetry trace相關依賴

  • 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 ---用於服務命名和標準化資料結構​​。

設定sdk

在專案中新增一個 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,
};

初始化sdk並運行應用

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

image

加入第二個Python服務,查看span

為了展示跨服務的追蹤,我們將新增一個 Python FastAPI 服務,並集成 OpenTelemetry。

在python fastapi專案中引入otel相關依賴

在 Python FastAPI 專案中安裝 OpenTelemetry SDK 和 FastAPI 的自動化 instrumentation 依賴:

  • opentelemetry-api
  • opentelemetry-sdk
  • opentelemetry-instrumentation-fastapi

在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"}

在NodeJS專案中呼叫 Python API

在 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 連線,觀察每個服務之間的依賴關係。

image

小結

今天,我們通過 OpenTelemetry SDK 和 Jaeger,實現了分散式追蹤數據的本地可視化。接下來,我們將深入探討 Opentelemetry 是如何產生 Trace。

完整程式碼可以查看此 Github repository

ref

ChangeLog

  • 20240930--補充完整內容
  • 20240923--大綱與初稿

上一篇
Day15---談到Opentelemetry,我們在談論什麼
下一篇
Day17--在 Opentelemetry 中,是如何發起trace/span
系列文
全端監控技術筆記---從Sentry到Opentelemetry30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言