本文介紹對于Java和Node.js應用如何將TraceId自動寫入HTTP Response Header。
Java應用
默認情況下,TraceId只會在保存在HTTP Requst Header中,如果您需要在HTTP Response Header中設置 TraceId,可參考本文使用OpenTelemetry Java Agent Extension(擴展)以增強OpenTelemetry Java Agent的功能。
本文提供了兩種方法:
方法一:開箱即用。直接使用可觀測鏈路 OpenTelemetry 版已打包好的OpenTelemetry Java Agent擴展,簡單快捷。
方法二:自行實現OpenTelemetry Java Agent擴展。如果可觀測鏈路 OpenTelemetry 版的擴展不滿足您的需求,可以參考此方法實現OpenTelemetry Java Agent擴展并打成JAR包。
方法一:開箱即用
擴展下載地址:ot-java-agent-extension-1.28.0.jar。
可觀測鏈路 OpenTelemetry 版已經實現了簡單的OpenTelemetry Java Agent擴展,在HTTP Response Header中自動添加TraceId
和SpanId
字段,只需要在啟動參數中加載JAR包即可。
使用方法
在原有啟動參數上添加otel.javaagent.extensions
參數:-Dotel.javaagent.extensions=/path/to/opentelemetry-java-agent-extension.jar
。
完整的啟動命令示例:
java -javaagent:path/to/opentelemetry-javaagent.jar \
-Dotel.javaagent.extensions=path/to/opentelemetry-java-agent-extension.jar \
-Dotel.exporter.otlp.headers=Authentication=<token> \
-Dotel.exporter.otlp.endpoint=<endpoint> \
-Dotel.metrics.exporter=none \
-jar your-app.jar
方法二:自行實現OpenTelemetry Java Agent擴展
前提條件
已使用OpenTelemetry Java Agent。
OpenTelemetry Java Agent版本為1.24.0或以上。
編寫OpenTelemetry Java Agent擴展
新建一個項目。
在pom.xml中添加依賴。
Opentelemetry-javaagent的版本需要與您使用的OpenTelemetry Java Agent版本一致。
<dependencies> <dependency> <groupId>com.google.auto.service</groupId> <artifactId>auto-service</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>io.opentelemetry.javaagent</groupId> <artifactId>opentelemetry-javaagent</artifactId> <version>1.28.0</version> <scope>compile</scope> </dependency> </dependencies>
新建AgentHttpResponseCustomizer類,實現HttpServerResponseCustomizer接口。
package org.example; import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.shaded.io.opentelemetry.api.trace.Span; import io.opentelemetry.javaagent.shaded.io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.javaagent.shaded.io.opentelemetry.context.Context; import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseCustomizer; import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseMutator; @AutoService(HttpServerResponseCustomizer.class) public class AgentHttpResponseCustomizer implements HttpServerResponseCustomizer { @Override public <RESPONSE> void customize(Context context, RESPONSE response, HttpServerResponseMutator<RESPONSE> responseMutator) { SpanContext spanContext = Span.fromContext(context).getSpanContext(); String traceId = spanContext.getTraceId(); String spanId = spanContext.getSpanId(); // 在 HTTP Response Header中設置 traceId 和 spanId, Header 字段名可以自定義 responseMutator.appendHeader(response, "TraceId", traceId); responseMutator.appendHeader(response, "SpanId", spanId); } }
構建OpenTelemetry Java Agent擴展。
將程序打包成JAR包,構建后存儲在target目錄下。
mvn clean package
啟動應用時加載OpenTelemetry Java Agent擴展。
在原有啟動參數上添加 otel.javaagent.extensions 參數:
-Dotel.javaagent.extensions=/path/to/opentelemetry-java-agent-extension.jar
。完整的啟動命令示例:
java -javaagent:path/to/opentelemetry-javaagent.jar \ -Dotel.javaagent.extensions=path/to/opentelemetry-java-agent-extension.jar \ -Dotel.exporter.otlp.headers=Authentication=<token> \ -Dotel.exporter.otlp.endpoint=<endpoint> \ -Dotel.metrics.exporter=none -jar yourapp.jar
Node.js應用
(可選)下載示例Demo:node.js-demo。
如果您的Node.js應用已經使用OpenTelemetry接入,則無需下載示例Demo,直接參考下一步修改Node.js應用中的代碼。
修改Demo中HttpInstrumentation的創建代碼。
創建HttpInstrumentation時可以設置HttpInstrumentationConfig參數,參數包括responseHook,該參數允許用戶傳入一個自定義方法的方法,在響應被處理之前添加自定義內容,例如在HTTP Header中添加TraceId。
... // 要被替換的內容 // registerInstrumentations({ // tracerProvider: provider, // instrumentations: [new HttpInstrumentation(), ExpressInstrumentation], // }); const httpInstrumentation = new HttpInstrumentation({ // 添加一個自定義的responseHook responseHook: (span, response) => { // 從當前上下文中獲取traceId, spanId const traceId = span.spanContext().traceId; const spanId = span.spanContext().spanId; // 將traceId, spanId添加到響應標頭中 response.setHeader('TraceId', traceId); response.setHeader('SpanId', spanId); // 返回響應對象 return response; }, }); registerInstrumentations({ tracerProvider: provider, instrumentations: [httpInstrumentation, ExpressInstrumentation], }); ...