@react-native-windows/telemetry 0.73.2 → 0.74.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib-commonjs/e2etest/telemetry.test.d.ts +28 -28
- package/lib-commonjs/e2etest/telemetry.test.js +496 -496
- package/lib-commonjs/index.d.ts +11 -11
- package/lib-commonjs/index.js +26 -26
- package/lib-commonjs/telemetry.d.ts +84 -84
- package/lib-commonjs/telemetry.js +370 -370
- package/lib-commonjs/telemetry.js.map +1 -1
- package/lib-commonjs/test/basePropUtils.test.d.ts +7 -7
- package/lib-commonjs/test/basePropUtils.test.js +137 -137
- package/lib-commonjs/test/errorUtils.test.d.ts +7 -7
- package/lib-commonjs/test/errorUtils.test.js +159 -159
- package/lib-commonjs/test/projectUtils.test.d.ts +7 -7
- package/lib-commonjs/test/projectUtils.test.js +87 -87
- package/lib-commonjs/test/sanitizeUtils.test.d.ts +7 -7
- package/lib-commonjs/test/sanitizeUtils.test.js +97 -97
- package/lib-commonjs/test/versionUtils.test.d.ts +7 -7
- package/lib-commonjs/test/versionUtils.test.js +114 -114
- package/lib-commonjs/utils/basePropUtils.d.ts +81 -81
- package/lib-commonjs/utils/basePropUtils.js +173 -173
- package/lib-commonjs/utils/errorUtils.d.ts +87 -87
- package/lib-commonjs/utils/errorUtils.js +178 -178
- package/lib-commonjs/utils/optionUtils.d.ts +45 -45
- package/lib-commonjs/utils/optionUtils.js +95 -95
- package/lib-commonjs/utils/projectUtils.d.ts +50 -50
- package/lib-commonjs/utils/projectUtils.js +186 -186
- package/lib-commonjs/utils/sanitizeUtils.d.ts +12 -12
- package/lib-commonjs/utils/sanitizeUtils.js +81 -81
- package/lib-commonjs/utils/versionUtils.d.ts +38 -38
- package/lib-commonjs/utils/versionUtils.js +155 -155
- package/package.json +13 -15
|
@@ -1,371 +1,371 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Copyright (c) Microsoft Corporation.
|
|
4
|
-
* Licensed under the MIT License.
|
|
5
|
-
* @format
|
|
6
|
-
*/
|
|
7
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
-
if (k2 === undefined) k2 = k;
|
|
9
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
-
}
|
|
13
|
-
Object.defineProperty(o, k2, desc);
|
|
14
|
-
}) : (function(o, m, k, k2) {
|
|
15
|
-
if (k2 === undefined) k2 = k;
|
|
16
|
-
o[k2] = m[k];
|
|
17
|
-
}));
|
|
18
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
-
}) : function(o, v) {
|
|
21
|
-
o["default"] = v;
|
|
22
|
-
});
|
|
23
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
24
|
-
if (mod && mod.__esModule) return mod;
|
|
25
|
-
var result = {};
|
|
26
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
27
|
-
__setModuleDefault(result, mod);
|
|
28
|
-
return result;
|
|
29
|
-
};
|
|
30
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
-
exports.Telemetry = exports.NuGetPackagesWeTrack = exports.NpmPackagesWeTrack = exports.EventNamesWeTrack = exports.CodedErrorEventName = exports.CommandEventName = void 0;
|
|
32
|
-
const appInsights = __importStar(require("applicationinsights"));
|
|
33
|
-
const basePropUtils = __importStar(require("./utils/basePropUtils"));
|
|
34
|
-
const versionUtils = __importStar(require("./utils/versionUtils"));
|
|
35
|
-
const errorUtils = __importStar(require("./utils/errorUtils"));
|
|
36
|
-
// This is our key with the AI backend
|
|
37
|
-
const RNWSetupString = '795006ca-cf54-40ee-8bc6-03deb91401c3';
|
|
38
|
-
// Environment variable to override the default setup string
|
|
39
|
-
const ENV_SETUP_OVERRIDE = 'RNW_TELEMETRY_SETUP';
|
|
40
|
-
// Environment variable to override the http proxy (such as http://localhost:8888 for Fiddler debugging)
|
|
41
|
-
const ENV_PROXY_OVERRIDE = 'RNW_TELEMETRY_PROXY';
|
|
42
|
-
exports.CommandEventName = 'RNWCLI.Command';
|
|
43
|
-
exports.CodedErrorEventName = 'RNWCLI.CodedError';
|
|
44
|
-
// These are the event names we're tracking
|
|
45
|
-
exports.EventNamesWeTrack = [
|
|
46
|
-
exports.CommandEventName,
|
|
47
|
-
exports.CodedErrorEventName,
|
|
48
|
-
];
|
|
49
|
-
// These are NPM packages we care about, in terms of capturing versions used
|
|
50
|
-
// and getting more details about when reporting errors
|
|
51
|
-
exports.NpmPackagesWeTrack = [
|
|
52
|
-
'@react-native-community/cli',
|
|
53
|
-
'@react-native-windows/cli',
|
|
54
|
-
'@react-native-windows/telemetry',
|
|
55
|
-
'react',
|
|
56
|
-
'react-native',
|
|
57
|
-
'react-native-windows',
|
|
58
|
-
'react-native-windows-init',
|
|
59
|
-
];
|
|
60
|
-
// These are NPM packages we care about, in terms of capturing versions used
|
|
61
|
-
exports.NuGetPackagesWeTrack = [
|
|
62
|
-
'Microsoft.UI.Xaml',
|
|
63
|
-
'Microsoft.Windows.CppWinRT',
|
|
64
|
-
'Microsoft.WinUI',
|
|
65
|
-
];
|
|
66
|
-
/**
|
|
67
|
-
* The Telemetry class is responsible for reporting telemetry for RNW CLI.
|
|
68
|
-
*/
|
|
69
|
-
class Telemetry {
|
|
70
|
-
static getDefaultSetupString() {
|
|
71
|
-
var _a;
|
|
72
|
-
// Enable overriding the default setup string via an environment variable
|
|
73
|
-
return (_a = process.env[ENV_SETUP_OVERRIDE]) !== null && _a !== void 0 ? _a : RNWSetupString;
|
|
74
|
-
}
|
|
75
|
-
static reset() {
|
|
76
|
-
// Reset client
|
|
77
|
-
if (Telemetry.client) {
|
|
78
|
-
Telemetry.client.flush();
|
|
79
|
-
Telemetry.client = undefined;
|
|
80
|
-
}
|
|
81
|
-
// Reset local members
|
|
82
|
-
Telemetry.options = {
|
|
83
|
-
setupString: Telemetry.getDefaultSetupString(),
|
|
84
|
-
preserveErrorMessages: false,
|
|
85
|
-
populateNpmPackageVersions: true,
|
|
86
|
-
};
|
|
87
|
-
Telemetry.commandInfo = {};
|
|
88
|
-
Telemetry.versionsProp = {};
|
|
89
|
-
Telemetry.projectProp = undefined;
|
|
90
|
-
}
|
|
91
|
-
static isEnabled() {
|
|
92
|
-
return Telemetry.client !== undefined;
|
|
93
|
-
}
|
|
94
|
-
static getSessionId() {
|
|
95
|
-
return basePropUtils.getSessionId();
|
|
96
|
-
}
|
|
97
|
-
/** Sets up the Telemetry static to be used elsewhere. */
|
|
98
|
-
static async setup(options) {
|
|
99
|
-
if (Telemetry.client) {
|
|
100
|
-
// Bail since we've already setup
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
// Bail if we're in CI and not capturing CI
|
|
104
|
-
if (!this.isTest && basePropUtils.isCI() && !basePropUtils.captureCI()) {
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
// Save off options for later
|
|
108
|
-
Object.assign(Telemetry.options, options);
|
|
109
|
-
Telemetry.setupClient();
|
|
110
|
-
await Telemetry.setupBaseProperties();
|
|
111
|
-
Telemetry.setupTelemetryProcessors();
|
|
112
|
-
}
|
|
113
|
-
/** Sets up Telemetry.client. */
|
|
114
|
-
static setupClient() {
|
|
115
|
-
var _a;
|
|
116
|
-
appInsights.Configuration.setInternalLogging(false, false);
|
|
117
|
-
Telemetry.client = new appInsights.TelemetryClient(Telemetry.options.setupString);
|
|
118
|
-
// Allow overriding the proxy server via an environment variable
|
|
119
|
-
const proxyServer = process.env[ENV_PROXY_OVERRIDE];
|
|
120
|
-
if (proxyServer) {
|
|
121
|
-
Telemetry.client.config.proxyHttpUrl = proxyServer;
|
|
122
|
-
Telemetry.client.config.proxyHttpsUrl = proxyServer;
|
|
123
|
-
}
|
|
124
|
-
Telemetry.client.config.disableAppInsights = Telemetry.isTest;
|
|
125
|
-
Telemetry.client.config.disableStatsbeat = true;
|
|
126
|
-
// Despite trying to disable the statsbeat, it might still be running: https://github.com/microsoft/ApplicationInsights-node.js/issues/943
|
|
127
|
-
// So we want to disable it, and despite the method's typing, getStatsbeat() _can_ return undefined
|
|
128
|
-
(_a = Telemetry.client.getStatsbeat()) === null || _a === void 0 ? void 0 : _a.enable(false);
|
|
129
|
-
Telemetry.client.channel.setUseDiskRetryCaching(!Telemetry.isTest);
|
|
130
|
-
}
|
|
131
|
-
/** Sets up any base properties that all telemetry events require. */
|
|
132
|
-
static async setupBaseProperties() {
|
|
133
|
-
Telemetry.client.commonProperties.deviceId =
|
|
134
|
-
await basePropUtils.deviceId();
|
|
135
|
-
Telemetry.client.commonProperties.deviceArchitecture =
|
|
136
|
-
basePropUtils.deviceArchitecture();
|
|
137
|
-
Telemetry.client.commonProperties.nodeArchitecture =
|
|
138
|
-
basePropUtils.nodeArchitecture();
|
|
139
|
-
Telemetry.client.commonProperties.devicePlatform =
|
|
140
|
-
basePropUtils.devicePlatform();
|
|
141
|
-
Telemetry.client.commonProperties.deviceLocale =
|
|
142
|
-
await basePropUtils.deviceLocale();
|
|
143
|
-
Telemetry.client.commonProperties.deviceNumCPUs = basePropUtils
|
|
144
|
-
.deviceNumCPUs()
|
|
145
|
-
.toString();
|
|
146
|
-
Telemetry.client.commonProperties.deviceTotalMemory = basePropUtils
|
|
147
|
-
.deviceTotalMemory()
|
|
148
|
-
.toString();
|
|
149
|
-
Telemetry.client.commonProperties.deviceDiskFreeSpace = basePropUtils
|
|
150
|
-
.deviceDiskFreeSpace()
|
|
151
|
-
.toString();
|
|
152
|
-
Telemetry.client.commonProperties.ciCaptured = basePropUtils
|
|
153
|
-
.captureCI()
|
|
154
|
-
.toString();
|
|
155
|
-
Telemetry.client.commonProperties.ciType = basePropUtils.ciType();
|
|
156
|
-
Telemetry.client.commonProperties.isMsftInternal = basePropUtils
|
|
157
|
-
.isMsftInternal()
|
|
158
|
-
.toString();
|
|
159
|
-
Telemetry.client.commonProperties.sampleRate = basePropUtils
|
|
160
|
-
.sampleRate()
|
|
161
|
-
.toString();
|
|
162
|
-
Telemetry.client.commonProperties.isTest = Telemetry.isTest.toString();
|
|
163
|
-
Telemetry.client.commonProperties.sessionId = Telemetry.getSessionId();
|
|
164
|
-
Telemetry.client.config.samplingPercentage = basePropUtils.sampleRate();
|
|
165
|
-
await Telemetry.populateToolsVersions();
|
|
166
|
-
if (Telemetry.options.populateNpmPackageVersions) {
|
|
167
|
-
await Telemetry.populateNpmPackageVersions();
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
/** Sets up any telemetry processors. */
|
|
171
|
-
static setupTelemetryProcessors() {
|
|
172
|
-
Telemetry.client.addTelemetryProcessor(Telemetry.basicTelemetryProcessor);
|
|
173
|
-
Telemetry.client.addTelemetryProcessor(Telemetry.errorTelemetryProcessor);
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Performs the processing necessary (mostly PII sanitization) for all events.
|
|
177
|
-
* @param envelope The ApplicationInsights event envelope.
|
|
178
|
-
* @param _contextObjects An optional context object.
|
|
179
|
-
* @returns Whether to kee
|
|
180
|
-
*/
|
|
181
|
-
static basicTelemetryProcessor(envelope, _contextObjects) {
|
|
182
|
-
var _a;
|
|
183
|
-
delete envelope.tags['ai.cloud.roleInstance'];
|
|
184
|
-
// Filter out "legacy" events from older stable branches
|
|
185
|
-
const properties = (_a = envelope.data.baseData) === null || _a === void 0 ? void 0 : _a.properties;
|
|
186
|
-
if ((properties === null || properties === void 0 ? void 0 : properties.eventName) &&
|
|
187
|
-
exports.EventNamesWeTrack.includes(properties.eventName)) {
|
|
188
|
-
return true;
|
|
189
|
-
}
|
|
190
|
-
return false;
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Performs the processing necessary (mostly PII sanitization) for error events.
|
|
194
|
-
* @param envelope
|
|
195
|
-
* @param _contextObjects
|
|
196
|
-
* @returns
|
|
197
|
-
*/
|
|
198
|
-
static errorTelemetryProcessor(envelope, _contextObjects) {
|
|
199
|
-
if (envelope.data.baseType === 'ExceptionData') {
|
|
200
|
-
const data = envelope.data.baseData;
|
|
201
|
-
if (data === null || data === void 0 ? void 0 : data.exceptions) {
|
|
202
|
-
for (const exception of data.exceptions) {
|
|
203
|
-
for (const frame of exception.parsedStack) {
|
|
204
|
-
errorUtils.sanitizeErrorStackFrame(frame);
|
|
205
|
-
}
|
|
206
|
-
// Exception message must never be blank, or AI will reject it
|
|
207
|
-
exception.message = exception.message || '[None]';
|
|
208
|
-
// CodedError has non-PII information in its 'type' member, plus optionally some more info in its 'data'.
|
|
209
|
-
// The message may contain PII information. This can be sanitized, but for now delete it.
|
|
210
|
-
// Note that the type of data.exceptions[0] is always going to be ExceptionDetails. It is not the original thrown exception.
|
|
211
|
-
// https://github.com/microsoft/ApplicationInsights-node.js/issues/707
|
|
212
|
-
if (Telemetry.options.preserveErrorMessages) {
|
|
213
|
-
exception.message = errorUtils.sanitizeErrorMessage(exception.message);
|
|
214
|
-
}
|
|
215
|
-
else {
|
|
216
|
-
exception.message = '[Removed]';
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
return true;
|
|
222
|
-
}
|
|
223
|
-
/** Tries to update the version of the named package/tool by calling getValue(). */
|
|
224
|
-
static async tryUpdateVersionsProp(name, getValue, forceRefresh) {
|
|
225
|
-
if (!Telemetry.client) {
|
|
226
|
-
return true;
|
|
227
|
-
}
|
|
228
|
-
if (forceRefresh === true || !Telemetry.versionsProp[name]) {
|
|
229
|
-
const value = await getValue();
|
|
230
|
-
if (value) {
|
|
231
|
-
Telemetry.versionsProp[name] = value;
|
|
232
|
-
return true;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
return false;
|
|
236
|
-
}
|
|
237
|
-
/** Populates the versions property of tools we care to track. */
|
|
238
|
-
static async populateToolsVersions(refresh) {
|
|
239
|
-
await Telemetry.tryUpdateVersionsProp('node', versionUtils.getNodeVersion, refresh);
|
|
240
|
-
await Telemetry.tryUpdateVersionsProp('npm', versionUtils.getNpmVersion, refresh);
|
|
241
|
-
await Telemetry.tryUpdateVersionsProp('yarn', versionUtils.getYarnVersion, refresh);
|
|
242
|
-
await Telemetry.tryUpdateVersionsProp('VisualStudio', versionUtils.getVisualStudioVersion, refresh);
|
|
243
|
-
}
|
|
244
|
-
/** Populates the versions property of npm packages we care to track. */
|
|
245
|
-
static async populateNpmPackageVersions(refresh) {
|
|
246
|
-
for (const npmPackage of exports.NpmPackagesWeTrack) {
|
|
247
|
-
await Telemetry.tryUpdateVersionsProp(npmPackage, async () => await versionUtils.getVersionOfNpmPackage(npmPackage), refresh);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
/** Populates the versions property of nuget packages we care to track. */
|
|
251
|
-
static async populateNuGetPackageVersions(projectFile, refresh) {
|
|
252
|
-
const nugetVersions = await versionUtils.getVersionsOfNuGetPackages(projectFile, exports.NuGetPackagesWeTrack);
|
|
253
|
-
for (const nugetPackage of exports.NuGetPackagesWeTrack) {
|
|
254
|
-
await Telemetry.tryUpdateVersionsProp(nugetPackage, async () => nugetVersions[nugetPackage], refresh);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
static setProjectInfo(info) {
|
|
258
|
-
if (!Telemetry.client) {
|
|
259
|
-
return;
|
|
260
|
-
}
|
|
261
|
-
Telemetry.projectProp = info;
|
|
262
|
-
}
|
|
263
|
-
static startCommand(info) {
|
|
264
|
-
if (!Telemetry.client) {
|
|
265
|
-
return;
|
|
266
|
-
}
|
|
267
|
-
if (Telemetry.commandInfo.startInfo) {
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
Telemetry.commandInfo.startTime = Date.now();
|
|
271
|
-
Telemetry.commandInfo.startInfo = info;
|
|
272
|
-
// Set common command props
|
|
273
|
-
Telemetry.client.commonProperties.commandName = info.commandName;
|
|
274
|
-
}
|
|
275
|
-
static endCommand(info, extraProps) {
|
|
276
|
-
if (!Telemetry.client) {
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
if (!Telemetry.commandInfo.startInfo) {
|
|
280
|
-
return;
|
|
281
|
-
}
|
|
282
|
-
Telemetry.commandInfo.endTime = Date.now();
|
|
283
|
-
Telemetry.commandInfo.endInfo = info;
|
|
284
|
-
Telemetry.trackCommandEvent(extraProps);
|
|
285
|
-
}
|
|
286
|
-
static trackCommandEvent(extraProps) {
|
|
287
|
-
var _a, _b, _c, _d;
|
|
288
|
-
const props = {
|
|
289
|
-
eventName: exports.CommandEventName,
|
|
290
|
-
};
|
|
291
|
-
// Set command props
|
|
292
|
-
props.command = {
|
|
293
|
-
options: (_a = Telemetry.commandInfo.startInfo) === null || _a === void 0 ? void 0 : _a.options,
|
|
294
|
-
defaultOptions: (_b = Telemetry.commandInfo.startInfo) === null || _b === void 0 ? void 0 : _b.defaultOptions,
|
|
295
|
-
args: (_c = Telemetry.commandInfo.startInfo) === null || _c === void 0 ? void 0 : _c.args,
|
|
296
|
-
durationInSecs: (Telemetry.commandInfo.endTime - Telemetry.commandInfo.startTime) /
|
|
297
|
-
1000,
|
|
298
|
-
resultCode: (_d = Telemetry.commandInfo.endInfo) === null || _d === void 0 ? void 0 : _d.resultCode,
|
|
299
|
-
};
|
|
300
|
-
// Set remaining common props
|
|
301
|
-
props.project = Telemetry.projectProp;
|
|
302
|
-
props.versions = Telemetry.versionsProp;
|
|
303
|
-
// Set extra props
|
|
304
|
-
props.extraProps = {};
|
|
305
|
-
Object.assign(props.extraProps, extraProps);
|
|
306
|
-
// Fire event
|
|
307
|
-
Telemetry.client.trackEvent({ name: props.eventName, properties: props });
|
|
308
|
-
Telemetry.client.flush();
|
|
309
|
-
}
|
|
310
|
-
static trackException(error, extraProps) {
|
|
311
|
-
var _a, _b;
|
|
312
|
-
if (!Telemetry.client) {
|
|
313
|
-
return;
|
|
314
|
-
}
|
|
315
|
-
const props = {
|
|
316
|
-
eventName: exports.CodedErrorEventName,
|
|
317
|
-
};
|
|
318
|
-
// Save off CodedError info
|
|
319
|
-
const codedError = error instanceof errorUtils.CodedError
|
|
320
|
-
? error
|
|
321
|
-
: null;
|
|
322
|
-
props.codedError = {
|
|
323
|
-
type: (_a = codedError === null || codedError === void 0 ? void 0 : codedError.type) !== null && _a !== void 0 ? _a : 'Unknown',
|
|
324
|
-
data: (_b = codedError === null || codedError === void 0 ? void 0 : codedError.data) !== null && _b !== void 0 ? _b : {},
|
|
325
|
-
};
|
|
326
|
-
// Copy msBuildErrorMessages into the codedError.data object
|
|
327
|
-
if (error.msBuildErrorMessages) {
|
|
328
|
-
// Always grab MSBuild error codes if possible
|
|
329
|
-
props.codedError.data.msBuildErrors = error.msBuildErrorMessages
|
|
330
|
-
.map(errorUtils.tryGetErrorCode)
|
|
331
|
-
.filter((msg) => msg);
|
|
332
|
-
// Grab sanitized MSBuild error messages if we're preserving them
|
|
333
|
-
if (Telemetry.options.preserveErrorMessages) {
|
|
334
|
-
props.codedError.data.msBuildErrorMessages = error.msBuildErrorMessages
|
|
335
|
-
.map(errorUtils.sanitizeErrorMessage)
|
|
336
|
-
.filter((msg) => msg);
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
// Copy miscellaneous system error fields into the codedError.data object
|
|
340
|
-
const syscallExceptionFieldsToCopy = ['errno', 'syscall', 'code'];
|
|
341
|
-
for (const f of syscallExceptionFieldsToCopy) {
|
|
342
|
-
if (error[f]) {
|
|
343
|
-
props.codedError.data[f] = error[f];
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
// Set remaining common props
|
|
347
|
-
props.project = Telemetry.projectProp;
|
|
348
|
-
props.versions = Telemetry.versionsProp;
|
|
349
|
-
// Set extra props
|
|
350
|
-
props.extraProps = {};
|
|
351
|
-
Object.assign(props.extraProps, extraProps);
|
|
352
|
-
// Fire event
|
|
353
|
-
Telemetry.client.trackException({
|
|
354
|
-
exception: error,
|
|
355
|
-
properties: props,
|
|
356
|
-
});
|
|
357
|
-
Telemetry.client.flush();
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
Telemetry.
|
|
362
|
-
Telemetry.
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
Telemetry.
|
|
368
|
-
Telemetry.
|
|
369
|
-
Telemetry.
|
|
370
|
-
Telemetry
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Microsoft Corporation.
|
|
4
|
+
* Licensed under the MIT License.
|
|
5
|
+
* @format
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
24
|
+
if (mod && mod.__esModule) return mod;
|
|
25
|
+
var result = {};
|
|
26
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
27
|
+
__setModuleDefault(result, mod);
|
|
28
|
+
return result;
|
|
29
|
+
};
|
|
30
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
exports.Telemetry = exports.NuGetPackagesWeTrack = exports.NpmPackagesWeTrack = exports.EventNamesWeTrack = exports.CodedErrorEventName = exports.CommandEventName = void 0;
|
|
32
|
+
const appInsights = __importStar(require("applicationinsights"));
|
|
33
|
+
const basePropUtils = __importStar(require("./utils/basePropUtils"));
|
|
34
|
+
const versionUtils = __importStar(require("./utils/versionUtils"));
|
|
35
|
+
const errorUtils = __importStar(require("./utils/errorUtils"));
|
|
36
|
+
// This is our key with the AI backend
|
|
37
|
+
const RNWSetupString = '795006ca-cf54-40ee-8bc6-03deb91401c3';
|
|
38
|
+
// Environment variable to override the default setup string
|
|
39
|
+
const ENV_SETUP_OVERRIDE = 'RNW_TELEMETRY_SETUP';
|
|
40
|
+
// Environment variable to override the http proxy (such as http://localhost:8888 for Fiddler debugging)
|
|
41
|
+
const ENV_PROXY_OVERRIDE = 'RNW_TELEMETRY_PROXY';
|
|
42
|
+
exports.CommandEventName = 'RNWCLI.Command';
|
|
43
|
+
exports.CodedErrorEventName = 'RNWCLI.CodedError';
|
|
44
|
+
// These are the event names we're tracking
|
|
45
|
+
exports.EventNamesWeTrack = [
|
|
46
|
+
exports.CommandEventName,
|
|
47
|
+
exports.CodedErrorEventName,
|
|
48
|
+
];
|
|
49
|
+
// These are NPM packages we care about, in terms of capturing versions used
|
|
50
|
+
// and getting more details about when reporting errors
|
|
51
|
+
exports.NpmPackagesWeTrack = [
|
|
52
|
+
'@react-native-community/cli',
|
|
53
|
+
'@react-native-windows/cli',
|
|
54
|
+
'@react-native-windows/telemetry',
|
|
55
|
+
'react',
|
|
56
|
+
'react-native',
|
|
57
|
+
'react-native-windows',
|
|
58
|
+
'react-native-windows-init',
|
|
59
|
+
];
|
|
60
|
+
// These are NPM packages we care about, in terms of capturing versions used
|
|
61
|
+
exports.NuGetPackagesWeTrack = [
|
|
62
|
+
'Microsoft.UI.Xaml',
|
|
63
|
+
'Microsoft.Windows.CppWinRT',
|
|
64
|
+
'Microsoft.WinUI',
|
|
65
|
+
];
|
|
66
|
+
/**
|
|
67
|
+
* The Telemetry class is responsible for reporting telemetry for RNW CLI.
|
|
68
|
+
*/
|
|
69
|
+
class Telemetry {
|
|
70
|
+
static getDefaultSetupString() {
|
|
71
|
+
var _a;
|
|
72
|
+
// Enable overriding the default setup string via an environment variable
|
|
73
|
+
return (_a = process.env[ENV_SETUP_OVERRIDE]) !== null && _a !== void 0 ? _a : RNWSetupString;
|
|
74
|
+
}
|
|
75
|
+
static reset() {
|
|
76
|
+
// Reset client
|
|
77
|
+
if (Telemetry.client) {
|
|
78
|
+
Telemetry.client.flush();
|
|
79
|
+
Telemetry.client = undefined;
|
|
80
|
+
}
|
|
81
|
+
// Reset local members
|
|
82
|
+
Telemetry.options = {
|
|
83
|
+
setupString: Telemetry.getDefaultSetupString(),
|
|
84
|
+
preserveErrorMessages: false,
|
|
85
|
+
populateNpmPackageVersions: true,
|
|
86
|
+
};
|
|
87
|
+
Telemetry.commandInfo = {};
|
|
88
|
+
Telemetry.versionsProp = {};
|
|
89
|
+
Telemetry.projectProp = undefined;
|
|
90
|
+
}
|
|
91
|
+
static isEnabled() {
|
|
92
|
+
return Telemetry.client !== undefined;
|
|
93
|
+
}
|
|
94
|
+
static getSessionId() {
|
|
95
|
+
return basePropUtils.getSessionId();
|
|
96
|
+
}
|
|
97
|
+
/** Sets up the Telemetry static to be used elsewhere. */
|
|
98
|
+
static async setup(options) {
|
|
99
|
+
if (Telemetry.client) {
|
|
100
|
+
// Bail since we've already setup
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
// Bail if we're in CI and not capturing CI
|
|
104
|
+
if (!this.isTest && basePropUtils.isCI() && !basePropUtils.captureCI()) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
// Save off options for later
|
|
108
|
+
Object.assign(Telemetry.options, options);
|
|
109
|
+
Telemetry.setupClient();
|
|
110
|
+
await Telemetry.setupBaseProperties();
|
|
111
|
+
Telemetry.setupTelemetryProcessors();
|
|
112
|
+
}
|
|
113
|
+
/** Sets up Telemetry.client. */
|
|
114
|
+
static setupClient() {
|
|
115
|
+
var _a;
|
|
116
|
+
appInsights.Configuration.setInternalLogging(false, false);
|
|
117
|
+
Telemetry.client = new appInsights.TelemetryClient(Telemetry.options.setupString);
|
|
118
|
+
// Allow overriding the proxy server via an environment variable
|
|
119
|
+
const proxyServer = process.env[ENV_PROXY_OVERRIDE];
|
|
120
|
+
if (proxyServer) {
|
|
121
|
+
Telemetry.client.config.proxyHttpUrl = proxyServer;
|
|
122
|
+
Telemetry.client.config.proxyHttpsUrl = proxyServer;
|
|
123
|
+
}
|
|
124
|
+
Telemetry.client.config.disableAppInsights = Telemetry.isTest;
|
|
125
|
+
Telemetry.client.config.disableStatsbeat = true;
|
|
126
|
+
// Despite trying to disable the statsbeat, it might still be running: https://github.com/microsoft/ApplicationInsights-node.js/issues/943
|
|
127
|
+
// So we want to disable it, and despite the method's typing, getStatsbeat() _can_ return undefined
|
|
128
|
+
(_a = Telemetry.client.getStatsbeat()) === null || _a === void 0 ? void 0 : _a.enable(false);
|
|
129
|
+
Telemetry.client.channel.setUseDiskRetryCaching(!Telemetry.isTest);
|
|
130
|
+
}
|
|
131
|
+
/** Sets up any base properties that all telemetry events require. */
|
|
132
|
+
static async setupBaseProperties() {
|
|
133
|
+
Telemetry.client.commonProperties.deviceId =
|
|
134
|
+
await basePropUtils.deviceId();
|
|
135
|
+
Telemetry.client.commonProperties.deviceArchitecture =
|
|
136
|
+
basePropUtils.deviceArchitecture();
|
|
137
|
+
Telemetry.client.commonProperties.nodeArchitecture =
|
|
138
|
+
basePropUtils.nodeArchitecture();
|
|
139
|
+
Telemetry.client.commonProperties.devicePlatform =
|
|
140
|
+
basePropUtils.devicePlatform();
|
|
141
|
+
Telemetry.client.commonProperties.deviceLocale =
|
|
142
|
+
await basePropUtils.deviceLocale();
|
|
143
|
+
Telemetry.client.commonProperties.deviceNumCPUs = basePropUtils
|
|
144
|
+
.deviceNumCPUs()
|
|
145
|
+
.toString();
|
|
146
|
+
Telemetry.client.commonProperties.deviceTotalMemory = basePropUtils
|
|
147
|
+
.deviceTotalMemory()
|
|
148
|
+
.toString();
|
|
149
|
+
Telemetry.client.commonProperties.deviceDiskFreeSpace = basePropUtils
|
|
150
|
+
.deviceDiskFreeSpace()
|
|
151
|
+
.toString();
|
|
152
|
+
Telemetry.client.commonProperties.ciCaptured = basePropUtils
|
|
153
|
+
.captureCI()
|
|
154
|
+
.toString();
|
|
155
|
+
Telemetry.client.commonProperties.ciType = basePropUtils.ciType();
|
|
156
|
+
Telemetry.client.commonProperties.isMsftInternal = basePropUtils
|
|
157
|
+
.isMsftInternal()
|
|
158
|
+
.toString();
|
|
159
|
+
Telemetry.client.commonProperties.sampleRate = basePropUtils
|
|
160
|
+
.sampleRate()
|
|
161
|
+
.toString();
|
|
162
|
+
Telemetry.client.commonProperties.isTest = Telemetry.isTest.toString();
|
|
163
|
+
Telemetry.client.commonProperties.sessionId = Telemetry.getSessionId();
|
|
164
|
+
Telemetry.client.config.samplingPercentage = basePropUtils.sampleRate();
|
|
165
|
+
await Telemetry.populateToolsVersions();
|
|
166
|
+
if (Telemetry.options.populateNpmPackageVersions) {
|
|
167
|
+
await Telemetry.populateNpmPackageVersions();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/** Sets up any telemetry processors. */
|
|
171
|
+
static setupTelemetryProcessors() {
|
|
172
|
+
Telemetry.client.addTelemetryProcessor(Telemetry.basicTelemetryProcessor);
|
|
173
|
+
Telemetry.client.addTelemetryProcessor(Telemetry.errorTelemetryProcessor);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Performs the processing necessary (mostly PII sanitization) for all events.
|
|
177
|
+
* @param envelope The ApplicationInsights event envelope.
|
|
178
|
+
* @param _contextObjects An optional context object.
|
|
179
|
+
* @returns Whether to kee
|
|
180
|
+
*/
|
|
181
|
+
static basicTelemetryProcessor(envelope, _contextObjects) {
|
|
182
|
+
var _a;
|
|
183
|
+
delete envelope.tags['ai.cloud.roleInstance'];
|
|
184
|
+
// Filter out "legacy" events from older stable branches
|
|
185
|
+
const properties = (_a = envelope.data.baseData) === null || _a === void 0 ? void 0 : _a.properties;
|
|
186
|
+
if ((properties === null || properties === void 0 ? void 0 : properties.eventName) &&
|
|
187
|
+
exports.EventNamesWeTrack.includes(properties.eventName)) {
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Performs the processing necessary (mostly PII sanitization) for error events.
|
|
194
|
+
* @param envelope
|
|
195
|
+
* @param _contextObjects
|
|
196
|
+
* @returns
|
|
197
|
+
*/
|
|
198
|
+
static errorTelemetryProcessor(envelope, _contextObjects) {
|
|
199
|
+
if (envelope.data.baseType === 'ExceptionData') {
|
|
200
|
+
const data = envelope.data.baseData;
|
|
201
|
+
if (data === null || data === void 0 ? void 0 : data.exceptions) {
|
|
202
|
+
for (const exception of data.exceptions) {
|
|
203
|
+
for (const frame of exception.parsedStack) {
|
|
204
|
+
errorUtils.sanitizeErrorStackFrame(frame);
|
|
205
|
+
}
|
|
206
|
+
// Exception message must never be blank, or AI will reject it
|
|
207
|
+
exception.message = exception.message || '[None]';
|
|
208
|
+
// CodedError has non-PII information in its 'type' member, plus optionally some more info in its 'data'.
|
|
209
|
+
// The message may contain PII information. This can be sanitized, but for now delete it.
|
|
210
|
+
// Note that the type of data.exceptions[0] is always going to be ExceptionDetails. It is not the original thrown exception.
|
|
211
|
+
// https://github.com/microsoft/ApplicationInsights-node.js/issues/707
|
|
212
|
+
if (Telemetry.options.preserveErrorMessages) {
|
|
213
|
+
exception.message = errorUtils.sanitizeErrorMessage(exception.message);
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
exception.message = '[Removed]';
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
223
|
+
/** Tries to update the version of the named package/tool by calling getValue(). */
|
|
224
|
+
static async tryUpdateVersionsProp(name, getValue, forceRefresh) {
|
|
225
|
+
if (!Telemetry.client) {
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
if (forceRefresh === true || !Telemetry.versionsProp[name]) {
|
|
229
|
+
const value = await getValue();
|
|
230
|
+
if (value) {
|
|
231
|
+
Telemetry.versionsProp[name] = value;
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
/** Populates the versions property of tools we care to track. */
|
|
238
|
+
static async populateToolsVersions(refresh) {
|
|
239
|
+
await Telemetry.tryUpdateVersionsProp('node', versionUtils.getNodeVersion, refresh);
|
|
240
|
+
await Telemetry.tryUpdateVersionsProp('npm', versionUtils.getNpmVersion, refresh);
|
|
241
|
+
await Telemetry.tryUpdateVersionsProp('yarn', versionUtils.getYarnVersion, refresh);
|
|
242
|
+
await Telemetry.tryUpdateVersionsProp('VisualStudio', versionUtils.getVisualStudioVersion, refresh);
|
|
243
|
+
}
|
|
244
|
+
/** Populates the versions property of npm packages we care to track. */
|
|
245
|
+
static async populateNpmPackageVersions(refresh) {
|
|
246
|
+
for (const npmPackage of exports.NpmPackagesWeTrack) {
|
|
247
|
+
await Telemetry.tryUpdateVersionsProp(npmPackage, async () => await versionUtils.getVersionOfNpmPackage(npmPackage), refresh);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/** Populates the versions property of nuget packages we care to track. */
|
|
251
|
+
static async populateNuGetPackageVersions(projectFile, refresh) {
|
|
252
|
+
const nugetVersions = await versionUtils.getVersionsOfNuGetPackages(projectFile, exports.NuGetPackagesWeTrack);
|
|
253
|
+
for (const nugetPackage of exports.NuGetPackagesWeTrack) {
|
|
254
|
+
await Telemetry.tryUpdateVersionsProp(nugetPackage, async () => nugetVersions[nugetPackage], refresh);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
static setProjectInfo(info) {
|
|
258
|
+
if (!Telemetry.client) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
Telemetry.projectProp = info;
|
|
262
|
+
}
|
|
263
|
+
static startCommand(info) {
|
|
264
|
+
if (!Telemetry.client) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
if (Telemetry.commandInfo.startInfo) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
Telemetry.commandInfo.startTime = Date.now();
|
|
271
|
+
Telemetry.commandInfo.startInfo = info;
|
|
272
|
+
// Set common command props
|
|
273
|
+
Telemetry.client.commonProperties.commandName = info.commandName;
|
|
274
|
+
}
|
|
275
|
+
static endCommand(info, extraProps) {
|
|
276
|
+
if (!Telemetry.client) {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
if (!Telemetry.commandInfo.startInfo) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
Telemetry.commandInfo.endTime = Date.now();
|
|
283
|
+
Telemetry.commandInfo.endInfo = info;
|
|
284
|
+
Telemetry.trackCommandEvent(extraProps);
|
|
285
|
+
}
|
|
286
|
+
static trackCommandEvent(extraProps) {
|
|
287
|
+
var _a, _b, _c, _d;
|
|
288
|
+
const props = {
|
|
289
|
+
eventName: exports.CommandEventName,
|
|
290
|
+
};
|
|
291
|
+
// Set command props
|
|
292
|
+
props.command = {
|
|
293
|
+
options: (_a = Telemetry.commandInfo.startInfo) === null || _a === void 0 ? void 0 : _a.options,
|
|
294
|
+
defaultOptions: (_b = Telemetry.commandInfo.startInfo) === null || _b === void 0 ? void 0 : _b.defaultOptions,
|
|
295
|
+
args: (_c = Telemetry.commandInfo.startInfo) === null || _c === void 0 ? void 0 : _c.args,
|
|
296
|
+
durationInSecs: (Telemetry.commandInfo.endTime - Telemetry.commandInfo.startTime) /
|
|
297
|
+
1000,
|
|
298
|
+
resultCode: (_d = Telemetry.commandInfo.endInfo) === null || _d === void 0 ? void 0 : _d.resultCode,
|
|
299
|
+
};
|
|
300
|
+
// Set remaining common props
|
|
301
|
+
props.project = Telemetry.projectProp;
|
|
302
|
+
props.versions = Telemetry.versionsProp;
|
|
303
|
+
// Set extra props
|
|
304
|
+
props.extraProps = {};
|
|
305
|
+
Object.assign(props.extraProps, extraProps);
|
|
306
|
+
// Fire event
|
|
307
|
+
Telemetry.client.trackEvent({ name: props.eventName, properties: props });
|
|
308
|
+
Telemetry.client.flush();
|
|
309
|
+
}
|
|
310
|
+
static trackException(error, extraProps) {
|
|
311
|
+
var _a, _b;
|
|
312
|
+
if (!Telemetry.client) {
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
const props = {
|
|
316
|
+
eventName: exports.CodedErrorEventName,
|
|
317
|
+
};
|
|
318
|
+
// Save off CodedError info
|
|
319
|
+
const codedError = error instanceof errorUtils.CodedError
|
|
320
|
+
? error
|
|
321
|
+
: null;
|
|
322
|
+
props.codedError = {
|
|
323
|
+
type: (_a = codedError === null || codedError === void 0 ? void 0 : codedError.type) !== null && _a !== void 0 ? _a : 'Unknown',
|
|
324
|
+
data: (_b = codedError === null || codedError === void 0 ? void 0 : codedError.data) !== null && _b !== void 0 ? _b : {},
|
|
325
|
+
};
|
|
326
|
+
// Copy msBuildErrorMessages into the codedError.data object
|
|
327
|
+
if (error.msBuildErrorMessages) {
|
|
328
|
+
// Always grab MSBuild error codes if possible
|
|
329
|
+
props.codedError.data.msBuildErrors = error.msBuildErrorMessages
|
|
330
|
+
.map(errorUtils.tryGetErrorCode)
|
|
331
|
+
.filter((msg) => msg);
|
|
332
|
+
// Grab sanitized MSBuild error messages if we're preserving them
|
|
333
|
+
if (Telemetry.options.preserveErrorMessages) {
|
|
334
|
+
props.codedError.data.msBuildErrorMessages = error.msBuildErrorMessages
|
|
335
|
+
.map(errorUtils.sanitizeErrorMessage)
|
|
336
|
+
.filter((msg) => msg);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
// Copy miscellaneous system error fields into the codedError.data object
|
|
340
|
+
const syscallExceptionFieldsToCopy = ['errno', 'syscall', 'code'];
|
|
341
|
+
for (const f of syscallExceptionFieldsToCopy) {
|
|
342
|
+
if (error[f]) {
|
|
343
|
+
props.codedError.data[f] = error[f];
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
// Set remaining common props
|
|
347
|
+
props.project = Telemetry.projectProp;
|
|
348
|
+
props.versions = Telemetry.versionsProp;
|
|
349
|
+
// Set extra props
|
|
350
|
+
props.extraProps = {};
|
|
351
|
+
Object.assign(props.extraProps, extraProps);
|
|
352
|
+
// Fire event
|
|
353
|
+
Telemetry.client.trackException({
|
|
354
|
+
exception: error,
|
|
355
|
+
properties: props,
|
|
356
|
+
});
|
|
357
|
+
Telemetry.client.flush();
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
Telemetry.client = undefined;
|
|
361
|
+
Telemetry.options = {
|
|
362
|
+
setupString: Telemetry.getDefaultSetupString(),
|
|
363
|
+
preserveErrorMessages: false,
|
|
364
|
+
populateNpmPackageVersions: true,
|
|
365
|
+
};
|
|
366
|
+
Telemetry.isTest = basePropUtils.isCliTest();
|
|
367
|
+
Telemetry.commandInfo = {};
|
|
368
|
+
Telemetry.versionsProp = {};
|
|
369
|
+
Telemetry.projectProp = undefined;
|
|
370
|
+
exports.Telemetry = Telemetry;
|
|
371
371
|
//# sourceMappingURL=telemetry.js.map
|