Clusters pbiclients.eastus + pbiclientseu.northeurope ·
Database appinsights.
Standardized-report and App-Insights data are partitioned regionally. Each query below uses union across both clusters so totals match the dashboard. Click any tab to view the exact KQL.
Q1 · Impressions (Spark + permission)
Q2 · FixWithCopilot clicks
Q3 · Fix → Undo (10 min)
Q4 · Impressions by env
Q5 · Top tenants
Q6 · Failure analysis
Q7 · Path A (exact impressions)
// === Path B: approximate "Diagnose with Copilot" impressions (Spark + permission, 30 d) ===
// Standardized-report data is split between two regional clusters. Use the union form
// so the query covers both. If the cross-cluster channel is unavailable for your
// principal, run the query against each cluster separately and sum the result.
let lookback = 30d;
let scr =
union
cluster('pbiclients.eastus').database('appinsights').StandardizedClientReporting,
cluster('pbiclientseu.northeurope').database('appinsights').StandardizedClientReporting;
let ev =
union
cluster('pbiclients.eastus').database('appinsights').customEvents,
cluster('pbiclientseu.northeurope').database('appinsights').customEvents;
let failedCells =
ev
| where timestamp > ago(lookback)
| where name == 'DiagnosticTrace'
| extend
componentName = tostring(customDimensions.TL_componentName),
message = tostring(customDimensions.TL_message),
state = tostring(customDimensions.TU_state),
artifactId = tostring(customDimensions.TU_artifactId),
tabId = tostring(customDimensions.browserTabId),
tenantId = tostring(customDimensions.customerTenantId)
| where componentName == 'Notebook.NotebookFileView'
| where message == 'Finish to run Notebook code cell'
| where state == 'failed'
| extend hourBucket = bin(timestamp, 1h);
let sparkTabHours =
scr
| where Timestamp > ago(lookback)
| where ActivityName == 'RunNotebookCodeCell'
| extend hourBucket = bin(Timestamp, 1h)
| distinct BrowserTabId, hourBucket;
let nonSparkTabHours =
scr
| where Timestamp > ago(lookback)
| where ActivityName in ('RunPythonNotebookCodeCell', 'runTSQLNotebookCodeCell')
| extend hourBucket = bin(Timestamp, 1h)
| distinct BrowserTabId, hourBucket;
// (artifact, hour) windows where the Copilot license check confirmed "no access"
// for the user. The button cannot render in these windows.
// Note: FullAccess is not logged — only the Disallowed / region-limited / final-error cases
// are written, so this list is the precise set of windows we need to exclude.
let noCopilotArtifactHours =
ev
| where timestamp > ago(lookback)
| where tostring(customDimensions.TL_extensionName) == 'DES'
| where tostring(customDimensions.TL_componentName) == 'LLMEndpointTenantSettings.checkAccess'
| extend level = tostring(customDimensions.TL_level),
message = tostring(customDimensions.TL_message)
| where (level == 'warning' and message in ('Copilot is currently limited to certain regions for your organization',
'Valid copilot license, but one or more models are disallowed'))
or (level == 'error' and message == 'failed to check copilot license')
| extend artifactId = tostring(customDimensions.TU_artifactId),
hourBucket = bin(timestamp, 1h)
| where isnotempty(artifactId)
| distinct artifactId, hourBucket;
failedCells
| join kind=leftsemi sparkTabHours on $left.tabId == $right.BrowserTabId, hourBucket
| join kind=leftanti nonSparkTabHours on $left.tabId == $right.BrowserTabId, hourBucket
| join kind=leftanti noCopilotArtifactHours on artifactId, hourBucket
| summarize
Impressions = count(),
Users = dcount(user_Id),
Notebooks = dcount(artifactId),
Tabs = dcount(tabId),
Tenants = dcount(tenantId)
by dayBucket = bin(timestamp, 1d)
| order by dayBucket asc
// === FixWithCopilot clicks (30 d), union of both standardized-report clusters ===
union
cluster('pbiclients.eastus').database('appinsights').StandardizedClientReporting,
cluster('pbiclientseu.northeurope').database('appinsights').StandardizedClientReporting
| where Timestamp > ago(30d)
| where ActivityName == 'FixWithCopilot'
| where FeatureName == 'NotebookCopilot'
| summarize
Clicks = count(),
Succeeded = countif(ActivityStatus == 'Succeeded'),
Failed = countif(ActivityStatus == 'Failed'),
Users = dcount(ExecutingUserObjectId),
Tenants = dcount(CustomerTenantId),
Tabs = dcount(BrowserTabId)
by dayBucket = bin(Timestamp, 1d)
| order by dayBucket asc
// === Fix -> Undo correlation (10-min window, 30 d) ===
let lookback = 30d;
let scr =
union
cluster('pbiclients.eastus').database('appinsights').StandardizedClientReporting,
cluster('pbiclientseu.northeurope').database('appinsights').StandardizedClientReporting;
let fixes =
scr
| where Timestamp > ago(lookback)
| where ActivityName == 'FixWithCopilot' and FeatureName == 'NotebookCopilot'
| project FixTime = Timestamp, BrowserTabId, FixUser = ExecutingUserObjectId, FixTenant = CustomerTenantId;
let undos =
scr
| where Timestamp > ago(lookback)
| where ActivityName == 'UndoChanges' and FeatureName == 'NotebookCopilot'
| extend UndoId = strcat(BrowserTabId, '|', tostring(Timestamp))
| project UndoId, UndoTime = Timestamp, BrowserTabId, UndoUser = ExecutingUserObjectId, UndoTenant = CustomerTenantId;
undos
| join kind=inner fixes on BrowserTabId
| where FixTime <= UndoTime and datetime_diff('minute', UndoTime, FixTime) <= 10
| summarize arg_max(FixTime, FixUser, FixTenant) by UndoId, UndoTime, BrowserTabId, UndoUser, UndoTenant
| summarize
UndoAfterFix = count(),
Users = dcount(UndoUser),
Tabs = dcount(BrowserTabId),
Tenants = dcount(UndoTenant)
by dayBucket = bin(UndoTime, 1d)
| order by dayBucket asc
// === Impressions by env (Spark + permission, 30 d) ===
let lookback = 30d;
let scr =
union
cluster('pbiclients.eastus').database('appinsights').StandardizedClientReporting,
cluster('pbiclientseu.northeurope').database('appinsights').StandardizedClientReporting;
let ev =
union
cluster('pbiclients.eastus').database('appinsights').customEvents,
cluster('pbiclientseu.northeurope').database('appinsights').customEvents;
let failedCells =
ev
| where timestamp > ago(lookback)
| where name == 'DiagnosticTrace'
| extend
componentName = tostring(customDimensions.TL_componentName),
message = tostring(customDimensions.TL_message),
state = tostring(customDimensions.TU_state),
artifactId = tostring(customDimensions.TU_artifactId),
tabId = tostring(customDimensions.browserTabId),
env = tostring(customDimensions.TL_environment)
| where componentName == 'Notebook.NotebookFileView'
| where message == 'Finish to run Notebook code cell' and state == 'failed'
| extend hourBucket = bin(timestamp, 1h);
let sparkTabs = scr | where Timestamp > ago(lookback) | where ActivityName == 'RunNotebookCodeCell' | extend hourBucket = bin(Timestamp, 1h) | distinct BrowserTabId, hourBucket;
let nonSparkTabs = scr | where Timestamp > ago(lookback) | where ActivityName in ('RunPythonNotebookCodeCell','runTSQLNotebookCodeCell') | extend hourBucket = bin(Timestamp, 1h) | distinct BrowserTabId, hourBucket;
let noCopilotArtifactHours =
ev
| where timestamp > ago(lookback)
| where tostring(customDimensions.TL_extensionName) == 'DES'
| where tostring(customDimensions.TL_componentName) == 'LLMEndpointTenantSettings.checkAccess'
| extend level = tostring(customDimensions.TL_level), message = tostring(customDimensions.TL_message)
| where (level == 'warning' and message in ('Copilot is currently limited to certain regions for your organization',
'Valid copilot license, but one or more models are disallowed'))
or (level == 'error' and message == 'failed to check copilot license')
| extend artifactId = tostring(customDimensions.TU_artifactId), hourBucket = bin(timestamp, 1h)
| where isnotempty(artifactId)
| distinct artifactId, hourBucket;
failedCells
| join kind=leftsemi sparkTabs on $left.tabId == $right.BrowserTabId, hourBucket
| join kind=leftanti nonSparkTabs on $left.tabId == $right.BrowserTabId, hourBucket
| join kind=leftanti noCopilotArtifactHours on artifactId, hourBucket
| summarize Impressions = count(), Users = dcount(user_Id), Notebooks = dcount(artifactId) by env
| order by Impressions desc
// === Top tenants by FixWithCopilot clicks (30 d), both clusters ===
union
cluster('pbiclients.eastus').database('appinsights').StandardizedClientReporting,
cluster('pbiclientseu.northeurope').database('appinsights').StandardizedClientReporting
| where Timestamp > ago(30d)
| where ActivityName == 'FixWithCopilot' and FeatureName == 'NotebookCopilot'
| where isnotempty(CustomerTenantId)
| summarize Clicks = count(), Users = dcount(ExecutingUserObjectId), Tabs = dcount(BrowserTabId) by CustomerTenantId
| order by Clicks desc
| take 10
// === FixWithCopilot failure analysis (30 d), both clusters ===
let lookback = 30d;
let scr =
union
cluster('pbiclients.eastus').database('appinsights').StandardizedClientReporting,
cluster('pbiclientseu.northeurope').database('appinsights').StandardizedClientReporting;
scr
| where Timestamp > ago(lookback)
| where ActivityName == 'FixWithCopilot' and FeatureName == 'NotebookCopilot'
| where ActivityStatus == 'Failed'
| extend bucket = case(
DurationMs <= 5000, 'A. Quick failure (\u22645s) \u2014 synchronous throw',
DurationMs <= 50000, 'B. Backend failure (5-50s) \u2014 sendMessage rejected early',
DurationMs <= 70000, 'C. Chat-pane init timeout (~60s)',
DurationMs <= 180000, 'D. sendMessage failure (70-180s)',
DurationMs <= 600000, 'E. Stuck request (3-10 min)',
'F. Extreme (>10 min)')
| summarize
Failures = count(),
Users = dcount(ExecutingUserObjectId),
Tenants = dcount(CustomerTenantId)
by bucket
| order by bucket asc
// Duration overview: median ok vs median fail (the 60s spike is unmistakable)
scr
| where Timestamp > ago(30d)
| where ActivityName == 'FixWithCopilot' and FeatureName == 'NotebookCopilot'
| summarize
Events = count(),
p50_ms = percentile(DurationMs, 50),
p90_ms = percentile(DurationMs, 90),
p99_ms = percentile(DurationMs, 99)
by ActivityStatus
// Per-OS failure rate
scr
| where Timestamp > ago(30d)
| where ActivityName == 'FixWithCopilot' and FeatureName == 'NotebookCopilot'
| summarize
Clicks = count(),
Failed = countif(ActivityStatus == 'Failed')
by OperatingSystemName
| extend FailPct = round(100.0 * Failed / Clicks, 2)
| where Clicks >= 10
| order by Clicks desc
// === Path A: exact impression query (after instrumentation) ===
//
// Inside packages/@synapse/spark-notebook-extensions/src/components/cellMonitor/CopilotFixErrorButton.tsx:
//
// const logger = getLogger('CellMonitor.CopilotFixErrorButton');
// const showFixButton = useMemo(() => {
// const visible = isCopilotEnabledForUser
// && statementMeta?.statementId
// && copilotState !== CopilotState.Hidden
// && canShowFixButton(...);
// if (visible) logger.event('CopilotFixButtonShown', { artifactId, cellId });
// return visible;
// }, [...]);
//
union
cluster('pbiclients.eastus').database('appinsights').customEvents,
cluster('pbiclientseu.northeurope').database('appinsights').customEvents
| where timestamp > ago(30d)
| where name == 'DiagnosticTrace'
| extend componentName = tostring(customDimensions.TL_componentName),
message = tostring(customDimensions.TL_message),
env = tostring(customDimensions.TL_environment)
| where componentName has 'CellMonitor.CopilotFixErrorButton'
| where message == 'CopilotFixButtonShown'
| summarize Impressions = count(), Users = dcount(user_Id) by env, dayBucket = bin(timestamp, 1d)
| order by dayBucket asc, env asc