forked from microsoft/vscode-cpptools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtelemetry.ts
155 lines (134 loc) · 5.74 KB
/
telemetry.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
import TelemetryReporter from '@vscode/extension-telemetry';
import { getExperimentationServiceAsync, IExperimentationService, IExperimentationTelemetry, TargetPopulation } from 'vscode-tas-client';
import { CppSettings } from './LanguageServer/settings';
import * as util from './common';
interface IPackageInfo {
name: string;
version: string;
}
export class ExperimentationTelemetry implements IExperimentationTelemetry {
private sharedProperties: Record<string, string> = {};
constructor(private baseReporter: TelemetryReporter) { }
sendTelemetryEvent(eventName: string, properties?: Record<string, string>, measurements?: Record<string, number>): void {
this.baseReporter.sendTelemetryEvent(
eventName,
{
...this.sharedProperties,
...properties
},
measurements
);
}
sendTelemetryErrorEvent(eventName: string, properties?: Record<string, string>, _measurements?: Record<string, number>): void {
this.baseReporter.sendTelemetryErrorEvent(eventName, {
...this.sharedProperties,
...properties
});
}
setSharedProperty(name: string, value: string): void {
this.sharedProperties[name] = value;
}
postEvent(eventName: string, props: Map<string, string>): void {
const event: Record<string, string> = {};
for (const [key, value] of props) {
event[key] = value;
}
this.sendTelemetryEvent(eventName, event);
}
dispose(): Promise<any> {
return this.baseReporter.dispose();
}
}
let initializationPromise: Promise<IExperimentationService> | undefined;
let experimentationTelemetry: ExperimentationTelemetry | undefined;
const appInsightsKey: string = "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255";
export function activate(): void {
try {
if (util.extensionContext) {
const packageInfo: IPackageInfo = getPackageInfo();
if (packageInfo) {
const targetPopulation: TargetPopulation = util.getCppToolsTargetPopulation();
experimentationTelemetry = new ExperimentationTelemetry(new TelemetryReporter(packageInfo.name, packageInfo.version, appInsightsKey));
initializationPromise = getExperimentationServiceAsync(packageInfo.name, packageInfo.version, targetPopulation, experimentationTelemetry, util.extensionContext.globalState);
}
}
} catch (e) {
// Handle error with a try/catch, but do nothing for errors.
}
}
export function getExperimentationService(): Promise<IExperimentationService> | undefined {
return initializationPromise;
}
export async function showLanguageStatusExperiment(): Promise<boolean> {
return isExperimentEnabled("ShowLangStatBar");
}
export async function showStatusBarIntelliSenseIndicator(): Promise<boolean> {
return isExperimentEnabled("showStatusBarIntelliSenseIndicator");
}
async function isExperimentEnabled(experimentName: string): Promise<boolean> {
if (new CppSettings().experimentalFeatures) {
return true;
}
const experimentationService: IExperimentationService | undefined = await getExperimentationService();
const isEnabled: boolean | undefined = experimentationService?.getTreatmentVariable<boolean>("vscode", experimentName);
return isEnabled ?? false;
}
export async function deactivate(): Promise<void> {
if (initializationPromise) {
try {
await initializationPromise;
} catch (e) {
// Continue even if we were not able to initialize the experimentation platform.
}
}
if (experimentationTelemetry) {
experimentationTelemetry.dispose();
}
}
export function logDebuggerEvent(eventName: string, properties?: { [key: string]: string }, metrics?: { [key: string]: number }): void {
const sendTelemetry = () => {
if (experimentationTelemetry) {
const eventNamePrefix: string = "cppdbg/VS/Diagnostics/Debugger/";
experimentationTelemetry.sendTelemetryEvent(eventNamePrefix + eventName, properties, metrics);
}
};
if (initializationPromise) {
try {
// Use 'then' instead of 'await' because telemetry should be "fire and forget".
initializationPromise.then(sendTelemetry);
return;
} catch (e) {
// Continue even if we were not able to initialize the experimentation platform.
}
}
sendTelemetry();
}
export function logLanguageServerEvent(eventName: string, properties?: { [key: string]: string }, metrics?: { [key: string]: number }): void {
const sendTelemetry = () => {
if (experimentationTelemetry) {
const eventNamePrefix: string = "C_Cpp/LanguageServer/";
experimentationTelemetry.sendTelemetryEvent(eventNamePrefix + eventName, properties, metrics);
}
};
if (initializationPromise) {
try {
// Use 'then' instead of 'await' because telemetry should be "fire and forget".
initializationPromise.then(sendTelemetry);
return;
} catch (e) {
// Continue even if we were not able to initialize the experimentation platform.
}
}
sendTelemetry();
}
function getPackageInfo(): IPackageInfo {
return {
name: util.packageJson.publisher + "." + util.packageJson.name,
version: util.packageJson.version
};
}