问题描述
在用 Azure API Management(APIM)做统一 API 网关的场景下,很多人都会遇到这样一个需求:想基于诊断日志(AzureDiagnostics 表)里的数据,把不同产品、不同服务之间的调用关系和性能指标理清楚。比如,一个请求从 APIM 进来,经过 A 服务、B 服务,最后返回——能不能把这条链路上的每一步都串起来,看到每一跳的耗时和结果?

核心问题其实很直接:如果注册在 APIM 上的所有 API 以及后端服务都已经集成了 Application Insights,那么能不能利用 AzureDiagnostics 表里的 CorrelationId 字段作为 TraceId,把一次请求经过的所有服务串联起来,构建出完整的端到端调用链路?
问题解答
答案是:可以,但有个关键点必须搞清楚——CorrelationId 本身并不是最终的那个 TraceId,它更像是进入 Application Insights 调用链的一张“门票”。
真正能在不同服务之间统一追踪的标识,是 Application Insights 里的 operation_Id。两者之间其实有一条固定的映射路径,顺着走就能打通全链路:
AzureDiagnostics.CorrelationId
↓
Application Insights requests 表 customDimensions["Request-Id"](值与 CorrelationId 相同)
↓
requests.operation_Id
↓
所有后端服务的 requests / dependencies / traces / exceptions
第一步:通过 CorrelationId 找到 operation_Id
先把 APIM 的诊断日志和 Application Insights 的请求日志关联起来。直接用下面的查询就能拿到 CorrelationId 对应的 operation_Id:
AzureDiagnostics
| where ResourceType == "APIMANAGEMENT"
| where Category == "GatewayLogs"
| project TimeGenerated, CorrelationId, ApiId, ResponseCode, DurationMs
| join kind=inner ( app('').requests | extend reqId = tostring(customDimensions["Request-Id"]) | project reqId, operation_Id, duration, resultCode
) on $left.CorrelationId == $right.reqId
| project TimeGenerated, CorrelationId, operation_Id, ApiId, ResponseCode, DurationMs
第二步:用 operation_Id 拉取完整调用链
拿到了 operation_Id,接下来就好办了——在 Application Insights 里把同一次请求的所有遥测数据(请求、依赖、异常、跟踪)都捞出来,按时间顺序排好,就能看到完整的调用链。下面这个查询就是干这事儿的:
let targetCorrelationId = "<填入你的 CorrelationId>";
let opId = app('' ).requests | extend reqId = tostring(customDimensions["Request-Id"]) | where reqId == targetCorrelationId | project operation_Id | take 1;
union app('' ).requests, app('' ).dependencies, app('' ).exceptions, app('' ).traces
| where operation_Id in (opId)
| project timestamp, itemType, cloud_RoleName, name, duration, success, operation_ParentId
| order timestamp asc
注意:多个 Application Insights 实例时需要跨资源查询
现实情况往往更复杂——APIM 和各后端服务可能用的不是同一个 Application Insights 实例。这时候,即使 operation_Id 是一致的,如果不把多个实例的遥测数据一起查,就看不到完整的链路。所以,在 union 里要同时引用多个 app() 实例,像这样:
union app('apim-appinsights').requests, app('webapp-appinsights').requests, app('funcapp-appinsights').dependencies
| where operation_Id == ""
| order timestamp asc
参考资料
如果想深入了解,这几个官方文档值得一看:
- 如何将 Azure API 管理与 Azure 应用程序 Insights 集成:https://learn.microsoft.com/zh-cn/azure/api-management/api-management-howto-app-insights?tabs=rest
- 应用程序映射:分类整理分布式应用程序:https://learn.microsoft.com/zh-cn/azure/azure-monitor/app/app-map
- AzureDiagnostics:https://learn.microsoft.com/zh-cn/azure/azure-monitor/reference/tables/azurediagnostics
- 在 Azure Monitor 中跨 Log Analytics 工作区、应用程序和资源查询数据:https://learn.microsoft.com/zh-cn/azure/azure-monitor/logs/cross-workspace-query
