@fluidframework/telemetry-utils 2.0.0-internal.6.3.3 → 2.0.0-internal.7.0.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/CHANGELOG.md +73 -0
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -2
- package/dist/config.js.map +1 -1
- package/dist/error.d.ts +13 -5
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +10 -2
- package/dist/error.js.map +1 -1
- package/dist/errorLogging.d.ts +36 -1
- package/dist/errorLogging.d.ts.map +1 -1
- package/dist/errorLogging.js +56 -20
- package/dist/errorLogging.js.map +1 -1
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +16 -6
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +64 -42
- package/dist/logger.js.map +1 -1
- package/dist/telemetryTypes.d.ts +2 -2
- package/dist/telemetryTypes.d.ts.map +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +1 -1
- package/dist/utils.js.map +1 -1
- package/lib/config.d.ts +1 -1
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +4 -2
- package/lib/config.js.map +1 -1
- package/lib/error.d.ts +13 -5
- package/lib/error.d.ts.map +1 -1
- package/lib/error.js +10 -2
- package/lib/error.js.map +1 -1
- package/lib/errorLogging.d.ts +36 -1
- package/lib/errorLogging.d.ts.map +1 -1
- package/lib/errorLogging.js +55 -20
- package/lib/errorLogging.js.map +1 -1
- package/lib/events.d.ts.map +1 -1
- package/lib/events.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/logger.d.ts +16 -6
- package/lib/logger.d.ts.map +1 -1
- package/lib/logger.js +63 -41
- package/lib/logger.js.map +1 -1
- package/lib/telemetryTypes.d.ts +2 -2
- package/lib/telemetryTypes.d.ts.map +1 -1
- package/lib/utils.d.ts +1 -1
- package/lib/utils.js +1 -1
- package/lib/utils.js.map +1 -1
- package/package.json +11 -11
- package/src/config.ts +4 -2
- package/src/error.ts +15 -7
- package/src/errorLogging.ts +55 -15
- package/src/events.ts +2 -0
- package/src/index.ts +1 -0
- package/src/logger.ts +68 -37
- package/src/utils.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/telemetry-utils",
|
|
3
|
-
"version": "2.0.0-internal.
|
|
3
|
+
"version": "2.0.0-internal.7.0.0",
|
|
4
4
|
"description": "Collection of telemetry relates utilities for Fluid",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -39,22 +39,22 @@
|
|
|
39
39
|
"temp-directory": "nyc/.nyc_output"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@fluid-internal/client-utils": ">=2.0.0-internal.
|
|
43
|
-
"@fluidframework/core-interfaces": ">=2.0.0-internal.
|
|
44
|
-
"@fluidframework/core-utils": ">=2.0.0-internal.
|
|
45
|
-
"@fluidframework/protocol-definitions": "^
|
|
42
|
+
"@fluid-internal/client-utils": ">=2.0.0-internal.7.0.0 <2.0.0-internal.7.1.0",
|
|
43
|
+
"@fluidframework/core-interfaces": ">=2.0.0-internal.7.0.0 <2.0.0-internal.7.1.0",
|
|
44
|
+
"@fluidframework/core-utils": ">=2.0.0-internal.7.0.0 <2.0.0-internal.7.1.0",
|
|
45
|
+
"@fluidframework/protocol-definitions": "^3.0.0",
|
|
46
46
|
"debug": "^4.1.1",
|
|
47
47
|
"events": "^3.1.0",
|
|
48
48
|
"uuid": "^9.0.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@fluid-tools/build-cli": "^0.
|
|
51
|
+
"@fluid-tools/build-cli": "^0.24.0",
|
|
52
52
|
"@fluidframework/build-common": "^2.0.0",
|
|
53
|
-
"@fluidframework/build-tools": "^0.
|
|
53
|
+
"@fluidframework/build-tools": "^0.24.0",
|
|
54
54
|
"@fluidframework/eslint-config-fluid": "^2.1.0",
|
|
55
|
-
"@fluidframework/mocha-test-setup": ">=2.0.0-internal.
|
|
56
|
-
"@fluidframework/telemetry-utils-previous": "npm:@fluidframework/telemetry-utils@2.0.0-internal.6.3.
|
|
57
|
-
"@microsoft/api-extractor": "^7.
|
|
55
|
+
"@fluidframework/mocha-test-setup": ">=2.0.0-internal.7.0.0 <2.0.0-internal.7.1.0",
|
|
56
|
+
"@fluidframework/telemetry-utils-previous": "npm:@fluidframework/telemetry-utils@2.0.0-internal.6.3.0",
|
|
57
|
+
"@microsoft/api-extractor": "^7.37.0",
|
|
58
58
|
"@types/debug": "^4.1.5",
|
|
59
59
|
"@types/events": "^3.0.0",
|
|
60
60
|
"@types/mocha": "^9.1.1",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"prettier": "~2.6.2",
|
|
72
72
|
"rimraf": "^4.4.0",
|
|
73
73
|
"sinon": "^7.4.2",
|
|
74
|
-
"typescript": "~
|
|
74
|
+
"typescript": "~5.1.6"
|
|
75
75
|
},
|
|
76
76
|
"typeValidation": {
|
|
77
77
|
"broken": {}
|
package/src/config.ts
CHANGED
|
@@ -77,10 +77,12 @@ function isPrimitiveType(type: string): type is PrimitiveTypeStrings {
|
|
|
77
77
|
switch (type) {
|
|
78
78
|
case "boolean":
|
|
79
79
|
case "number":
|
|
80
|
-
case "string":
|
|
80
|
+
case "string": {
|
|
81
81
|
return true;
|
|
82
|
-
|
|
82
|
+
}
|
|
83
|
+
default: {
|
|
83
84
|
return false;
|
|
85
|
+
}
|
|
84
86
|
}
|
|
85
87
|
}
|
|
86
88
|
|
package/src/error.ts
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
FluidErrorTypes,
|
|
8
8
|
IGenericError,
|
|
9
9
|
IErrorBase,
|
|
10
|
-
|
|
10
|
+
ITelemetryBaseProperties,
|
|
11
11
|
IUsageError,
|
|
12
12
|
} from "@fluidframework/core-interfaces";
|
|
13
13
|
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
|
|
@@ -23,6 +23,8 @@ import { IFluidErrorBase } from "./fluidErrorBase";
|
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Generic wrapper for an unrecognized/uncategorized error object
|
|
26
|
+
*
|
|
27
|
+
* @internal
|
|
26
28
|
*/
|
|
27
29
|
export class GenericError extends LoggingError implements IGenericError, IFluidErrorBase {
|
|
28
30
|
readonly errorType = FluidErrorTypes.genericError;
|
|
@@ -35,7 +37,7 @@ export class GenericError extends LoggingError implements IGenericError, IFluidE
|
|
|
35
37
|
*/
|
|
36
38
|
// TODO: Use `unknown` instead (API breaking change because error is not just an input parameter, but a public member of the class)
|
|
37
39
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
|
|
38
|
-
constructor(message: string, public readonly error?: any, props?:
|
|
40
|
+
constructor(message: string, public readonly error?: any, props?: ITelemetryBaseProperties) {
|
|
39
41
|
// Don't try to log the inner error
|
|
40
42
|
super(message, props, new Set(["error"]));
|
|
41
43
|
}
|
|
@@ -43,11 +45,13 @@ export class GenericError extends LoggingError implements IGenericError, IFluidE
|
|
|
43
45
|
|
|
44
46
|
/**
|
|
45
47
|
* Error indicating an API is being used improperly resulting in an invalid operation.
|
|
48
|
+
*
|
|
49
|
+
* @internal
|
|
46
50
|
*/
|
|
47
51
|
export class UsageError extends LoggingError implements IUsageError, IFluidErrorBase {
|
|
48
52
|
readonly errorType = FluidErrorTypes.usageError;
|
|
49
53
|
|
|
50
|
-
constructor(message: string, props?:
|
|
54
|
+
constructor(message: string, props?: ITelemetryBaseProperties) {
|
|
51
55
|
super(message, { ...props, usageError: true });
|
|
52
56
|
}
|
|
53
57
|
}
|
|
@@ -55,12 +59,14 @@ export class UsageError extends LoggingError implements IUsageError, IFluidError
|
|
|
55
59
|
/**
|
|
56
60
|
* DataCorruptionError indicates that we encountered definitive evidence that the data at rest
|
|
57
61
|
* backing this container is corrupted, and this container would never be expected to load properly again
|
|
62
|
+
*
|
|
63
|
+
* @internal
|
|
58
64
|
*/
|
|
59
65
|
export class DataCorruptionError extends LoggingError implements IErrorBase, IFluidErrorBase {
|
|
60
66
|
readonly errorType = FluidErrorTypes.dataCorruptionError;
|
|
61
67
|
readonly canRetry = false;
|
|
62
68
|
|
|
63
|
-
constructor(message: string, props:
|
|
69
|
+
constructor(message: string, props: ITelemetryBaseProperties) {
|
|
64
70
|
super(message, { ...props, dataProcessingError: 1 });
|
|
65
71
|
}
|
|
66
72
|
}
|
|
@@ -73,6 +79,8 @@ export class DataCorruptionError extends LoggingError implements IErrorBase, IFl
|
|
|
73
79
|
* The error will often originate in the dataStore or DDS implementation that is responding to incoming changes.
|
|
74
80
|
* This differs from {@link DataCorruptionError} in that this may be a transient error that will not repro in another
|
|
75
81
|
* client or session.
|
|
82
|
+
*
|
|
83
|
+
* @internal
|
|
76
84
|
*/
|
|
77
85
|
export class DataProcessingError extends LoggingError implements IErrorBase, IFluidErrorBase {
|
|
78
86
|
/**
|
|
@@ -82,8 +90,8 @@ export class DataProcessingError extends LoggingError implements IErrorBase, IFl
|
|
|
82
90
|
|
|
83
91
|
public readonly canRetry = false;
|
|
84
92
|
|
|
85
|
-
private constructor(errorMessage: string) {
|
|
86
|
-
super(errorMessage);
|
|
93
|
+
private constructor(errorMessage: string, props?: ITelemetryBaseProperties) {
|
|
94
|
+
super(errorMessage, props);
|
|
87
95
|
}
|
|
88
96
|
|
|
89
97
|
/**
|
|
@@ -93,7 +101,7 @@ export class DataProcessingError extends LoggingError implements IErrorBase, IFl
|
|
|
93
101
|
errorMessage: string,
|
|
94
102
|
dataProcessingCodepath: string,
|
|
95
103
|
sequencedMessage?: ISequencedDocumentMessage,
|
|
96
|
-
props:
|
|
104
|
+
props: ITelemetryBaseProperties = {},
|
|
97
105
|
): IFluidErrorBase {
|
|
98
106
|
const dataProcessingError = DataProcessingError.wrapIfUnrecognized(
|
|
99
107
|
errorMessage,
|
package/src/errorLogging.ts
CHANGED
|
@@ -27,6 +27,8 @@ const isRegularObject = (value: unknown): boolean => {
|
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Inspect the given error for common "safe" props and return them.
|
|
30
|
+
*
|
|
31
|
+
* @internal
|
|
30
32
|
*/
|
|
31
33
|
export function extractLogSafeErrorProperties(
|
|
32
34
|
error: unknown,
|
|
@@ -95,6 +97,8 @@ function copyProps(
|
|
|
95
97
|
|
|
96
98
|
/**
|
|
97
99
|
* Metadata to annotate an error object when annotating or normalizing it
|
|
100
|
+
*
|
|
101
|
+
* @internal
|
|
98
102
|
*/
|
|
99
103
|
export interface IFluidErrorAnnotations {
|
|
100
104
|
/**
|
|
@@ -121,6 +125,8 @@ function patchLegacyError(
|
|
|
121
125
|
* @returns A valid Fluid Error with any provided annotations applied
|
|
122
126
|
* @param error - The error to normalize
|
|
123
127
|
* @param annotations - Annotations to apply to the normalized error
|
|
128
|
+
*
|
|
129
|
+
* @internal
|
|
124
130
|
*/
|
|
125
131
|
export function normalizeError(
|
|
126
132
|
error: unknown,
|
|
@@ -190,6 +196,8 @@ let stackPopulatedOnCreation: boolean | undefined;
|
|
|
190
196
|
* For such cases it's better to not read stack property right away, but rather delay it until / if it's needed
|
|
191
197
|
* Some browsers will populate stack right away, others require throwing Error, so we do auto-detection on the fly.
|
|
192
198
|
* @returns Error object that has stack populated.
|
|
199
|
+
*
|
|
200
|
+
* @internal
|
|
193
201
|
*/
|
|
194
202
|
export function generateErrorWithStack(): Error {
|
|
195
203
|
const err = new Error("<<generated stack>>");
|
|
@@ -209,6 +217,12 @@ export function generateErrorWithStack(): Error {
|
|
|
209
217
|
}
|
|
210
218
|
}
|
|
211
219
|
|
|
220
|
+
/**
|
|
221
|
+
* Generate a stack at this callsite as if an error were thrown from here.
|
|
222
|
+
* @returns the callstack (does not throw)
|
|
223
|
+
*
|
|
224
|
+
* @internal
|
|
225
|
+
*/
|
|
212
226
|
export function generateStack(): string | undefined {
|
|
213
227
|
return generateErrorWithStack().stack;
|
|
214
228
|
}
|
|
@@ -219,6 +233,8 @@ export function generateStack(): string | undefined {
|
|
|
219
233
|
* @param innerError - An error from untrusted/unknown origins
|
|
220
234
|
* @param newErrorFn - callback that will create a new error given the original error's message
|
|
221
235
|
* @returns A new error object "wrapping" the given error
|
|
236
|
+
*
|
|
237
|
+
* @internal
|
|
222
238
|
*/
|
|
223
239
|
export function wrapError<T extends LoggingError>(
|
|
224
240
|
innerError: unknown,
|
|
@@ -258,6 +274,8 @@ export function wrapError<T extends LoggingError>(
|
|
|
258
274
|
* The same as wrapError, but also logs the innerError, including the wrapping error's instance ID.
|
|
259
275
|
*
|
|
260
276
|
* @typeParam T - The kind of wrapper error to create.
|
|
277
|
+
*
|
|
278
|
+
* @internal
|
|
261
279
|
*/
|
|
262
280
|
export function wrapErrorAndLog<T extends LoggingError>(
|
|
263
281
|
innerError: unknown,
|
|
@@ -284,8 +302,15 @@ export function wrapErrorAndLog<T extends LoggingError>(
|
|
|
284
302
|
return newError;
|
|
285
303
|
}
|
|
286
304
|
|
|
287
|
-
|
|
288
|
-
|
|
305
|
+
/**
|
|
306
|
+
* Attempts to overwrite the error's stack
|
|
307
|
+
*
|
|
308
|
+
* There have been reports of certain JS environments where overwriting stack will throw.
|
|
309
|
+
* If that happens, this adds the given stack as the telemetry property "stack2"
|
|
310
|
+
*
|
|
311
|
+
* @internal
|
|
312
|
+
*/
|
|
313
|
+
export function overwriteStack(error: IFluidErrorBase | LoggingError, stack: string): void {
|
|
289
314
|
try {
|
|
290
315
|
Object.assign(error, { stack });
|
|
291
316
|
} catch {
|
|
@@ -297,6 +322,8 @@ function overwriteStack(error: IFluidErrorBase | LoggingError, stack: string): v
|
|
|
297
322
|
* True for any error object that is an (optionally normalized) external error
|
|
298
323
|
* False for any error we created and raised within the FF codebase via LoggingError base class,
|
|
299
324
|
* or wrapped in a well-known error type
|
|
325
|
+
*
|
|
326
|
+
* @internal
|
|
300
327
|
*/
|
|
301
328
|
export function isExternalError(error: unknown): boolean {
|
|
302
329
|
// LoggingErrors are an internal FF error type. However, an external error can be converted
|
|
@@ -322,8 +349,8 @@ export function isTaggedTelemetryPropertyValue(
|
|
|
322
349
|
|
|
323
350
|
/**
|
|
324
351
|
* Filter serializable telemetry properties
|
|
325
|
-
* @param x -
|
|
326
|
-
* @returns -
|
|
352
|
+
* @param x - Any telemetry prop
|
|
353
|
+
* @returns As-is if x is primitive. returns stringified if x is an array of primitive.
|
|
327
354
|
* otherwise returns null since this is what we support at the moment.
|
|
328
355
|
*/
|
|
329
356
|
function filterValidTelemetryProps(x: unknown, key: string): TelemetryBaseEventPropertyType {
|
|
@@ -344,12 +371,15 @@ function isTelemetryEventPropertyValue(x: unknown): x is TelemetryBaseEventPrope
|
|
|
344
371
|
case "string":
|
|
345
372
|
case "number":
|
|
346
373
|
case "boolean":
|
|
347
|
-
case "undefined":
|
|
374
|
+
case "undefined": {
|
|
348
375
|
return true;
|
|
349
|
-
|
|
376
|
+
}
|
|
377
|
+
default: {
|
|
350
378
|
return false;
|
|
379
|
+
}
|
|
351
380
|
}
|
|
352
381
|
}
|
|
382
|
+
|
|
353
383
|
/**
|
|
354
384
|
* Walk an object's enumerable properties to find those fit for telemetry.
|
|
355
385
|
*/
|
|
@@ -364,14 +394,12 @@ function getValidTelemetryProps(obj: object, keysToOmit: Set<string>): ITelemetr
|
|
|
364
394
|
| Tagged<TelemetryEventPropertyTypeExt>;
|
|
365
395
|
|
|
366
396
|
// ensure only valid props get logged, since props of logging error could be in any shape
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
props[key] = filterValidTelemetryProps(val, key);
|
|
374
|
-
}
|
|
397
|
+
props[key] = isTaggedTelemetryPropertyValue(val)
|
|
398
|
+
? {
|
|
399
|
+
value: filterValidTelemetryProps(val.value, key),
|
|
400
|
+
tag: val.tag,
|
|
401
|
+
}
|
|
402
|
+
: filterValidTelemetryProps(val, key);
|
|
375
403
|
}
|
|
376
404
|
return props;
|
|
377
405
|
}
|
|
@@ -382,6 +410,8 @@ function getValidTelemetryProps(obj: object, keysToOmit: Set<string>): ITelemetr
|
|
|
382
410
|
* Avoids runtime errors with circular references.
|
|
383
411
|
* Not ideal, as will cut values that are not necessarily circular references.
|
|
384
412
|
* Could be improved by implementing Node's util.inspect() for browser (minus all the coloring code)
|
|
413
|
+
*
|
|
414
|
+
* @internal
|
|
385
415
|
*/
|
|
386
416
|
// TODO: Use `unknown` instead (API breaking change)
|
|
387
417
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
@@ -405,6 +435,8 @@ export const getCircularReplacer = (): ((key: string, value: unknown) => any) =>
|
|
|
405
435
|
* will be logged in accordance with their tag, if present.
|
|
406
436
|
*
|
|
407
437
|
* PLEASE take care to avoid setting sensitive data on this object without proper tagging!
|
|
438
|
+
*
|
|
439
|
+
* @internal
|
|
408
440
|
*/
|
|
409
441
|
export class LoggingError
|
|
410
442
|
extends Error
|
|
@@ -450,7 +482,7 @@ export class LoggingError
|
|
|
450
482
|
/**
|
|
451
483
|
* Determines if a given object is an instance of a LoggingError
|
|
452
484
|
* @param object - any object
|
|
453
|
-
* @returns
|
|
485
|
+
* @returns true if the object is an instance of a LoggingError, false if not.
|
|
454
486
|
*/
|
|
455
487
|
public static typeCheck(object: unknown): object is LoggingError {
|
|
456
488
|
if (typeof object === "object" && object !== null) {
|
|
@@ -487,8 +519,16 @@ export class LoggingError
|
|
|
487
519
|
|
|
488
520
|
/**
|
|
489
521
|
* The Error class used when normalizing an external error
|
|
522
|
+
*
|
|
523
|
+
* @internal
|
|
490
524
|
*/
|
|
491
525
|
export const NORMALIZED_ERROR_TYPE = "genericError";
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Subclass of LoggingError returned by normalizeError
|
|
529
|
+
*
|
|
530
|
+
* @internal
|
|
531
|
+
*/
|
|
492
532
|
class NormalizedLoggingError extends LoggingError {
|
|
493
533
|
// errorType "genericError" is used as a default value throughout the code.
|
|
494
534
|
// Note that this matches ContainerErrorType/DriverErrorType's genericError
|
package/src/events.ts
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
// False positive: this is an import from the `events` package, not from Node.
|
|
7
|
+
// eslint-disable-next-line unicorn/prefer-node-protocol
|
|
6
8
|
import { EventEmitter } from "events";
|
|
7
9
|
import { ITelemetryLoggerExt } from "./telemetryTypes";
|
|
8
10
|
|
package/src/index.ts
CHANGED
package/src/logger.ts
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
LogLevel,
|
|
15
15
|
Tagged,
|
|
16
16
|
ITelemetryBaseProperties,
|
|
17
|
+
TelemetryBaseEventPropertyType,
|
|
17
18
|
} from "@fluidframework/core-interfaces";
|
|
18
19
|
import { IsomorphicPerformance, performance } from "@fluid-internal/client-utils";
|
|
19
20
|
import { CachedConfigProvider, loggerIsMonitoringContext, mixinMonitoringContext } from "./config";
|
|
@@ -304,26 +305,30 @@ export class TaggedLoggerAdapter implements ITelemetryBaseLogger {
|
|
|
304
305
|
? taggableProp
|
|
305
306
|
: { value: taggableProp, tag: undefined };
|
|
306
307
|
switch (tag) {
|
|
307
|
-
case undefined:
|
|
308
|
+
case undefined: {
|
|
308
309
|
// No tag means we can log plainly
|
|
309
310
|
newEvent[key] = value;
|
|
310
311
|
break;
|
|
312
|
+
}
|
|
311
313
|
case "PackageData": // For back-compat
|
|
312
|
-
case TelemetryDataTag.CodeArtifact:
|
|
314
|
+
case TelemetryDataTag.CodeArtifact: {
|
|
313
315
|
// For Microsoft applications, CodeArtifact is safe for now
|
|
314
316
|
// (we don't load 3P code in 1P apps)
|
|
315
317
|
newEvent[key] = value;
|
|
316
318
|
break;
|
|
317
|
-
|
|
319
|
+
}
|
|
320
|
+
case TelemetryDataTag.UserData: {
|
|
318
321
|
// Strip out anything tagged explicitly as UserData.
|
|
319
322
|
// Alternate strategy would be to hash these props
|
|
320
323
|
newEvent[key] = "REDACTED (UserData)";
|
|
321
324
|
break;
|
|
322
|
-
|
|
325
|
+
}
|
|
326
|
+
default: {
|
|
323
327
|
// If we encounter a tag we don't recognize
|
|
324
328
|
// then we must assume we should scrub.
|
|
325
329
|
newEvent[key] = "REDACTED (unknown tag)";
|
|
326
330
|
break;
|
|
331
|
+
}
|
|
327
332
|
}
|
|
328
333
|
}
|
|
329
334
|
this.logger.send(newEvent);
|
|
@@ -403,11 +408,7 @@ export class ChildLogger extends TelemetryLogger {
|
|
|
403
408
|
return child;
|
|
404
409
|
}
|
|
405
410
|
|
|
406
|
-
return new ChildLogger(
|
|
407
|
-
baseLogger ? baseLogger : { send(): void {} },
|
|
408
|
-
namespace,
|
|
409
|
-
properties,
|
|
410
|
-
);
|
|
411
|
+
return new ChildLogger(baseLogger ?? { send(): void {} }, namespace, properties);
|
|
411
412
|
}
|
|
412
413
|
|
|
413
414
|
private constructor(
|
|
@@ -488,7 +489,7 @@ export class MultiSinkLogger extends TelemetryLogger {
|
|
|
488
489
|
loggers: ITelemetryBaseLogger[] = [],
|
|
489
490
|
tryInheritProperties?: true,
|
|
490
491
|
) {
|
|
491
|
-
let realProperties = properties
|
|
492
|
+
let realProperties = properties === undefined ? undefined : { ...properties };
|
|
492
493
|
if (tryInheritProperties === true) {
|
|
493
494
|
const merge = (realProperties ??= {});
|
|
494
495
|
loggers
|
|
@@ -629,8 +630,7 @@ export class PerformanceEvent {
|
|
|
629
630
|
this.reportEvent("start");
|
|
630
631
|
}
|
|
631
632
|
|
|
632
|
-
|
|
633
|
-
if (typeof window === "object" && window != null && window.performance?.mark) {
|
|
633
|
+
if (typeof window === "object" && window?.performance?.mark) {
|
|
634
634
|
this.startMark = `${event.eventName}-start`;
|
|
635
635
|
window.performance.mark(this.startMark);
|
|
636
636
|
}
|
|
@@ -768,54 +768,85 @@ function convertToBasePropertyTypeUntagged(
|
|
|
768
768
|
case "string":
|
|
769
769
|
case "number":
|
|
770
770
|
case "boolean":
|
|
771
|
-
case "undefined":
|
|
771
|
+
case "undefined": {
|
|
772
772
|
return x;
|
|
773
|
-
|
|
773
|
+
}
|
|
774
|
+
case "object": {
|
|
774
775
|
// We assume this is an array or flat object based on the input types
|
|
775
776
|
return JSON.stringify(x);
|
|
776
|
-
|
|
777
|
+
}
|
|
778
|
+
default: {
|
|
777
779
|
// should never reach this case based on the input types
|
|
778
780
|
console.error(
|
|
779
781
|
`convertToBasePropertyTypeUntagged: INVALID PROPERTY (typed as ${typeof x})`,
|
|
780
782
|
);
|
|
781
783
|
return `INVALID PROPERTY (typed as ${typeof x})`;
|
|
784
|
+
}
|
|
782
785
|
}
|
|
783
786
|
}
|
|
784
787
|
|
|
785
788
|
export const tagData = <
|
|
786
789
|
T extends TelemetryDataTag,
|
|
787
|
-
V extends Record<
|
|
790
|
+
V extends Record<
|
|
791
|
+
string,
|
|
792
|
+
TelemetryBaseEventPropertyType | (() => TelemetryBaseEventPropertyType)
|
|
793
|
+
>,
|
|
788
794
|
>(
|
|
789
795
|
tag: T,
|
|
790
796
|
values: V,
|
|
791
797
|
): {
|
|
792
798
|
[P in keyof V]:
|
|
793
|
-
|
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
799
|
+
| (V[P] extends () => TelemetryBaseEventPropertyType
|
|
800
|
+
? () => {
|
|
801
|
+
value: ReturnType<V[P]>;
|
|
802
|
+
tag: T;
|
|
803
|
+
}
|
|
804
|
+
: {
|
|
805
|
+
value: Exclude<V[P], undefined>;
|
|
806
|
+
tag: T;
|
|
807
|
+
})
|
|
797
808
|
| (V[P] extends undefined ? undefined : never);
|
|
798
809
|
} =>
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
810
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
811
|
+
Object.entries(values)
|
|
812
|
+
.filter((e) => e[1] !== undefined)
|
|
813
|
+
// eslint-disable-next-line unicorn/no-array-reduce, unicorn/prefer-object-from-entries
|
|
814
|
+
.reduce((pv, cv) => {
|
|
815
|
+
const [key, value] = cv;
|
|
816
|
+
// The ternary form is less legible in this case.
|
|
817
|
+
// eslint-disable-next-line unicorn/prefer-ternary
|
|
818
|
+
if (typeof value === "function") {
|
|
819
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
820
|
+
pv[key] = () => {
|
|
821
|
+
return { tag, value: value() };
|
|
822
|
+
};
|
|
823
|
+
} else {
|
|
824
|
+
pv[key] = { tag, value };
|
|
825
|
+
}
|
|
808
826
|
return pv;
|
|
809
|
-
|
|
810
|
-
}, {} as any);
|
|
827
|
+
}, {}) as ReturnType<typeof tagData>;
|
|
811
828
|
|
|
812
|
-
|
|
829
|
+
/**
|
|
830
|
+
* Helper function to tag telemetry properties as CodeArtifacts. It supports properties of type
|
|
831
|
+
* TelemetryBaseEventPropertyType as well as getters that return TelemetryBaseEventPropertyType.
|
|
832
|
+
*/
|
|
833
|
+
export const tagCodeArtifacts = <
|
|
834
|
+
T extends Record<
|
|
835
|
+
string,
|
|
836
|
+
TelemetryBaseEventPropertyType | (() => TelemetryBaseEventPropertyType)
|
|
837
|
+
>,
|
|
838
|
+
>(
|
|
813
839
|
values: T,
|
|
814
840
|
): {
|
|
815
841
|
[P in keyof T]:
|
|
816
|
-
|
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
842
|
+
| (T[P] extends () => TelemetryBaseEventPropertyType
|
|
843
|
+
? () => {
|
|
844
|
+
value: ReturnType<T[P]>;
|
|
845
|
+
tag: TelemetryDataTag.CodeArtifact;
|
|
846
|
+
}
|
|
847
|
+
: {
|
|
848
|
+
value: Exclude<T[P], undefined>;
|
|
849
|
+
tag: TelemetryDataTag.CodeArtifact;
|
|
850
|
+
})
|
|
820
851
|
| (T[P] extends undefined ? undefined : never);
|
|
821
|
-
} => tagData(TelemetryDataTag.CodeArtifact, values);
|
|
852
|
+
} => tagData<TelemetryDataTag.CodeArtifact, T>(TelemetryDataTag.CodeArtifact, values);
|
package/src/utils.ts
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
* @param condition - The condition to attest too
|
|
14
14
|
* @param logger - The logger to log with
|
|
15
15
|
* @param event - The string or event to log
|
|
16
|
-
* @returns
|
|
16
|
+
* @returns The outcome of the condition
|
|
17
17
|
*/
|
|
18
18
|
export function logIfFalse(
|
|
19
19
|
condition: unknown,
|