使用自定义遥测修复Linux环境Java Azure Functions端到端链路追踪
解决方案
方案可行性评估
你的整体思路符合链路追踪的W3C Trace Context规范,方向是对的,不生效的原因是你修改的RequestTelemetryContext仅属于Application Insights的局部上下文,优先级低于Azure Functions Linux运行时生成的默认追踪上下文,无法覆盖自动遥测的关联属性。
具体实现步骤
1. 应用A侧(func_A_2)传递标准追踪头
不需要手动解析traceparent,直接将W3C标准追踪头完整注入HTTP POST请求头即可,避免解析出错:
// 从函数执行上下文获取追踪信息 TraceContext traceCtx = executionContext.getTraceContext(); // 构造请求头 HttpHeaders headers = new HttpHeaders(); headers.add("traceparent", traceCtx.getTraceparent()); traceCtx.getTracestate().ifPresent(ts -> headers.add("tracestate", ts)); // 后续正常发起HTTP POST请求到应用B
2. 应用B侧(func_B_1)覆盖全局追踪上下文
Azure Functions Java的ExecutionContext本身是只读的,无法直接修改,需要通过OpenTelemetry的活动上下文接口设置全局追踪上下文,后续所有Azure自动生成的遥测(包括Service Bus触发的后续函数链路)都会自动继承该上下文:
import com.microsoft.applicationinsights.core.dependencies.io.opentelemetry.api.trace.Span; import com.microsoft.applicationinsights.core.dependencies.io.opentelemetry.api.trace.SpanContext; import com.microsoft.applicationinsights.core.dependencies.io.opentelemetry.api.trace.TraceFlags; import com.microsoft.applicationinsights.core.dependencies.io.opentelemetry.context.Scope; // 从入站请求头中获取traceparent String traceparent = request.getHeaders().get("traceparent"); String[] traceParts = traceparent.split("-"); String traceId = traceParts[1]; // 对应你的Operation ID AAA String parentSpanId = traceParts[2]; // 对应func_A_2的Span ID 2 TraceFlags traceFlags = TraceFlags.fromHex(traceParts[3], 0); // 构造来自应用A的父链路上下文 SpanContext remoteParentCtx = SpanContext.createFromRemoteParent( traceId, parentSpanId, traceFlags, TraceState.getDefault() ); // 将父上下文设置为当前线程的活动上下文 Span parentSpan = Span.wrap(remoteParentCtx); try (Scope ignored = parentSpan.makeCurrent()) { // 把func_B_1所有业务逻辑都放在这个代码块内 // 包括触发Service Bus调用func_B_2的逻辑 // 该代码块内所有自动生成的遥测都会自动继承traceId和parentSpanId }
3. 补全跨应用HTTP调用节点(可选)
如果需要在链路中显示你提到的HTTP POST节点,可以在上述try代码块开头手动上报一条依赖遥测:
import com.microsoft.applicationinsights.TelemetryClient; import com.microsoft.applicationinsights.telemetry.DependencyTelemetry; TelemetryClient telemetryClient = new TelemetryClient(); DependencyTelemetry httpCall = new DependencyTelemetry(); httpCall.setName("HTTP POST"); httpCall.setType("Http"); httpCall.setSuccess(true); httpCall.getContext().getOperation().setId(traceId); httpCall.setParentId(parentSpanId); telemetryClient.trackDependency(httpCall);
必要配置检查
- 两个应用都使用Application Insights Java Agent 3.x版本,且开启W3C追踪:环境变量
APPLICATIONINSIGHTS_ENABLE_W3C_TRACING设置为true - Azure Functions Linux运行时版本为4.x及以上,低版本存在W3C上下文传递的已知问题
- 关闭应用B的自动HTTP请求追踪覆盖,避免生成多余的链路节点
内容的提问来源于stack exchange,提问作者Anders Nørløv Berthelsen
相关产品推荐
相关产品推荐

