OpenTelemetry (OTel) 官網的開場白是「OpenTelemetry is a collection of APIs, SDKs, and tools.」,本章聚焦在生成階段,整理如何透過各語言的 SDK,特別是自動插樁(Auto Instrumentation),快速地在現有服務中產生 Telemetry Data。
兩種 Instrumentation 模式#
OpenTelemetry 將「在程式中埋設追蹤點」這件事抽象為 Instrumentation(中文常譯為「儀器化」),並提供兩種模式:
- 手動插樁(Manual Instrumentation):相較於直接呼叫 SDK API,這層封裝較為簡潔,但仍需要在程式碼中明確建立 Span 與屬性。
- 自動插樁(Auto Instrumentation):不需修改程式碼,搭配特定語言或框架即可自動產生 Telemetry Data,目前覆蓋 .NET、Java、JavaScript、PHP、Python 等主要語言。
由於 Auto Instrumentation 對既有服務的侵入性最低,本章以它為主進行介紹。
自動插樁的資料流向#
當服務套上 Auto Instrumentation 後,整體資料流大致是:
- Auto Instrumentation 自動生成 Telemetry Data 並送出。
- Tracing Backend(如 Zipkin、Jaeger、Tempo)負責收集與儲存。
- 使用者透過對應 UI(Zipkin UI、Jaeger UI、Grafana)查詢與分析。
它通常以 Filter 或 Middleware 的方式套在應用程式外層,自動判斷 Request 是否已帶有 Trace ID,若有則沿用,沒有就生成新的。例如三個串連的服務 APP A → APP B → APP C,當 A、B 都有 Auto Instrumentation 而 C 沒有時,A 與 B 之間的 Span 會以同一組 Trace ID 串聯,但 C 內部就不會被收集。
常用環境變數#
Auto Instrumentation 的設定方式因語言而異,但多半透過環境變數或設定檔。以下是幾個跨語言常用的環境變數:
OTEL_TRACES_EXPORTER:選擇 Trace 傳送方式,例如otlp、jaeger。OTEL_EXPORTER_OTLP_ENDPOINT:OTLP 對應的 Endpoint,例如http://localhost:4317。OTEL_EXPORTER_JAEGER_ENDPOINT:Jaeger 對應的 Endpoint,例如http://localhost:14250。
- 服務名稱可透過下列任一方式設定:
OTEL_SERVICE_NAME:直接指定服務名稱,例如service-a。OTEL_RESOURCE_ATTRIBUTES:以資源屬性方式設定service.name=service-a。
OTEL_PROPAGATORS:設定 Tracing Header 的傳遞格式,可用,串接多個,預設為tracecontext,baggage,跨工具整合時常需調整。
目前內容最完整的環境變數說明是 Java 的 OpenTelemetry SDK Autoconfigure 文件,由於這些變數設計上是跨語言共用,其他語言也可以參考使用。
Log 中加入 Trace ID#
在多執行緒環境下,不同 Request 的 Log 容易交錯,難以追查問題。透過 SDK 與 Log Pattern 的搭配,可以將 Trace ID 寫入 Log,從 Trace 出發後就能用 Trace ID 反查相關 Log。範例如下:
[2021-10-13 10:00:00,000] [INFO] [trace_id=123] [class=Main] [message=Hello World]
[2021-10-13 10:00:01,000] [INFO] [trace_id=456] [class=Worker] [message=Hello World]
[2021-10-13 10:00:02,000] [INFO] [trace_id=456] [class=Worker] [message=Hello World]
[2021-10-13 10:00:03,000] [INFO] [trace_id=123] [class=Worker] [message=Hello World]不同語言有對應的整合方式,例如 Python 透過 OpenTelemetry Logging Instrumentation,Java 則搭配 Log4j、Logback 與 Logger MDC auto-instrumentation。
Python 自動插樁#
在 Python 中啟用 Auto Instrumentation,至少需要安裝以下三類套件:
opentelemetry-distro:一次安裝 API、SDK 與 Instrumentation 的整合套件。opentelemetry-exporter:依後端選擇對應的 Exporter,例如opentelemetry-exporter-otlp或opentelemetry-exporter-jaeger。opentelemetry-instrumentation:針對特定套件或框架的 Instrumentation Library,如 Flask、FastAPI、requests 對應的 instrumentation。
也可以使用 opentelemetry-bootstrap 指令掃描環境並自動安裝對應的 Instrumentation Library:
opentelemetry-bootstrap -a install啟動服務時,使用 opentelemetry-instrument 指令包住原本的 Python 程式:
opentelemetry-instrument python main.py設定方式有兩種,可使用環境變數,也可使用 CLI 參數:
# 使用 Environment Variables
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 opentelemetry-instrument python main.py
# 使用 CLI arguments
opentelemetry-instrument --exporter_otlp_endpoint http://localhost:4317 python main.py完整的 CLI 參數可透過 opentelemetry-instrument --help 查詢。
Java 自動插樁#
Java 的 Auto Instrumentation 支援 Java 8 以上版本,啟動後會自動捕捉服務的進出 Request、外部呼叫與資料庫操作等。啟用方式是在執行時透過 -javaagent 指定 OpenTelemetry Instrumentation for Java 的 agent jar:
java -javaagent:path/to/opentelemetry-javaagent.jar -jar myapp.jar設定方式按優先順序由高到低分為 System Properties、Environment Variables、Configuration File 與 ConfigPropertySource SPI。以指定 OTLP Endpoint 為例:
- System Properties:
java -javaagent:path/to/opentelemetry-javaagent.jar \
-Dotel.exporter.otlp.endpoint=http://localhost:4317 \
-jar myapp.jar- Environment Variables:
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 java -javaagent:path/to/opentelemetry-javaagent.jar -jar myapp.jar- Configuration File:
java -javaagent:path/to/opentelemetry-javaagent.jar \
-Dotel.javaagent.configuration-file=path/to/otel.properties \
-jar myapp.jar對應 otel.properties 內容例如:
otel.exporter.otlp.endpoint=http://localhost:4317小結#
OpenTelemetry SDK 與 Auto Instrumentation 的組合,讓既有服務能夠在最少改動下開始輸出 Trace。對於想要快速導入 Tracing 的團隊,先用自動插樁建立全鏈路骨幹,再針對關鍵業務邏輯補上手動插樁,是相對務實的策略。
原文出處#
- 原書/iThome:https://ithelp.ithome.com.tw/articles/10334220