Skip to content

Commit 7a9936d

Browse files
fix bug with telemetry to pass correct metrics and record stage based failures (#1504)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 3a8ee96 commit 7a9936d

3 files changed

Lines changed: 31 additions & 17 deletions

File tree

src/common/telemetry/constants.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ export enum EventNames {
6565
* the timer is cancelled and this event never fires.
6666
* Properties:
6767
* - failureStage: string (which phase was in progress when the watchdog fired)
68+
* Measures:
69+
* - duration: total elapsed since activation
70+
* - stageDuration: elapsed in the current stage
6871
*/
6972
SETUP_HANG_DETECTED = 'SETUP.HANG_DETECTED',
7073
/**
@@ -103,12 +106,10 @@ export enum EventNames {
103106
ENV_SELECTION_RESULT = 'ENV_SELECTION.RESULT',
104107
/**
105108
* Telemetry event fired when applyInitialEnvironmentSelection returns.
106-
* Duration measures the blocking time (excludes deferred global scope).
107109
* Properties:
108-
* - globalScopeDeferred: boolean (true = global scope fired in background, false = awaited)
109-
* - workspaceFolderCount: number (total workspace folders)
110-
* - resolvedFolderCount: number (folders that resolved with a non-undefined env)
111-
* - settingErrorCount: number (user-configured settings that could not be applied)
110+
* - globalScopeDeferred: boolean (true = global scope fired in background)
111+
* Measures:
112+
* - duration, workspaceFolderCount, resolvedFolderCount, settingErrorCount
112113
*/
113114
ENV_SELECTION_COMPLETED = 'ENV_SELECTION.COMPLETED',
114115
/**
@@ -381,7 +382,8 @@ export interface IEventNamePropertyMapping {
381382
/* __GDPR__
382383
"setup.hang_detected": {
383384
"failureStage": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "owner": "StellaHuang95" },
384-
"<duration>": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "StellaHuang95" }
385+
"<duration>": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "eleanorjboyd" },
386+
"<stageDuration>": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "eleanorjboyd" }
385387
}
386388
*/
387389
[EventNames.SETUP_HANG_DETECTED]: {
@@ -451,9 +453,6 @@ export interface IEventNamePropertyMapping {
451453
*/
452454
[EventNames.ENV_SELECTION_COMPLETED]: {
453455
globalScopeDeferred: boolean;
454-
workspaceFolderCount: number;
455-
resolvedFolderCount: number;
456-
settingErrorCount: number;
457456
};
458457

459458
/* __GDPR__

src/extension.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@ export async function activate(context: ExtensionContext): Promise<PythonEnviron
552552
*/
553553
setImmediate(async () => {
554554
let failureStage = 'nativeFinder';
555+
const stageWatch = new StopWatch();
555556
// Watchdog: fires if setup hasn't completed within 120s, indicating a likely hang
556557
const SETUP_HANG_TIMEOUT_MS = 120_000;
557558
let hangWatchdogActive = true;
@@ -568,7 +569,11 @@ export async function activate(context: ExtensionContext): Promise<PythonEnviron
568569
}
569570
hangWatchdogActive = false;
570571
traceError(`Setup appears hung during stage: ${failureStage}`);
571-
sendTelemetryEvent(EventNames.SETUP_HANG_DETECTED, start.elapsedTime, { failureStage });
572+
sendTelemetryEvent(
573+
EventNames.SETUP_HANG_DETECTED,
574+
{ duration: start.elapsedTime, stageDuration: stageWatch.elapsedTime },
575+
{ failureStage },
576+
);
572577
}, SETUP_HANG_TIMEOUT_MS);
573578
context.subscriptions.push({ dispose: clearHangWatchdog });
574579
try {
@@ -592,6 +597,7 @@ export async function activate(context: ExtensionContext): Promise<PythonEnviron
592597
sysPythonManager.resolve(sysMgr);
593598
// Each manager registers independently — one failure must not block the others.
594599
failureStage = 'managerRegistration';
600+
stageWatch.reset();
595601
await Promise.all([
596602
safeRegister(
597603
'system',
@@ -611,14 +617,17 @@ export async function activate(context: ExtensionContext): Promise<PythonEnviron
611617
]);
612618

613619
failureStage = 'envSelection';
620+
stageWatch.reset();
614621
await applyInitialEnvironmentSelection(envManagers, projectManager, nativeFinder, api, start.elapsedTime);
615622

616623
// Register manager-agnostic terminal watcher for package-modifying commands
617624
failureStage = 'terminalWatcher';
625+
stageWatch.reset();
618626
registerTerminalPackageWatcher(api, terminalActivation, outputChannel, context.subscriptions);
619627

620628
// Register listener for interpreter settings changes for interpreter re-selection
621629
failureStage = 'settingsListener';
630+
stageWatch.reset();
622631
context.subscriptions.push(
623632
registerInterpreterSettingsChangeListener(envManagers, projectManager, nativeFinder, api),
624633
);

src/features/interpreterSelection.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -395,13 +395,19 @@ export async function applyInitialEnvironmentSelection(
395395
await notifyUserOfSettingErrors(allErrors);
396396
}
397397

398-
// Duration measures blocking time only (excludes deferred global scope).
399-
sendTelemetryEvent(EventNames.ENV_SELECTION_COMPLETED, selectionStopWatch.elapsedTime, {
400-
globalScopeDeferred: workspaceFolderResolved,
401-
workspaceFolderCount: folders.length,
402-
resolvedFolderCount,
403-
settingErrorCount: allErrors.length,
404-
});
398+
// Numeric values must go via the measures argument (properties are dropped).
399+
sendTelemetryEvent(
400+
EventNames.ENV_SELECTION_COMPLETED,
401+
{
402+
duration: selectionStopWatch.elapsedTime,
403+
workspaceFolderCount: folders.length,
404+
resolvedFolderCount,
405+
settingErrorCount: allErrors.length,
406+
},
407+
{
408+
globalScopeDeferred: workspaceFolderResolved,
409+
},
410+
);
405411
}
406412

407413
/**

0 commit comments

Comments
 (0)