Skip to content

Commit ca51c2d

Browse files
eleanorjboydCopilot
andcommitted
feat: capture PET RefreshPerformance breakdown and locator timings in pet.refresh telemetry
PET already sends a 'telemetry' JSON-RPC notification with RefreshPerformance data after each refresh call. We were discarding it. Now we listen for it and include the per-phase and per-locator timings in our pet.refresh event. New fields on pet.refresh: - breakdownLocators / breakdownPath / breakdownGlobalVirtualEnvs / breakdownWorkspaces (isMeasurement, ms) — the 4 parallel discovery phases from PET's breakdown map - locatorsJson (string) — JSON-serialized per-locator durations (Conda, WindowsRegistry, WindowsStore, etc.); query in Kusto with parse_json(Properties.locatorsJson) This lets us slice slow-cohort p90s by locator/phase to answer which Windows discovery path is responsible for the 11% slowdown (WindowsRegistry, WindowsStore, Conda, etc.) without any changes on PET's side. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 5cc5162 commit ca51c2d

2 files changed

Lines changed: 47 additions & 0 deletions

File tree

src/common/telemetry/constants.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,11 @@ export interface IEventNamePropertyMapping {
518518
"searchPathCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "eleanorjboyd" },
519519
"attempt": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "eleanorjboyd" },
520520
"errorType": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "owner": "eleanorjboyd" },
521+
"breakdownLocators": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true, "owner": "eleanorjboyd" },
522+
"breakdownPath": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true, "owner": "eleanorjboyd" },
523+
"breakdownGlobalVirtualEnvs": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true, "owner": "eleanorjboyd" },
524+
"breakdownWorkspaces": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true, "owner": "eleanorjboyd" },
525+
"locatorsJson": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "owner": "eleanorjboyd" },
521526
"<duration>": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "eleanorjboyd" }
522527
}
523528
*/
@@ -529,6 +534,16 @@ export interface IEventNamePropertyMapping {
529534
searchPathCount?: number;
530535
attempt: number;
531536
errorType?: string;
537+
/** ms spent in the Locators phase (runs locator plugins). From PET RefreshPerformance.breakdown. */
538+
breakdownLocators?: number;
539+
/** ms spent walking PATH entries. From PET RefreshPerformance.breakdown. */
540+
breakdownPath?: number;
541+
/** ms spent scanning global virtual-env dirs. From PET RefreshPerformance.breakdown. */
542+
breakdownGlobalVirtualEnvs?: number;
543+
/** ms spent scanning workspace dirs. From PET RefreshPerformance.breakdown. */
544+
breakdownWorkspaces?: number;
545+
/** JSON-serialized Record<locatorName, ms>. Query with parse_json() in Kusto. From PET RefreshPerformance.locators. */
546+
locatorsJson?: string;
532547
};
533548

534549
/* __GDPR__

src/managers/common/nativePythonFinder.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,23 @@ interface RefreshOptions {
182182
searchPaths?: string[];
183183
}
184184

185+
/** Performance breakdown sent by PET via the `telemetry` notification after a refresh. */
186+
interface RefreshPerformance {
187+
total: number;
188+
/** Phase name (Locators | Path | GlobalVirtualEnvs | Workspaces) → wall-clock ms */
189+
breakdown: Record<string, number>;
190+
/** Locator name (Conda | WindowsRegistry | …) → wall-clock ms; only ran locators are present */
191+
locators: Record<string, number>;
192+
}
193+
194+
/** Params shape of the PET `telemetry` JSON-RPC notification. */
195+
interface PetTelemetryNotification {
196+
event: string;
197+
data: {
198+
refreshPerformance?: RefreshPerformance;
199+
};
200+
}
201+
185202
/**
186203
* Error thrown when a JSON-RPC request times out.
187204
*/
@@ -673,6 +690,7 @@ class NativePythonFinderImpl implements NativePythonFinder {
673690
const nativeInfo: NativeInfo[] = [];
674691
const sw = new StopWatch();
675692
let unresolvedCount = 0;
693+
let refreshPerf: RefreshPerformance | undefined;
676694
try {
677695
await this.configure();
678696
const refreshOptions = this.getRefreshOptions(options);
@@ -708,6 +726,11 @@ class NativePythonFinderImpl implements NativePythonFinder {
708726
this.outputChannel.info(`Discovered manager: (${data.tool}) ${data.executable}`);
709727
nativeInfo.push(data);
710728
}),
729+
this.connection.onNotification('telemetry', (notification: PetTelemetryNotification) => {
730+
if (notification?.event === 'RefreshPerformance' && notification.data?.refreshPerformance) {
731+
refreshPerf = notification.data.refreshPerformance;
732+
}
733+
}),
711734
);
712735
await sendRequestWithTimeout<{ duration: number }>(
713736
this.connection,
@@ -730,6 +753,15 @@ class NativePythonFinderImpl implements NativePythonFinder {
730753
workspaceDirCount,
731754
searchPathCount,
732755
attempt,
756+
// Per-phase breakdown from PET's RefreshPerformance notification.
757+
// Breakdown phases run in parallel so their sum may exceed total (wall-clock).
758+
breakdownLocators: refreshPerf?.breakdown['Locators'],
759+
breakdownPath: refreshPerf?.breakdown['Path'],
760+
breakdownGlobalVirtualEnvs: refreshPerf?.breakdown['GlobalVirtualEnvs'],
761+
breakdownWorkspaces: refreshPerf?.breakdown['Workspaces'],
762+
// Per-locator timing serialized as JSON; platform-dependent keys (e.g. WindowsRegistry, Conda).
763+
// Query in Kusto with: parse_json(Properties.locatorsJson)
764+
locatorsJson: refreshPerf ? JSON.stringify(refreshPerf.locators) : undefined,
733765
});
734766
} catch (ex) {
735767
const errorType = classifyError(ex);

0 commit comments

Comments
 (0)