App Insights Workbook Export¶
ContributorsMyles Henaghan
Contributors 🕹️ Myles Henaghan
When to use: Export Application Insights values deterministically when the user needs either a known-default payload, an explicit KQL payload, or workbook-derived query execution with reliable subscription checks and Cloud Shell fallback.
Tested on: Azure Cloud Shell and the Azure REST API (ARM query path) only. Not yet tested with a locally installed Azure CLI (
az) — treat local runs as unverified.
Instructions¶
Intent¶
Use this skill to collect reproducible telemetry outputs from Application Insights when local environments can be unreliable, permissions vary by subscription, or workbook definitions differ between environments.
Cloud Shell validation note: in this environment, direct az monitor app-insights query frequently requires a data-plane audience token (https://api.applicationinsights.io) that may not be available to the default Cloud Shell credential. The script now auto-falls back to ARM query execution when this occurs.
Windows/Git Bash validation note: if running from Git Bash on Windows, resource IDs beginning with /subscriptions/... can be path-converted unless MSYS_NO_PATHCONV=1 is set. The script examples below include the safe invocation.
Subscription confirmation first (Cloud Shell and local)¶
Before running any example command, select the intended Azure account context:
az account list --output table
az account set --subscription dev-subscription
az account show --query "{name:name,id:id,isDefault:isDefault}" --output table
If you need a different subscription, replace dev-subscription explicitly.
Deterministic collection flow¶
flowchart TB
A[Parse explicit flags] --> B[Azure CLI preflight]
B --> C{Subscription queryable?}
C -- No --> D[Stop with Cloud Shell fallback steps]
C -- Yes --> E[Resolve appId from component]
E --> F[Probe minimal query]
F --> G{Mode}
G -- default-query --> H[Run built-in Apdex payload]
G -- custom-query --> I[Run caller-provided KQL]
G -- workbook-query --> J[Extract KQL from saved workbook]
H --> K[Return deterministic output]
I --> K
J --> K
Modes to use¶
| Mode | Use when | Required options |
|---|---|---|
default-query |
Need a baseline, controlled payload and cannot save workbook changes | --component-id (use --subscription explicitly for deterministic environment control) |
custom-query |
Query is provided by caller | --component-id, one of --query-text or --query-file (use --subscription explicitly for deterministic environment control) |
workbook-query |
Workbook is already configured and should define the payload | --component-id, one of --workbook-id or --workbook-name (use --subscription explicitly for deterministic environment control) |
Script path¶
Run script from:
library/skills/collect-app-insights-azure/scripts/collect-app-insights.shlibrary/skills/collect-app-insights-azure/scripts/check-role-health.sh— cross-environmentcloud_RoleNamehealth check (see below)
Local execution prerequisites¶
- Required CLIs:
azandjq - Recommended: run from Cloud Shell for cleanest dependency/runtime parity
- Local Windows option: run via Git Bash
Quick checks:
If jq is missing on Windows:
Windows-safe Git Bash invocation¶
Use this wrapper when running locally on Windows to avoid /subscriptions/... path conversion:
& "C:\Program Files\Git\bin\bash.exe" -lc '
export MSYS_NO_PATHCONV=1
cd "/c/<repo-root>"
bash ./library/skills/collect-app-insights-azure/scripts/collect-app-insights.sh \
--subscription <subscription-name-or-id> \
--component-id /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Insights/components/<app-insights-name> \
--mode default-query \
--timespan P30D
'
Minimum required identifiers¶
- Component ID: full Application Insights resource ID
- Workbook ID for strict workbook mode, or workbook display name for lookup
Subscription can be supplied explicitly with --subscription (recommended), or inherited from script defaults/environment.
The portal blade URL ending in /components/<app-id>/workbooks is not itself a saved workbook resource ID. Use --workbook-id for deterministic selection, or --workbook-name for a lookup scoped by sourceId and display name.
Command examples¶
Baseline deterministic payload:
bash library/skills/collect-app-insights-azure/scripts/collect-app-insights.sh \
--subscription dev-subscription \
--component-id /subscriptions/00000000-0000-0000-0000-000000000001/resourceGroups/rg-dev/providers/Microsoft.Insights/components/appi-dev \
--mode default-query \
--timespan P30D \
--apdex-threshold-ms 3000 \
--operation-types pageViews,requests,dependencies \
--output-format json \
--output-file apdex.json
Force ARM execution mode (useful when az monitor app-insights query is unavailable locally):
bash library/skills/collect-app-insights-azure/scripts/collect-app-insights.sh \
--subscription <subscription-name-or-id> \
--component-id /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Insights/components/<app-insights-name> \
--mode default-query \
--query-exec-mode arm \
--timespan P30D \
--output-format json
Starter template for permission-constrained contexts (send explicit query with execution):
bash library/skills/collect-app-insights-azure/scripts/collect-app-insights.sh \
--subscription dev-subscription \
--component-id /subscriptions/00000000-0000-0000-0000-000000000001/resourceGroups/rg-dev/providers/Microsoft.Insights/components/appi-dev \
--mode custom-query \
--timespan P30D \
--query-text "requests | where timestamp > ago(30d) | summarize Total=count(), Successes=countif(tobool(success)), Failures=countif(not(tobool(success)))"
Caller-provided query payload:
bash library/skills/collect-app-insights-azure/scripts/collect-app-insights.sh \
--subscription dev-subscription \
--component-id /subscriptions/00000000-0000-0000-0000-000000000001/resourceGroups/rg-dev/providers/Microsoft.Insights/components/appi-dev \
--mode custom-query \
--query-file ./query.kql \
--timespan P7D
Workbook-derived query execution (when a workbook is already saved and trusted):
bash library/skills/collect-app-insights-azure/scripts/collect-app-insights.sh \
--subscription dev-subscription \
--component-id /subscriptions/00000000-0000-0000-0000-000000000001/resourceGroups/rg-dev/providers/Microsoft.Insights/components/appi-dev \
--mode workbook-query \
--workbook-name "App Performance Index (Apdex)" \
--workbook-item-title "Apdex Score" \
--timespan P30D
Cloud Shell fallback policy¶
If any of the following checks fail locally, stop and move to Cloud Shell:
aznot installedjqnot installedaz account showfailsaz account set --subscription ...fails- subscription read probe fails
- App Insights query probe fails
Cloud Shell run path:
- Open Azure Portal and start Cloud Shell.
- Upload script via Manage files.
- Confirm account context with
az account list --output table. - Set account context with
az account set --subscription dev-subscription. - Run the same command with explicit flags.
Output behavior¶
- Use
--output-format jsonfor table payloads. - Use
--output-format valueto return a scalar cell; when anApdexcolumn exists, the script prefers that value. - Use
--output-file -for stdout (default) or a file path for reproducible artifacts.
Interpreting output quickly¶
- Watch console summary lines first: table count, row count, and the
Result summaryblock. - If
Result summaryincludes Apdex, use that value as the 30-day score for the selected operation types. - Keep full payload output in a file for auditability (for example,
apdex-30d.json).
Validated example artifact from Cloud Shell dev run:
references/example-apdex-30d.json
Cross-environment role health check¶
Use scripts/check-role-health.sh when the question is "is this app healthy right now in dev, test and prod?"
rather than "give me this one metric". It resolves each environment from
references/environments.json, delegates execution to collect-app-insights.sh (so the CLI/ARM fallback is
shared), and folds requests, dependencies, exceptions and traces into one verdict per environment.
Environment config¶
references/environments.json maps a friendly environment name to a subscription and App Insights component ID. The file in this skill is a placeholder — replace the subscription names and component IDs before a real run:
{ "environments": [ { "name": "dev", "subscription": "dev-subscription", "componentId": "/subscriptions/.../components/..." } ] }
Point at a different portfolio with --config <path>.
Interactive wizard¶
Run with no flags on a terminal and the script prompts for scope using the bash select builtin:
- Environment menu — each configured environment plus
all. - Window menu — 1h / 3h / 12h / 24h / 3d / 7d / 30d or a custom ISO-8601 duration. Enter accepts the default of the last 3 hours.
- Role menu — unique
cloud_RoleNamevalues actually observed in the chosen window, aggregated across the selected environments and sorted by signal volume. Accepts a single number, a comma-separated list (1,3), orall.
Pass --env, --timespan and/or --role to skip the matching prompt. --role takes a comma-separated
list and is repeatable. Prompts auto-disable when stdout/stderr are not a TTY; force with --interactive or
suppress with --non-interactive (which falls back to --env all and the PT3H default window).
Non-interactive examples¶
# All three environments, last 30 hours
bash library/skills/collect-app-insights-azure/scripts/check-role-health.sh \
--role pricing-engine --env all --timespan PT30H
# Several roles at once, results grouped per environment then per role
bash library/skills/collect-app-insights-azure/scripts/check-role-health.sh \
--role pricing-engine,report-builder --env dev,test --timespan PT12H
# Subset, machine-readable
bash library/skills/collect-app-insights-azure/scripts/check-role-health.sh \
--role pricing-engine --env dev,prod --output-format json --output-file role-health.json
# Discover role names only
bash library/skills/collect-app-insights-azure/scripts/check-role-health.sh \
--list-roles --env all --timespan P7D
# Gate on freshness as well as errors
bash library/skills/collect-app-insights-azure/scripts/check-role-health.sh \
--role pricing-engine --env prod --max-staleness-minutes 60 --error-rate-threshold 0.02
Status model¶
| Status | Icon | Meaning |
|---|---|---|
healthy |
✅ | Signals present and error rate at or below --error-rate-threshold (default 0.05) |
degraded |
❌ | Error rate above threshold |
no-data |
❓ | No signals for the role in the timespan |
stale |
🕒 | Newest signal older than --max-staleness-minutes (disabled by default) |
error |
⛔ | Collection failed for that environment; re-run with --verbose |
Error rate is errors / total summed across all four signals for that role, where errors are failed
requests, failed dependencies, every exception, and traces with severityLevel >= 3. Each environment takes
the worst status of its roles, and the overall status takes the worst of the environments.
Icons render on a TTY and fall back to ASCII labels when piped; override with --icons / --no-icons.
LAST SEEN is paired with a relative AGE column, and blocks are blank-line separated per environment/role.
Exit codes: 0 all healthy, 1 anything not healthy, 2 usage or config error — so the script drops
straight into a pipeline gate.
References¶
references/workbook-discovery.md— workbook ID discovery patterns and caveatsreferences/environments.json— dev/test/prod App Insights components used by the role health check
Troubleshooting¶
| Symptom | Cause | Action |
|---|---|---|
Missing command: az |
Azure CLI not available locally | Run in Cloud Shell or install Azure CLI |
Missing command: jq |
jq not available locally |
Install jq (for example via winget on Windows) or run in Cloud Shell |
Cannot set subscription |
Wrong subscription value or insufficient access | Verify with az account list --output table, then retry |
/subscriptions/... becomes C:/Program Files/Git/subscriptions/... |
Git Bash path conversion on Windows | Run with MSYS_NO_PATHCONV=1 before invoking script |
unrecognized arguments: --timespan |
Extension version expects --offset/--start-time/--end-time instead |
Use latest script; it auto-detects supported query time flags |
'app-insights' is misspelled or not recognized by the system |
Local Azure CLI lacks app-insights query command group | Use latest script; it auto-falls back to ARM query execution (or force --query-exec-mode arm) |
not a supported MSI token audience |
Cloud Shell credential cannot get App Insights data-plane token | Use latest script; it auto-falls back to ARM query execution |
| Workbook query extraction returns empty | Item title not matched or workbook has no KQL tile | Use --workbook-item-title or switch to custom-query |
| Query returns empty table | Time range or filter too restrictive | Expand --timespan and test with requests | take 1 |
| Output not machine-readable | Wrong output mode selected | Use --output-format json for deterministic parsing |