Skip to content

Commit 8dc42ab

Browse files
committed
Add telemetry for download, extract, and analyze.
Fixes microsoft#2461 (alternate fix to PR microsoft#2593) - Capture telemetry surrounds methods, minimizing change - Telemetry type can be altered with less code later. - Add success/fail props modifyer func to `captureTelemetry`
1 parent 59e79a3 commit 8dc42ab

File tree

5 files changed

+69
-3
lines changed

5 files changed

+69
-3
lines changed

src/client/activation/downloader.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ import { ProgressLocation, window } from 'vscode';
99
import { createDeferred } from '../../utils/async';
1010
import { IFileSystem } from '../common/platform/types';
1111
import { IExtensionContext, IOutputChannel } from '../common/types';
12+
import { captureTelemetry } from '../telemetry';
13+
import {
14+
PYTHON_LANGUAGE_SERVER_DOWNLOADED,
15+
PYTHON_LANGUAGE_SERVER_EXTRACTED
16+
} from '../telemetry/constants';
17+
import { LanguageServerInstallOpTelemetry } from '../telemetry/types';
1218
import { PlatformData, PlatformName } from './platformData';
1319
import { IDownloadFileService } from './types';
1420

@@ -28,6 +34,11 @@ export const DownloadLinks = {
2834
};
2935

