Skip to main content

Asking Questions of the Data

Everything the app tracks lands in Application Insights, where you interrogate it with KQL (Kusto Query Language). If you've never written KQL: it reads top-to-bottom as a pipeline. Start from a table (customEvents), then each | filters, reshapes, or aggregates what flows through — like Unix pipes for telemetry. That one idea is 80% of KQL; the recipes below are the rest.

Open the Azure portal → the App Insights resource → Logs, paste a recipe, adjust, run. Remember two facts from the overview: events arrive with a 2–5 minute lag, and history runs 90 days deep.

1. All Clicks in a Session

customEvents
| where name == "UserClick"
| where session_Id == "YOUR_SESSION_ID"
| order by timestamp asc
| project timestamp, actionName = tostring(customDimensions.actionName), parentContext = tostring(customDimensions.parentContext)

2. Most Common User Actions

customEvents
| where name == "UserClick"
| summarize clickCount = count() by actionName = tostring(customDimensions.actionName)
| order by clickCount desc
| take 20
| render barchart

3. Click Heatmap by Component

customEvents
| where name == "UserClick"
| summarize clicks = count() by component = tostring(customDimensions.parentContext)
| order by clicks desc
| render piechart

4. Session Flow Analysis

customEvents
| where name == "UserClick"
| summarize actions = make_list(tostring(customDimensions.actionName)) by session_Id
| extend actionCount = array_length(actions)
| where actionCount >= 3
| project session_Id, actionCount, actions
| take 100

5. Time Between Clicks

customEvents
| where name == "UserClick"
| order by session_Id, timestamp asc
| extend prevTimestamp = prev(timestamp, 1)
| extend prevSession = prev(session_Id, 1)
| where session_Id == prevSession
| extend timeBetweenClicks = datetime_diff('second', timestamp, prevTimestamp)
| summarize avgTime = avg(timeBetweenClicks), maxTime = max(timeBetweenClicks) by actionName = tostring(customDimensions.actionName)
| order by avgTime desc

6. Feature Funnel Analysis

customEvents
| where name startswith "Feature_"
| summarize
started = countif(tostring(customDimensions.action) == "started"),
completed = countif(tostring(customDimensions.action) == "completed"),
abandoned = countif(tostring(customDimensions.action) == "abandoned")
by featureName = tostring(customDimensions.featureName)
| extend completionRate = round(100.0 * completed / started, 1)

7. Error Rate by Action

customEvents
| where name == "UserClick"
| join kind=leftouter (exceptions | project session_Id, timestamp, errorType = type) on session_Id
| summarize errorCount = countif(isnotempty(errorType)), clickCount = count() by actionName = tostring(customDimensions.actionName)
| extend errorRate = 100.0 * errorCount / clickCount
| order by errorRate desc