Change:
<!-- Do Not Delete This! featurerequesttemplate --<!-- Please read our Rules of Conduct: --<!-- Please search existing issues to avoid creating duplicates. --<!-- Describe the feature you'd like. --Add telemetry at the startup of an extension host to know that the startup was begun. Add telemetry when the extension host is successfully started. Add telemetry when the extension host failed to start. This enables determining the success/failure rate of extension host startup as well as grouping of failure reasons to debug issues in the field.

Discussion:
import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { StopWatch } from 'vs/base/common/stopwatch'; import { VSBuffer } from 'vs/base/common/buffer'; <del> import { IExtensionHost, ExtensionHostKind, ActivationKind } from 'vs/workbench/services/extensions/common/extensions'; </del> <ins> import { IExtensionHost, ExtensionHostKind, ActivationKind, extensionHostKindToString } from 'vs/workbench/services/extensions/common/extensions'; </ins> import { ExtensionActivationReason } from 'vs/workbench/api/common/extHostExtensionActivator'; import { CATEGORIES } from 'vs/workbench/common/actions'; import { Barrier, timeout } from 'vs/base/common/async'; import { URI } from 'vs/base/common/uri'; import { ILogService } from 'vs/platform/log/common/log'; <ins> import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; </ins> // Enable to see detailed message communication between window and extension host const LOG_EXTENSION_HOST_COMMUNICATION = false;

return instantiationService.createInstance(ExtensionHostManager, extensionHost, initialActivationEvents); } <ins> export type ExtensionHostStartupClassification = { time: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' }; action: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' }; kind: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' }; errorName?: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' }; errorMessage?: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' }; errorStack?: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' }; }; export type ExtensionHostStartupEvent = { time: number; action: 'starting' | 'success' | 'error'; kind: string; errorName?: string; errorMessage?: string; errorStack?: string; }; </ins> class ExtensionHostManager extends Disposable implements IExtensionHostManager { public readonly kind: ExtensionHostKind;

initialActivationEvents: string[], @IInstantiationService private readonly _instantiationService: IInstantiationService, @IWorkbenchEnvironmentService private readonly _environmentService: IWorkbenchEnvironmentService, <ins> @ITelemetryService private readonly _telemetryService: ITelemetryService </ins> ) { super(); this._cachedActivationEvents = new Map<string, Promise<void>>();

this._extensionHost = extensionHost; this.kind = this._extensionHost.kind; this.onDidExit = this._extensionHost.onExit; <ins> const startingTelemetryEvent: ExtensionHostStartupEvent = { time: Date.now(), action: 'starting', kind: extensionHostKindToString(this.kind) }; this._telemetryService.publicLog2<ExtensionHostStartupEvent, ExtensionHostStartupClassification>('extensionHostStartup', startingTelemetryEvent); </ins> this._proxy = this._extensionHost.start()!.then( (protocol) => { this._hasStarted = true; <ins> // Track healthy extension host startup const successTelemetryEvent: ExtensionHostStartupEvent = { time: Date.now(), action: 'success', kind: extensionHostKindToString(this.kind) }; this._telemetryService.publicLog2<ExtensionHostStartupEvent, ExtensionHostStartupClassification>('extensionHostStartup', successTelemetryEvent); </ins> return { value: this._createExtensionHostCustomers(protocol) }; }, (err) => { console.error(`Error received from starting extension host (kind: ${this.kind})`); console.error(err); <ins> // Track errors during extension host startup const failureTelemetryEvent: ExtensionHostStartupEvent = { time: Date.now(), action: 'error', kind: extensionHostKindToString(this.kind) }; if (err && err.name) { failureTelemetryEvent.errorName = err.name; } if (err && err.message) { failureTelemetryEvent.errorMessage = err.message; } if (err && err.stack) { failureTelemetryEvent.errorStack = err.stack; } this._telemetryService.publicLog2<ExtensionHostStartupEvent, ExtensionHostStartupClassification>('extensionHostStartup', failureTelemetryEvent, true); </ins> return null; } );

Remote } <ins> export function extensionHostKindToString(kind: ExtensionHostKind): string { switch (kind) { case ExtensionHostKind.LocalProcess: return 'LocalProcess'; case ExtensionHostKind.LocalWebWorker: return 'LocalWebWorker'; case ExtensionHostKind.Remote: return 'Remote'; } } </ins> export interface IExtensionHost { readonly kind: ExtensionHostKind; readonly remoteAuthority: string | null;