3036
export class LanguageServerDownloader {
37+
//tslint:disable-next-line:no-unused-variable
38+
private lsDownloadTelemetry: LanguageServerInstallOpTelemetry = {};
39+
//tslint:disable-next-line:no-unused-variable
40+
private lsExtractTelemetry: LanguageServerInstallOpTelemetry = {};
41+
3142
constructor(
3243
private readonly output: IOutputChannel,
3344
private readonly fs: IFileSystem,
@@ -59,6 +70,12 @@ export class LanguageServerDownloader {
5970
}
6071
}
6172

73+
@captureTelemetry(
74+
PYTHON_LANGUAGE_SERVER_DOWNLOADED,
75+
{},
76+
true,
77+
(props?: LanguageServerInstallOpTelemetry) => props ? props.success = true : undefined
78+
)
6279
private async downloadFile(uri: string, title: string): Promise<string> {
6380
this.output.append(`Downloading ${uri}... `);
6481
const tempFile = await this.fs.createTemporaryFile(downloadFileExtension);
@@ -101,6 +118,12 @@ export class LanguageServerDownloader {
101118
return tempFile.filePath;
102119
}
103120

121+
@captureTelemetry(
122+
PYTHON_LANGUAGE_SERVER_EXTRACTED,
123+
this.languageServerStartupTelemetry,
124+
true,
125+
(props?: LanguageServerInstallOpTelemetry) => props ? props.success = true : undefined
126+
)
104127
private async unpackArchive(extensionPath: string, tempFilePath: string): Promise<void> {
105128
this.output.append('Unpacking archive... ');
106129

src/client/activation/languageServer.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4+
'use strict';
5+
46
import { inject, injectable } from 'inversify';
57
import * as path from 'path';
68
import {
@@ -27,12 +29,15 @@ import {
2729
} from '../common/types';
2830
import { IServiceContainer } from '../ioc/types';
2931
import { LanguageServerSymbolProvider } from '../providers/symbolProvider';
32+
import { captureTelemetry } from '../telemetry';
3033
import {
3134
PYTHON_LANGUAGE_SERVER_DOWNLOADED,
3235
PYTHON_LANGUAGE_SERVER_ENABLED,
33-
PYTHON_LANGUAGE_SERVER_ERROR
36+
PYTHON_LANGUAGE_SERVER_ERROR,
37+
PYTHON_LANGUAGE_SERVER_STARTUP
3438
} from '../telemetry/constants';
3539
import { getTelemetryReporter } from '../telemetry/telemetry';
40+
import { LanguageServerInstallOpTelemetry } from '../telemetry/types';
3641
import { IUnitTestManagementService } from '../unittests/types';
3742
import { LanguageServerDownloader } from './downloader';
3843
import { InterpreterData, InterpreterDataService } from './interpreterDataService';
@@ -75,6 +80,8 @@ export class LanguageServerExtensionActivator implements IExtensionActivator {
7580
private surveyBanner: IPythonExtensionBanner;
7681
// tslint:disable-next-line:no-unused-variable
7782
private progressReporting: ProgressReporting | undefined;
83+
//tslint:disable-next-line:no-unused-variable
84+
private languageServerStartupTelemetry: LanguageServerInstallOpTelemetry = {};
7885

7986
constructor(@inject(IServiceContainer) private readonly services: IServiceContainer) {
8087
this.context = this.services.get<IExtensionContext>(IExtensionContext);
@@ -140,6 +147,12 @@ export class LanguageServerExtensionActivator implements IExtensionActivator {
140147
(this.configuration.getSettings() as PythonSettings).removeListener('change', this.onSettingsChanged.bind(this));
141148
}
142149

150+
@captureTelemetry(
151+
PYTHON_LANGUAGE_SERVER_STARTUP,
152+
this.languageServerStartupTelemetry,
153+
true,
154+
(props?: LanguageServerInstallOpTelemetry) => props ? props.success = true : undefined
155+
)
143156
private async startLanguageServer(clientOptions: LanguageClientOptions): Promise<boolean> {
144157
// Determine if we are running MSIL/Universal via dotnet or self-contained app.
145158

src/client/telemetry/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export const UNITTEST_RUN = 'UNITTEST.RUN';
3333
export const UNITTEST_DISCOVER = 'UNITTEST.DISCOVER';
3434
export const UNITTEST_VIEW_OUTPUT = 'UNITTEST.VIEW_OUTPUT';
3535
export const PYTHON_LANGUAGE_SERVER_ENABLED = 'PYTHON_LANGUAGE_SERVER.ENABLED';
36+
export const PYTHON_LANGUAGE_SERVER_EXTRACTED = 'PYTHON_LANGUAGE_SERVER.EXTRACTED';
3637
export const PYTHON_LANGUAGE_SERVER_DOWNLOADED = 'PYTHON_LANGUAGE_SERVER.DOWNLOADED';
3738
export const PYTHON_LANGUAGE_SERVER_ERROR = 'PYTHON_LANGUAGE_SERVER.ERROR';
3839
export const PYTHON_LANGUAGE_SERVER_STARTUP = 'PYTHON_LANGUAGE_SERVER.STARTUP';

src/client/telemetry/index.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,15 @@ export function sendTelemetryEvent(eventName: string, durationMs?: number, prope
2626
}
2727

2828
// tslint:disable-next-line:no-any function-name
29-
export function captureTelemetry(eventName: string, properties?: TelemetryProperties, captureDuration: boolean = true) {
29+
export function captureTelemetry(
30+
eventName: string,
31+
properties?: TelemetryProperties,
32+
captureDuration: boolean = true,
33+
// tslint:disable-next-line:no-any
34+
beforeSuccessEmit?: (props?: any) => void,
35+
// tslint:disable-next-line:no-any
36+
beforeFailEmit?: (props?: any) => void
37+
) {
3038
// tslint:disable-next-line:no-function-expression no-any
3139
return function (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) {
3240
const originalMethod = descriptor.value;
@@ -48,11 +56,17 @@ export function captureTelemetry(eventName: string, properties?: TelemetryProper
4856
// tslint:disable-next-line:prefer-type-cast
4957
(result as Promise<void>)
5058
.then(data => {
59+
if (beforeSuccessEmit) {
60+
beforeSuccessEmit(properties);
61+
}
5162
sendTelemetryEvent(eventName, stopWatch.elapsedTime, properties);
5263
return data;
5364
})
5465
// tslint:disable-next-line:promise-function-async
5566
.catch(ex => {
67+
if (beforeFailEmit) {
68+
beforeFailEmit(properties);
69+
}
5670
sendTelemetryEvent(eventName, stopWatch.elapsedTime, properties);
5771
return Promise.reject(ex);
5872
});

src/client/telemetry/types.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ export type FormatTelemetry = {
1515
formatSelection: boolean;
1616
};
1717

18+
export type LanguageServerInstallOpTelemetry = {
19+
success?: boolean;
20+
};
21+
1822
export type LinterTrigger = 'auto' | 'save';
1923

2024
export type LintingTelemetry = {
@@ -81,4 +85,15 @@ export type TerminalTelemetry = {
8185
pythonVersion?: string;
8286
interpreterType?: InterpreterType;
8387
};
84-
export type TelemetryProperties = FormatTelemetry | LintingTelemetry | EditorLoadTelemetry | PythonInterpreterTelemetry | CodeExecutionTelemetry | TestRunTelemetry | TestDiscoverytTelemetry | FeedbackTelemetry | TerminalTelemetry | DebuggerTelemetryV2 | SettingsTelemetry;
88+
export type TelemetryProperties = FormatTelemetry
89+
| LanguageServerInstallOpTelemetry
90+
| LintingTelemetry
91+
| EditorLoadTelemetry
92+
| PythonInterpreterTelemetry
93+
| CodeExecutionTelemetry
94+
| TestRunTelemetry
95+
| TestDiscoverytTelemetry
96+
| FeedbackTelemetry
97+
| TerminalTelemetry
98+
| DebuggerTelemetryV2
99+
| SettingsTelemetry;

0 commit comments

Comments
 (0)