diff --git a/src/notebooks/controllers/notebookControllerManager.node.ts b/src/notebooks/controllers/notebookControllerManager.node.ts index 3452debe64b..1d8fcc407df 100644 --- a/src/notebooks/controllers/notebookControllerManager.node.ts +++ b/src/notebooks/controllers/notebookControllerManager.node.ts @@ -112,6 +112,12 @@ export class NotebookControllerManager implements INotebookControllerManager, IE private get isLocalLaunch(): boolean { return isLocalLaunch(this.configuration); } + private startTimeForFetchingControllers?: StopWatch; + private readonly controllerLoadingTelemetry = { + loadWithoutCacheSent: false, + loadWithCacheSent: false, + loadRemoteSent: false + }; private wasPythonInstalledWhenFetchingControllers?: boolean; private interactiveNoPythonController?: NoPythonKernelsNotebookController; private notebookNoPythonController?: NoPythonKernelsNotebookController; @@ -204,10 +210,24 @@ export class NotebookControllerManager implements INotebookControllerManager, IE // Find all the notebook controllers that we have registered public async loadNotebookControllers(refresh?: boolean): Promise { if (!this.controllersPromise || refresh) { + this.startTimeForFetchingControllers = this.startTimeForFetchingControllers || new StopWatch(); const stopWatch = new StopWatch(); // Fetch the list of kernels ignoring the cache. this.loadLocalNotebookControllersImpl('ignoreCache') + .then(() => { + if (!this.controllerLoadingTelemetry.loadWithoutCacheSent && this.startTimeForFetchingControllers) { + this.controllerLoadingTelemetry.loadWithoutCacheSent = true; + sendTelemetryEvent( + Telemetry.FetchControllers, + this.startTimeForFetchingControllers.elapsedTime, + { + firstTime: true, + kind: 'local' + } + ); + } + }) .catch((ex) => traceError('Failed to fetch controllers without cache', ex)) .finally(() => { this._controllersLoaded = true; @@ -239,9 +259,37 @@ export class NotebookControllerManager implements INotebookControllerManager, IE // Fetch kernel the fastest possible way (local kernels from cache but remote fetch latest). // Fetch the list of kernels from the cache (note: if there's nothing in the case, it will fallback to searching). // Fetching remote kernels cannot be done from cache. - const promises = [this.loadLocalNotebookControllersImpl('useCache')]; + const promises = [ + this.loadLocalNotebookControllersImpl('useCache').then(() => { + if (!this.controllerLoadingTelemetry.loadWithCacheSent && this.startTimeForFetchingControllers) { + this.controllerLoadingTelemetry.loadWithCacheSent = true; + sendTelemetryEvent( + Telemetry.FetchControllers, + this.startTimeForFetchingControllers.elapsedTime, + { + firstTime: false, + kind: 'local' + } + ); + } + }) + ]; if (!this.isLocalLaunch) { - promises.push(this.loadRemoteNotebookControllersImpl()); + promises.push( + this.loadRemoteNotebookControllersImpl().then(() => { + if (!this.controllerLoadingTelemetry.loadRemoteSent && this.startTimeForFetchingControllers) { + this.controllerLoadingTelemetry.loadRemoteSent = true; + sendTelemetryEvent( + Telemetry.FetchControllers, + this.startTimeForFetchingControllers.elapsedTime, + { + firstTime: true, + kind: 'remote' + } + ); + } + }) + ); } this.controllersPromise = Promise.all(promises) .then(() => noop()) diff --git a/src/telemetry/index.ts b/src/telemetry/index.ts index b9618d7b177..78811f43251 100644 --- a/src/telemetry/index.ts +++ b/src/telemetry/index.ts @@ -1533,4 +1533,18 @@ export interface IEventNamePropertyMapping { [Telemetry.KernelCrash]: never | undefined; [Telemetry.JupyterKernelHiddenViaFilter]: never | undefined; [Telemetry.JupyterKernelFilterUsed]: never | undefined; + /** + * Telemetry sent when we have loaded some controllers. + */ + [Telemetry.FetchControllers]: { + /** + * Whether this is the first time we're loading this (same as not using caches). + * In the case of remotes, this is always `true` (as we don't cache anything for remote kernels). + */ + firstTime: boolean; + /** + * Whether we've loaded local or remote controllers. + */ + kind: 'local' | 'remote'; + }; } diff --git a/src/webviews/webview-side/common/constants.ts b/src/webviews/webview-side/common/constants.ts index 347e159dc94..843935a7fb3 100644 --- a/src/webviews/webview-side/common/constants.ts +++ b/src/webviews/webview-side/common/constants.ts @@ -299,6 +299,7 @@ export enum Telemetry { */ ExportNotebookAsFailed = 'DATASCIENCE.EXPORT_NOTEBOOK_AS_FAILED', FailedToCreateNotebookController = 'DATASCIENCE.FAILED_TO_CREATE_CONTROLLER', + FetchControllers = 'DATASCIENCE.FETCH_CONTROLLERS', FailedToFindKernelSpecInterpreterForInteractive = 'DATASCIENCE.FAILED_TO_FIND_INTERPRETER_KERNEL_CONNECTION_FOR_INTERACTIVE', StartJupyter = 'DS_INTERNAL.JUPYTERSTARTUPCOST',