|
| 1 | +/* -------------------------------------------------------------------------------------------- |
| 2 | + * Copyright (c) Microsoft Corporation. All Rights Reserved. |
| 3 | + * See 'LICENSE' in the project root for license information. |
| 4 | + * ------------------------------------------------------------------------------------------ */ |
| 5 | +import * as telemetry from '../telemetry'; |
| 6 | +import * as util from '../common'; |
| 7 | +import * as vscode from 'vscode'; |
| 8 | + |
| 9 | +interface TimeStampSequence { |
| 10 | + firstFile?: number; // when the extension is activated by realActivation. Defined only for "cold" start cases. |
| 11 | + didOpen: number; // when the file appears in the editor. Defined for "warm" start cases. |
| 12 | + setup: number; // when the Intellisense_client constructor is completed |
| 13 | + updateRange: number; // when publishDiagnostics & provideSemanticTokens is completed |
| 14 | +} |
| 15 | + |
| 16 | +export class TimeTelemetryCollector { |
| 17 | + |
| 18 | + private cachedTimeStamps: Map<string, any> = new Map<string, any>(); // a map of uri's string to TimeStampSequence |
| 19 | + |
| 20 | + public setFirstFile(uri: vscode.Uri): void { |
| 21 | + if (util.fileIsCOrCppSource(uri.path)) { |
| 22 | + const curTimeStamps: TimeStampSequence = this.getTimeStamp(uri.path); |
| 23 | + curTimeStamps.firstFile = new Date().getTime(); |
| 24 | + this.cachedTimeStamps.set(uri.path, curTimeStamps); |
| 25 | + } |
| 26 | + } |
| 27 | + |
| 28 | + public setDidOpenTime(uri: vscode.Uri): void { |
| 29 | + const curTimeStamps: TimeStampSequence = this.getTimeStamp(uri.path); |
| 30 | + curTimeStamps.didOpen = new Date().getTime(); |
| 31 | + this.cachedTimeStamps.set(uri.path, curTimeStamps); |
| 32 | + } |
| 33 | + |
| 34 | + public setSetupTime(uri: vscode.Uri): void { |
| 35 | + const curTimeStamps: TimeStampSequence = this.getTimeStamp(uri.path); |
| 36 | + curTimeStamps.setup = new Date().getTime(); |
| 37 | + this.cachedTimeStamps.set(uri.path, curTimeStamps); |
| 38 | + if (curTimeStamps.didOpen && curTimeStamps.updateRange) { |
| 39 | + this.logTelemetry(uri.path, curTimeStamps); |
| 40 | + } |
| 41 | + } |
| 42 | + |
| 43 | + public setUpdateRangeTime(uri: vscode.Uri): void { |
| 44 | + const curTimeStamps: TimeStampSequence = this.getTimeStamp(uri.path); |
| 45 | + if (!curTimeStamps.updateRange) { |
| 46 | + curTimeStamps.updateRange = new Date().getTime(); |
| 47 | + this.cachedTimeStamps.set(uri.path, curTimeStamps); |
| 48 | + } |
| 49 | + if (curTimeStamps.didOpen && curTimeStamps.setup) { |
| 50 | + this.logTelemetry(uri.path, curTimeStamps); |
| 51 | + } |
| 52 | + } |
| 53 | + |
| 54 | + public clear(): void { |
| 55 | + console.log("clearing timestamp log"); |
| 56 | + this.cachedTimeStamps.clear(); |
| 57 | + } |
| 58 | + |
| 59 | + private getTimeStamp(uri: string): TimeStampSequence { |
| 60 | + return this.cachedTimeStamps.get(uri) ? this.cachedTimeStamps.get(uri) : |
| 61 | + { firstFile: 0, didOpen: 0, setup: 0, updateRange: 0 }; |
| 62 | + } |
| 63 | + |
| 64 | + private removeTimeStamp(uri: string): void { |
| 65 | + this.cachedTimeStamps.delete(uri); |
| 66 | + } |
| 67 | + |
| 68 | + private logTelemetry(uri: string, timeStamps: TimeStampSequence): void { |
| 69 | + const startTime: number = timeStamps.firstFile ? timeStamps.firstFile : timeStamps.didOpen; |
| 70 | + let properties: any = {}; |
| 71 | + let metrics: any = { |
| 72 | + "setupTime": (timeStamps.setup - startTime), |
| 73 | + "updateRangeTime": (timeStamps.updateRange - timeStamps.setup), |
| 74 | + "totalTime": (timeStamps.updateRange - startTime) |
| 75 | + }; |
| 76 | + if (timeStamps.firstFile) { |
| 77 | + properties = { "coldstart": "true" }; |
| 78 | + metrics = { "activationTime": (timeStamps.didOpen - startTime), ...metrics }; |
| 79 | + } |
| 80 | + telemetry.logLanguageServerEvent("timeStamps", properties, metrics); |
| 81 | + |
| 82 | + this.removeTimeStamp(uri); |
| 83 | + } |
| 84 | +} |
0 commit comments