diff --git a/extensions/typescript/package.json b/extensions/typescript/package.json index ba354fcb40c..5699507760e 100644 --- a/extensions/typescript/package.json +++ b/extensions/typescript/package.json @@ -6,6 +6,7 @@ "author": "Microsoft Corporation", "license": "MIT", "publisher": "vscode", + "aiKey":"AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", "engines": { "vscode": "*" }, diff --git a/extensions/typescript/src/typescriptServiceClient.ts b/extensions/typescript/src/typescriptServiceClient.ts index 40512e7900e..358b3c44cbe 100644 --- a/extensions/typescript/src/typescriptServiceClient.ts +++ b/extensions/typescript/src/typescriptServiceClient.ts @@ -18,6 +18,8 @@ import { ITypescriptServiceClient, ITypescriptServiceClientHost } from './types import * as VersionStatus from './utils/versionStatus'; +import TelemetryReporter from 'vscode-extension-telemetry'; + interface CallbackItem { c: (value: any) => void; e: (err: any) => void; @@ -34,6 +36,12 @@ interface RequestItem { callbacks: CallbackItem; } +interface IPackageInfo { + name: string; + version: string; + aiKey: string; +} + export default class TypeScriptServiceClient implements ITypescriptServiceClient { public static Trace: boolean = process.env.TSS_TRACE || false; @@ -56,6 +64,9 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient private pendingResponses: number; private callbacks: CallbackMap; + private _packageInfo: IPackageInfo; + private telemetryReporter: TelemetryReporter; + constructor(host: ITypescriptServiceClientHost) { this.host = host; this.pathSeparator = path.sep; @@ -83,6 +94,9 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient this.startService(); } }); + if (this.packageInfo && this.packageInfo.aiKey) { + this.telemetryReporter = new TelemetryReporter(this.packageInfo.name, this.packageInfo.version, this.packageInfo.aiKey); + } this.startService(); } @@ -94,6 +108,32 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient return TypeScriptServiceClient.Trace; } + private get packageInfo(): IPackageInfo { + + if (this._packageInfo !== undefined) { + return this._packageInfo; + } + let packagePath = path.join(__dirname, './../package.json'); + let extensionPackage = require(packagePath); + if (extensionPackage) { + this._packageInfo = { + name: extensionPackage.name, + version: extensionPackage.version, + aiKey: extensionPackage.aiKey + }; + } else { + this._packageInfo = null; + } + + return this._packageInfo; + } + + private logTelemetry(eventName: string, properties?: {[prop: string]: string}) { + if (this.telemetryReporter) { + this.telemetryReporter.sendTelemetryEvent(eventName, properties); + } + } + private service(): Promise { if (this.servicePromise) { return this.servicePromise; @@ -141,6 +181,7 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient if (err) { this.lastError = err; window.showErrorMessage(`TypeScript language server couldn\'t be started. Error message is: ${err.message}`); + this.logTelemetry('error', {message: err.message}); return; } this.lastStart = Date.now(); @@ -212,6 +253,7 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient } else if (diff < 2 * 1000 /* 2 seconds */) { startService = false; window.showErrorMessage('The Typesrript language service died 5 times right after it got started. The service will not be restarted. Please open a bug report.'); + this.logTelemetry('serviceExited'); } } if (startService) { diff --git a/extensions/typescript/src/typings/node.additions.d.ts b/extensions/typescript/src/typings/node.additions.d.ts index 3ae7322bc8a..834e4c251c1 100644 --- a/extensions/typescript/src/typings/node.additions.d.ts +++ b/extensions/typescript/src/typings/node.additions.d.ts @@ -25,4 +25,13 @@ interface Console { declare var Console: { prototype: Console; new(): Console; +}; + +declare var require: { + toUrl(path: string): string; + (moduleName: string): any; + (dependencies: string[], callback: (...args: any[]) => any, errorback?: (err: any) => void): any; + config(data: any): any; + onError: Function; + __$__nodeRequire(moduleName: string): T; }; \ No newline at end of file diff --git a/extensions/typescript/src/typings/vscode-extension-telemetry.d.ts b/extensions/typescript/src/typings/vscode-extension-telemetry.d.ts new file mode 100644 index 00000000000..4b2981b9b24 --- /dev/null +++ b/extensions/typescript/src/typings/vscode-extension-telemetry.d.ts @@ -0,0 +1,6 @@ +declare module 'vscode-extension-telemetry' { + export default class TelemetryReporter { + constructor(extensionId: string,extensionVersion: string, key: string); + sendTelemetryEvent(eventName: string, properties?: { [key: string]: string }, measures?: { [key: string]: number }): void; + } +} \ No newline at end of file diff --git a/package.json b/package.json index 25c1a77c9af..a443ef9515c 100644 --- a/package.json +++ b/package.json @@ -24,11 +24,12 @@ "http-proxy-agent": "^0.2.6", "https-proxy-agent": "^0.3.5", "iconv-lite": "^0.4.13", + "native-keymap": "^0.1.2", "sax": "^1.1.1", "semver": "^4.2.0", "vscode-debugprotocol": "^1.5.0", + "vscode-extension-telemetry": "^0.0.4", "vscode-textmate": "^1.0.11", - "native-keymap": "^0.1.2", "weak": "^1.0.1", "winreg": "0.0.12", "yauzl": "^2.3.1"