You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure APIM入站send-request未关联Application Insights链路追踪

APIM入站段send-request策略无法关联Application Insights全链路问题解决方案

问题现象

  • 构建组合API资源时,在入站(inbound)范围定义了若干send-request策略。可观测性层使用Application Insights,已完成APIM侧集成,全局日志配置为100%采样、verbose详细日志级别、Legacy关联协议,已排除日志采样遗漏问题。目标是实现全服务链路追踪,可在Application Insights「故障」「性能」选项卡下通过事务诊断功能查看完整链路,所有下游.Net C#服务均已独立接入Application Insights。
  • 预期行为:APIM自动为send-request策略调用的所有下游服务注入统一Request-Id标头,在事务诊断视图中呈现完整调用链路。
  • 实际现象:跟踪图仅记录传入APIM的初始请求,完全不展示入站段send-request调用的下游服务;仅backend后端范围通过forward-request发起的转发请求可正常完成依赖关联。
  • 排查确认根因:APIM不会为入站、出站、错误处理区段的send-request策略自动追加链路关联标头,仅forward-request触发的后端转发会自动注入关联头。

常见临时方案的缺陷

网上流传的全局手动加set-header方案配置如下:

<set-header name="Request-Id" exists-action="skip">
   <value>@(context.RequestId.ToString())</value>
</set-header>

该方案配合send-request的mode="copy"属性、或在send-request内单独配置set-header看似可生效,但存在致命可靠性问题:

  • 仅当客户端原始请求强制携带合法Request-Id标头时才能正常关联,链路追踪能力完全依赖调用方正确传头,生产环境不可用。
  • 若调用方未传递该标头,context.RequestId解析出的值与APIM上报到Application Insights的Operation Id完全不一致,直接导致链路断裂,依赖关系无法展示。

注:此处讨论的是Application Insights分布式链路追踪能力,并非设置Ocp-Apim-Trace: true后存储在Blob的APIM内置跟踪日志,后者本身可正常运行。

复现问题的参考配置

全局策略(仅配置CORS)

<policies>
<inbound>
    <cors allow-credentials="true">
        <allowed-origins>
            <origin>https://api.website.com</origin>
        </allowed-origins>
        <allowed-methods preflight-result-max-age="300">
            <method>*</method>
        </allowed-methods>
        <allowed-headers>
            <header>*</header>
        </allowed-headers>
        <expose-headers>
            <header>*</header>
        </expose-headers>
    </cors>
</inbound>
<backend>
    <forward-request />
</backend>
<outbound />
<on-error />
</policies>

API范围默认策略

<policies>
<inbound>
    <base />
</inbound>
<backend>
    <base />
</backend>
<outbound>
    <base />
</outbound>
<on-error>
    <base />
</on-error>
</policies>

端点入站段send-request示例策略

<policies>
<inbound>
    <base />
    <!-- 入站范围内的send-request不会自动携带Request-Id,无链路追踪记录 -->
    <send-request mode="copy" response-variable-name="service1" timeout="10" ignore-error="false">
        <set-url>myservice</set-url>
        <set-method>POST</set-method>
        <set-header name="Content-Type" exists-action="override">
            <value>application/json</value>
        </set-header>
        <set-body>"hello": "world"</set-body>
    </send-request>
</inbound>
<backend>
    <base />
    <!-- 后端块内的forward-request无需额外配置即可自动获得正确关联头 -->
</backend>
<outbound>
    <base />
</outbound>
<on-error>
    <base />
</on-error>
</policies>

可落地的修复方案

该问题不属于配置疏漏,是APIM Legacy关联模式下的已知设计行为,可通过以下配置100%修复,不依赖客户端传头:
核心逻辑是直接使用APIM内部生成、与Application Insights Operation Id完全一致的context.TraceId属性构造关联头,不使用和客户端传头绑定的context.RequestId。

  1. 全局入站策略最前端初始化链路标识,无论客户端是否传头,都以APIM自身生成的TraceId为链路根Id:
    <inbound>
        <!-- 最先执行,初始化全局链路标识,不受客户端传入头影响 -->
        <set-variable name="operationRootId" value="@(context.TraceId)" />
        <!-- 原有CORS、鉴权等其他全局配置放在后面 -->
        <cors allow-credentials="true">
        <!-- 省略原有CORS配置内容 -->
        </cors>
    </inbound>
    
  2. 所有send-request策略内部强制注入关联头,不要依赖mode="copy"复制原始请求头,不要使用exists-action="skip"逻辑:
    <send-request mode="new" response-variable-name="service1" timeout="10" ignore-error="false">
        <set-url>myservice</set-url>
        <set-method>POST</set-method>
        <!-- 强制注入Legacy协议关联头,适配旧版.Net Application Insights SDK -->
        <set-header name="Request-Id" exists-action="override">
            <value>@($"|{(string)context.Variables["operationRootId"]}.{Guid.NewGuid().ToString("N").Substring(0,16)}")</value>
        </set-header>
        <!-- 强制注入W3C标准traceparent头,适配新版SDK -->
        <set-header name="traceparent" exists-action="override">
            <value>@($"00-{(string)context.Variables["operationRootId"]}-{Guid.NewGuid().ToString("N").Substring(0,16)}-00")</value>
        </set-header>
        <set-header name="Content-Type" exists-action="override">
            <value>application/json</value>
        </set-header>
        <set-body>"hello": "world"</set-body>
    </send-request>
    
  3. 侧配置校验
    • 确认APIM的Application Insights集成设置中,关闭「优先使用客户端传入的关联标头」选项,确保APIM始终以自身生成的TraceId作为Operation Id
    • 下游.Net服务无需修改代码,新旧版本Application Insights SDK可自动识别上述两种关联头,完成链路拼接
    • 如果后续将关联协议从Legacy切换为W3C标准,仅保留traceparent头注入即可,无需再传递Request-Id

避坑说明

  • 禁止使用context.RequestId作为关联值:该属性值仅在客户端传入合法Request-Id时与Operation Id一致,客户端未传时会生成独立的随机Guid,直接导致链路断裂
  • 禁止依赖mode="copy"复制请求头:客户端未传关联头时,send-request发出的请求不会携带任何关联标识
  • 禁止使用exists-action="skip"配置:该逻辑会优先使用客户端传入的标头,可能被客户端传入的无效Id打断完整链路

内容的提问来源于stack exchange,提问作者Equestre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 05:15:31