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.

kustoOct 6, 2026MIT

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.

walk-a-trace.kql
// 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.