Snippet
Walk one trace hop by hop in KQL
A complete query that replays one request across services with millisecond offsets, using privacy-safe hop markers.
AI-generated, human-reviewed: the first draft was generated by an AI agent; I fact-checked, tested, and edited it. AI use policy
What it does#
Takes one trace ID and lists every hop marker for it in time order, with milliseconds since the first marker, so the slow hop stands out.
You need#
- A Log Analytics workspace receiving Application Insights telemetry from every hop
- Hop markers: trace messages or dependency names that start with
[FROM-TO], such as the<trace>elements in the gateway policy
Where it goes#
Run it in the Log Analytics workspace’s Logs page. Replace PASTE_TRACE_ID with a trace
ID.
// SPDX-License-Identifier: MIT
// Copyright (c) 2026 Sarang Datye
// [OPS-02] Walk one trace hop by hop
// Paste the trace ID your API returned with an answer.
// Returns only privacy-safe hop markers with millisecond offsets from the first marker.
let traceId = "PASTE_TRACE_ID";
let allowedMarkers = dynamic([
"[SPA-TO-APIM]",
"[APIM-TO-API]",
"[AGENT-TO-AIGATEWAY]",
"[API-TO-SERVICEBUS]",
"[SERVICEBUS-TO-FUNCTION]",
"[FUNCTION-TO-COSMOS]",
"[API-TO-APIM]",
"[APIM-TO-SPA]"
]);
let markers = union isfuzzy=true
(AppTraces
| project TimeGenerated, OperationId, rowType = "trace", AppRoleName,
markerText = Message),
(AppDependencies
| project TimeGenerated, OperationId, rowType = "dependency", AppRoleName,
markerText = Name)
| where OperationId == traceId
| extend marker = extract(@"^\[([A-Z0-9-]+)\]", 0, tostring(markerText))
| where isnotempty(marker) and marker in (allowedMarkers);
let startTime = toscalar(markers | summarize min(TimeGenerated));
markers
| extend offsetMs = datetime_diff("millisecond", TimeGenerated, startTime)
| project offsetMs, TimeGenerated, rowType, AppRoleName, marker
| order by TimeGenerated asc
Check that it works#
Paste the traceId your API returned with an answer. You get one row per hop, ordered, with
offsetMs growing from 0.