Skip to content

Commit fea4771

Browse files
committed
Add logging and improvements to the load times of the extension (#2947)
1 parent 8438f1c commit fea4771

File tree

10 files changed

+50
-48
lines changed

10 files changed

+50
-48
lines changed

news/2 Fixes/2732.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Disable activation of conda environments in PowerShell.

news/2 Fixes/2827.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Disable activation of conda environments in PowerShell.
1+
Add logging along with some some improvements to the load times of the extension.

src/client/activation/activationService.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ import {
2121
IOutputChannel, IPythonSettings
2222
} from '../common/types';
2323
import { IServiceContainer } from '../ioc/types';
24+
import { sendTelemetryEvent } from '../telemetry';
2425
import { PYTHON_LANGUAGE_SERVER_PLATFORM_NOT_SUPPORTED } from '../telemetry/constants';
25-
import { getTelemetryReporter } from '../telemetry/telemetry';
2626
import {
2727
ExtensionActivators, IExtensionActivationService,
2828
IExtensionActivator
@@ -69,10 +69,9 @@ export class ExtensionActivationService implements IExtensionActivationService,
6969
let jedi = this.useJedi();
7070
if (!jedi && !isLSSupported(this.serviceContainer)) {
7171
this.appShell.showWarningMessage('The Python Language Server is not supported on your platform.');
72-
const reporter = getTelemetryReporter();
7372
// tslint:disable-next-line:no-suspicious-comment
7473
// TODO: Only send once (ever)?
75-
reporter.sendTelemetryEvent(PYTHON_LANGUAGE_SERVER_PLATFORM_NOT_SUPPORTED);
74+
sendTelemetryEvent(PYTHON_LANGUAGE_SERVER_PLATFORM_NOT_SUPPORTED);
7675
jedi = true;
7776
}
7877

src/client/activation/languageServer.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ import {
3030
import { IEnvironmentVariablesProvider } from '../common/variables/types';
3131
import { IServiceContainer } from '../ioc/types';
3232
import { LanguageServerSymbolProvider } from '../providers/symbolProvider';
33+
import { sendTelemetryEvent } from '../telemetry';
3334
import {
3435
PYTHON_LANGUAGE_SERVER_ENABLED,
3536
PYTHON_LANGUAGE_SERVER_ERROR
3637
} from '../telemetry/constants';
37-
import { getTelemetryReporter } from '../telemetry/telemetry';
3838
import { IUnitTestManagementService } from '../unittests/types';
3939
import { LanguageServerDownloader } from './downloader';
4040
import { InterpreterData, InterpreterDataService } from './interpreterDataService';
@@ -144,8 +144,7 @@ export class LanguageServerExtensionActivator implements IExtensionActivator {
144144

145145
private async startLanguageServer(clientOptions: LanguageClientOptions): Promise<boolean> {
146146
// Determine if we are running MSIL/Universal via dotnet or self-contained app.
147-
const reporter = getTelemetryReporter();
148-
reporter.sendTelemetryEvent(PYTHON_LANGUAGE_SERVER_ENABLED);
147+
sendTelemetryEvent(PYTHON_LANGUAGE_SERVER_ENABLED);
149148

150149
const settings = this.configuration.getSettings();
151150
if (!settings.downloadLanguageServer) {
@@ -168,7 +167,7 @@ export class LanguageServerExtensionActivator implements IExtensionActivator {
168167
return true;
169168
} catch (ex) {
170169
this.appShell.showErrorMessage(`Language server failed to start. Error ${ex}`);
171-
reporter.sendTelemetryEvent(PYTHON_LANGUAGE_SERVER_ERROR, { error: 'Failed to start (platform)' });
170+
sendTelemetryEvent(PYTHON_LANGUAGE_SERVER_ERROR, undefined, { error: 'Failed to start (platform)' });
172171
return false;
173172
}
174173
}

src/client/common/nuget/azureBlobStoreNugetRepository.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
'use strict';
55

6-
import { common, createBlobServiceAnonymous } from 'azure-storage';
6+
import * as azStorageTypes from 'azure-storage';
77
import { inject, injectable, unmanaged } from 'inversify';
88
import { IServiceContainer } from '../../ioc/types';
99
import { captureTelemetry } from '../../telemetry';
@@ -23,12 +23,14 @@ export class AzureBlobStoreNugetRepository implements INugetRepository {
2323
@captureTelemetry(PYTHON_LANGUAGE_SERVER_LIST_BLOB_STORE_PACKAGES)
2424
@log('Listing Nuget Packages', LogOptions.Arguments)
2525
public listPackages(azureBlobStorageAccount: string, azureBlobStorageContainer: string, packageName: string) {
26-
const blobStore = createBlobServiceAnonymous(azureBlobStorageAccount);
26+
// tslint:disable-next-line:no-require-imports
27+
const az = require('azure-storage') as typeof azStorageTypes;
28+
const blobStore = az.createBlobServiceAnonymous(azureBlobStorageAccount);
2729
const nugetService = this.serviceContainer.get<INugetService>(INugetService);
2830
return new Promise<NugetPackage[]>((resolve, reject) => {
2931
// We must pass undefined according to docs, but type definition doesn't all it to be undefined or null!!!
3032
// tslint:disable-next-line:no-any
31-
const token = undefined as any as common.ContinuationToken;
33+
const token = undefined as any as azStorageTypes.common.ContinuationToken;
3234
blobStore.listBlobsSegmentedWithPrefix(azureBlobStorageContainer, packageName, token,
3335
(error, result) => {
3436
if (error) {

src/client/extension.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ if ((Reflect as any).metadata === undefined) {
55
// tslint:disable-next-line:no-require-imports no-var-requires
66
require('reflect-metadata');
77
}
8+
const durations: { [key: string]: number } = {};
89
import { StopWatch } from '../utils/stopWatch';
910
// Do not move this linne of code (used to measure extension load times).
1011
const stopWatch = new StopWatch();
@@ -64,10 +65,12 @@ import { OnEnterFormatter } from './typeFormatters/onEnterFormatter';
6465
import { TEST_OUTPUT_CHANNEL } from './unittests/common/constants';
6566
import { registerTypes as unitTestsRegisterTypes } from './unittests/serviceRegistry';
6667

68+
durations.codeLoadingTime = stopWatch.elapsedTime;
6769
const activationDeferred = createDeferred<void>();
6870

6971
// tslint:disable-next-line:max-func-body-length
7072
export async function activate(context: ExtensionContext): Promise<IExtensionApi> {
73+
durations.startActivateTime = stopWatch.elapsedTime;
7174
const cont = new Container();
7275
const serviceManager = new ServiceManager(cont);
7376
const serviceContainer = new ServiceContainer(cont);
@@ -163,6 +166,7 @@ export async function activate(context: ExtensionContext): Promise<IExtensionApi
163166
});
164167

165168
serviceContainer.get<IDebuggerBanner>(IDebuggerBanner).initialize();
169+
durations.endActivateTime = stopWatch.elapsedTime;
166170
activationDeferred.resolve();
167171

168172
return { ready: activationDeferred.promise };
@@ -213,7 +217,6 @@ async function sendStartupTelemetry(activatedPromise: Promise<void>, serviceCont
213217
await activatedPromise;
214218
const terminalHelper = serviceContainer.get<ITerminalHelper>(ITerminalHelper);
215219
const terminalShellType = terminalHelper.identifyTerminalShell(terminalHelper.getTerminalShellPath());
216-
const duration = stopWatch.elapsedTime;
217220
const condaLocator = serviceContainer.get<ICondaService>(ICondaService);
218221
const interpreterService = serviceContainer.get<IInterpreterService>(IInterpreterService);
219222
const [condaVersion, interpreter, interpreters] = await Promise.all([
@@ -230,7 +233,7 @@ async function sendStartupTelemetry(activatedPromise: Promise<void>, serviceCont
230233
.length > 0;
231234

232235
const props = { condaVersion, terminal: terminalShellType, pythonVersion, interpreterType, workspaceFolderCount, hasPython3 };
233-
sendTelemetryEvent(EDITOR_LOAD, duration, props);
236+
sendTelemetryEvent(EDITOR_LOAD, durations, props);
234237
} catch (ex) {
235238
logger.logError('sendStartupTelemetry failed.', ex);
236239
}

src/client/interpreter/configuration/pythonPathUpdaterService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export class PythonPathUpdaterService implements IPythonPathUpdaterServiceManage
5050
.catch<string>(() => '');
5151
const [info, pipVersion] = await Promise.all([infoPromise, pipVersionPromise]);
5252
if (info) {
53-
telemtryProperties.pyVersion = info.version;
53+
telemtryProperties.pythonVersion = info.version_info.join('.');
5454
}
5555
if (pipVersion) {
5656
telemtryProperties.pipVersion = pipVersion;

src/client/telemetry/index.ts

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,39 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4+
// tslint:disable-next-line:no-reference
5+
/// <reference path="./vscode-extension-telemetry.d.ts" />
6+
import { extensions } from 'vscode';
7+
// tslint:disable-next-line:import-name
8+
import TelemetryReporter from 'vscode-extension-telemetry';
49
import { StopWatch } from '../../utils/stopWatch';
5-
import { isTestExecution } from '../common/constants';
6-
import { getTelemetryReporter } from './telemetry';
10+
import { isTestExecution, PVSC_EXTENSION_ID } from '../common/constants';
711
import { TelemetryProperties } from './types';
812

9-
export function sendTelemetryEvent(eventName: string, durationMs?: number, properties?: TelemetryProperties) {
13+
let telemetryReporter: TelemetryReporter;
14+
function getTelemetryReporter() {
15+
if (telemetryReporter) {
16+
return telemetryReporter;
17+
}
18+
const extensionId = PVSC_EXTENSION_ID;
19+
// tslint:disable-next-line:no-non-null-assertion
20+
const extension = extensions.getExtension(extensionId)!;
21+
// tslint:disable-next-line:no-unsafe-any
22+
const extensionVersion = extension.packageJSON.version;
23+
// tslint:disable-next-line:no-unsafe-any
24+
const aiKey = extension.packageJSON.contributes.debuggers[0].aiKey;
25+
26+
// tslint:disable-next-line:no-require-imports
27+
const reporter = require('vscode-extension-telemetry').default as typeof TelemetryReporter;
28+
return telemetryReporter = new reporter(extensionId, extensionVersion, aiKey);
29+
}
30+
31+
export function sendTelemetryEvent(eventName: string, durationMs?: { [key: string]: number } | number, properties?: TelemetryProperties) {
1032
if (isTestExecution()) {
1133
return;
1234
}
1335
const reporter = getTelemetryReporter();
14-
const measures = typeof durationMs === 'number' ? { duration: durationMs } : undefined;
36+
const measures = typeof durationMs === 'number' ? { duration: durationMs } : (durationMs ? durationMs : undefined);
1537

1638
// tslint:disable-next-line:no-any
1739
const customProperties: { [key: string]: string } = {};

src/client/telemetry/telemetry.ts

Lines changed: 0 additions & 29 deletions
This file was deleted.

src/client/telemetry/types.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ export type LanguageServerTelemetry = {
2020
lsVersion?: string;
2121
};
2222

23+
export type LanguageServerErrorTelemetry = {
24+
error: string;
25+
};
26+
2327
export type LinterTrigger = 'auto' | 'save';
2428

2529
export type LintingTelemetry = {
@@ -31,7 +35,7 @@ export type LintingTelemetry = {
3135
export type PythonInterpreterTelemetry = {
3236
trigger: 'ui' | 'shebang' | 'load';
3337
failed: boolean;
34-
pyVersion?: string;
38+
pythonVersion?: string;
3539
pipVersion?: string;
3640
};
3741
export type CodeExecutionTelemetry = {
@@ -88,6 +92,7 @@ export type TerminalTelemetry = {
8892
};
8993
export type TelemetryProperties = FormatTelemetry
9094
| LanguageServerTelemetry
95+
| LanguageServerErrorTelemetry
9196
| LintingTelemetry
9297
| EditorLoadTelemetry
9398
| PythonInterpreterTelemetry

0 commit comments

Comments
 (0)