@fluidframework/telemetry-utils 2.0.0-dev.5.3.2.178189 → 2.0.0-dev.6.4.0.191457

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.
Files changed (122) hide show
  1. package/.eslintrc.js +2 -1
  2. package/CHANGELOG.md +108 -0
  3. package/README.md +4 -3
  4. package/dist/config.d.ts +2 -0
  5. package/dist/config.d.ts.map +1 -1
  6. package/dist/config.js +34 -36
  7. package/dist/config.js.map +1 -1
  8. package/dist/error.d.ts +92 -0
  9. package/dist/error.d.ts.map +1 -0
  10. package/dist/error.js +133 -0
  11. package/dist/error.js.map +1 -0
  12. package/dist/errorLogging.d.ts +44 -19
  13. package/dist/errorLogging.d.ts.map +1 -1
  14. package/dist/errorLogging.js +70 -31
  15. package/dist/errorLogging.js.map +1 -1
  16. package/dist/eventEmitterWithErrorHandling.d.ts +3 -3
  17. package/dist/eventEmitterWithErrorHandling.d.ts.map +1 -1
  18. package/dist/eventEmitterWithErrorHandling.js +10 -3
  19. package/dist/eventEmitterWithErrorHandling.js.map +1 -1
  20. package/dist/events.d.ts +1 -1
  21. package/dist/events.d.ts.map +1 -1
  22. package/dist/events.js.map +1 -1
  23. package/dist/fluidErrorBase.d.ts +48 -15
  24. package/dist/fluidErrorBase.d.ts.map +1 -1
  25. package/dist/fluidErrorBase.js +21 -14
  26. package/dist/fluidErrorBase.js.map +1 -1
  27. package/dist/index.d.ts +5 -5
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +16 -8
  30. package/dist/index.js.map +1 -1
  31. package/dist/logger.d.ts +98 -60
  32. package/dist/logger.d.ts.map +1 -1
  33. package/dist/logger.js +193 -124
  34. package/dist/logger.js.map +1 -1
  35. package/dist/mockLogger.d.ts +17 -8
  36. package/dist/mockLogger.d.ts.map +1 -1
  37. package/dist/mockLogger.js +49 -28
  38. package/dist/mockLogger.js.map +1 -1
  39. package/dist/sampledTelemetryHelper.d.ts +8 -7
  40. package/dist/sampledTelemetryHelper.d.ts.map +1 -1
  41. package/dist/sampledTelemetryHelper.js +21 -16
  42. package/dist/sampledTelemetryHelper.js.map +1 -1
  43. package/dist/telemetryTypes.d.ts +20 -6
  44. package/dist/telemetryTypes.d.ts.map +1 -1
  45. package/dist/telemetryTypes.js.map +1 -1
  46. package/dist/thresholdCounter.d.ts.map +1 -1
  47. package/dist/thresholdCounter.js.map +1 -1
  48. package/dist/utils.d.ts +2 -2
  49. package/dist/utils.d.ts.map +1 -1
  50. package/dist/utils.js +2 -2
  51. package/dist/utils.js.map +1 -1
  52. package/lib/config.d.ts +2 -0
  53. package/lib/config.d.ts.map +1 -1
  54. package/lib/config.js +33 -36
  55. package/lib/config.js.map +1 -1
  56. package/lib/error.d.ts +92 -0
  57. package/lib/error.d.ts.map +1 -0
  58. package/lib/error.js +125 -0
  59. package/lib/error.js.map +1 -0
  60. package/lib/errorLogging.d.ts +44 -19
  61. package/lib/errorLogging.d.ts.map +1 -1
  62. package/lib/errorLogging.js +69 -31
  63. package/lib/errorLogging.js.map +1 -1
  64. package/lib/eventEmitterWithErrorHandling.d.ts +3 -3
  65. package/lib/eventEmitterWithErrorHandling.d.ts.map +1 -1
  66. package/lib/eventEmitterWithErrorHandling.js +9 -2
  67. package/lib/eventEmitterWithErrorHandling.js.map +1 -1
  68. package/lib/events.d.ts +1 -1
  69. package/lib/events.d.ts.map +1 -1
  70. package/lib/events.js.map +1 -1
  71. package/lib/fluidErrorBase.d.ts +48 -15
  72. package/lib/fluidErrorBase.d.ts.map +1 -1
  73. package/lib/fluidErrorBase.js +21 -14
  74. package/lib/fluidErrorBase.js.map +1 -1
  75. package/lib/index.d.ts +5 -5
  76. package/lib/index.d.ts.map +1 -1
  77. package/lib/index.js +4 -4
  78. package/lib/index.js.map +1 -1
  79. package/lib/logger.d.ts +98 -60
  80. package/lib/logger.d.ts.map +1 -1
  81. package/lib/logger.js +184 -119
  82. package/lib/logger.js.map +1 -1
  83. package/lib/mockLogger.d.ts +17 -8
  84. package/lib/mockLogger.d.ts.map +1 -1
  85. package/lib/mockLogger.js +50 -29
  86. package/lib/mockLogger.js.map +1 -1
  87. package/lib/sampledTelemetryHelper.d.ts +8 -7
  88. package/lib/sampledTelemetryHelper.d.ts.map +1 -1
  89. package/lib/sampledTelemetryHelper.js +19 -14
  90. package/lib/sampledTelemetryHelper.js.map +1 -1
  91. package/lib/telemetryTypes.d.ts +20 -6
  92. package/lib/telemetryTypes.d.ts.map +1 -1
  93. package/lib/telemetryTypes.js.map +1 -1
  94. package/lib/thresholdCounter.d.ts.map +1 -1
  95. package/lib/thresholdCounter.js.map +1 -1
  96. package/lib/utils.d.ts +2 -2
  97. package/lib/utils.d.ts.map +1 -1
  98. package/lib/utils.js +2 -2
  99. package/lib/utils.js.map +1 -1
  100. package/package.json +19 -22
  101. package/src/config.ts +23 -13
  102. package/src/error.ts +202 -0
  103. package/src/errorLogging.ts +101 -56
  104. package/src/eventEmitterWithErrorHandling.ts +5 -3
  105. package/src/events.ts +3 -3
  106. package/src/fluidErrorBase.ts +62 -26
  107. package/src/index.ts +17 -6
  108. package/src/logger.ts +290 -120
  109. package/src/mockLogger.ts +65 -24
  110. package/src/sampledTelemetryHelper.ts +18 -14
  111. package/src/telemetryTypes.ts +29 -6
  112. package/src/thresholdCounter.ts +2 -2
  113. package/src/utils.ts +2 -2
  114. package/dist/debugLogger.d.ts +0 -39
  115. package/dist/debugLogger.d.ts.map +0 -1
  116. package/dist/debugLogger.js +0 -112
  117. package/dist/debugLogger.js.map +0 -1
  118. package/lib/debugLogger.d.ts +0 -39
  119. package/lib/debugLogger.d.ts.map +0 -1
  120. package/lib/debugLogger.js +0 -108
  121. package/lib/debugLogger.js.map +0 -1
  122. package/src/debugLogger.ts +0 -143
package/lib/logger.js CHANGED
@@ -2,18 +2,8 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- var __rest = (this && this.__rest) || function (s, e) {
6
- var t = {};
7
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
8
- t[p] = s[p];
9
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
10
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
11
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
12
- t[p[i]] = s[p[i]];
13
- }
14
- return t;
15
- };
16
- import { performance } from "@fluidframework/common-utils";
5
+ import { LogLevel, } from "@fluidframework/core-interfaces";
6
+ import { performance } from "@fluid-internal/client-utils";
17
7
  import { CachedConfigProvider, loggerIsMonitoringContext, mixinMonitoringContext } from "./config";
18
8
  import { isILoggingError, extractLogSafeErrorProperties, generateStack, isTaggedTelemetryPropertyValue, } from "./errorLogging";
19
9
  /**
@@ -22,11 +12,33 @@ import { isILoggingError, extractLogSafeErrorProperties, generateStack, isTagged
22
12
  */
23
13
  export var TelemetryDataTag;
24
14
  (function (TelemetryDataTag) {
25
- /** Data containing terms or IDs from code packages that may have been dynamically loaded */
15
+ /**
16
+ * Data containing terms or IDs from code packages that may have been dynamically loaded
17
+ */
26
18
  TelemetryDataTag["CodeArtifact"] = "CodeArtifact";
27
- /** Personal data of a variety of classifications that pertains to the user */
19
+ /**
20
+ * Personal data of a variety of classifications that pertains to the user
21
+ */
28
22
  TelemetryDataTag["UserData"] = "UserData";
29
23
  })(TelemetryDataTag || (TelemetryDataTag = {}));
24
+ /**
25
+ * Attempts to parse number from string.
26
+ * If fails,returns original string.
27
+ * Used to make telemetry data typed (and support math operations, like comparison),
28
+ * in places where we do expect numbers (like contentsize/duration property in http header)
29
+ */
30
+ // eslint-disable-next-line @rushstack/no-new-null
31
+ export function numberFromString(str) {
32
+ if (str === undefined || str === null) {
33
+ return undefined;
34
+ }
35
+ const num = Number(str);
36
+ return Number.isNaN(num) ? str : num;
37
+ }
38
+ export function formatTick(tick) {
39
+ return Math.floor(tick);
40
+ }
41
+ export const eventNamespaceSeparator = ":";
30
42
  /**
31
43
  * TelemetryLogger class contains various helper telemetry methods,
32
44
  * encoding in one place schemas for various types of Fluid telemetry events.
@@ -37,22 +49,6 @@ export class TelemetryLogger {
37
49
  this.namespace = namespace;
38
50
  this.properties = properties;
39
51
  }
40
- static formatTick(tick) {
41
- return Math.floor(tick);
42
- }
43
- /**
44
- * Attempts to parse number from string.
45
- * If fails,returns original string.
46
- * Used to make telemetry data typed (and support math operations, like comparison),
47
- * in places where we do expect numbers (like contentsize/duration property in http header)
48
- */
49
- static numberFromString(str) {
50
- if (str === undefined || str === null) {
51
- return undefined;
52
- }
53
- const num = Number(str);
54
- return Number.isNaN(num) ? str : num;
55
- }
56
52
  static sanitizePkgName(name) {
57
53
  return name.replace("@", "").replace("/", "-");
58
54
  }
@@ -90,27 +86,29 @@ export class TelemetryLogger {
90
86
  *
91
87
  * @param event - the event to send
92
88
  * @param error - optional error object to log
89
+ * @param logLevel - optional level of the log. It category of event is set as error,
90
+ * then the logLevel will be upgraded to be an error.
93
91
  */
94
- sendTelemetryEvent(event, error) {
95
- var _a;
96
- this.sendTelemetryEventCore(Object.assign(Object.assign({}, event), { category: (_a = event.category) !== null && _a !== void 0 ? _a : "generic" }), error);
92
+ sendTelemetryEvent(event, error, logLevel = LogLevel.default) {
93
+ this.sendTelemetryEventCore({ ...event, category: event.category ?? "generic" }, error, event.category === "error" ? LogLevel.error : logLevel);
97
94
  }
98
95
  /**
99
96
  * Send a telemetry event with the logger
100
97
  *
101
98
  * @param event - the event to send
102
99
  * @param error - optional error object to log
100
+ * @param logLevel - optional level of the log.
103
101
  */
104
- sendTelemetryEventCore(event, error) {
102
+ sendTelemetryEventCore(event, error, logLevel) {
105
103
  const newEvent = convertToBaseEvent(event);
106
104
  if (error !== undefined) {
107
105
  TelemetryLogger.prepareErrorObject(newEvent, error, false);
108
106
  }
109
107
  // Will include Nan & Infinity, but probably we do not care
110
108
  if (typeof newEvent.duration === "number") {
111
- newEvent.duration = TelemetryLogger.formatTick(newEvent.duration);
109
+ newEvent.duration = formatTick(newEvent.duration);
112
110
  }
113
- this.send(newEvent);
111
+ this.send(newEvent, logLevel);
114
112
  }
115
113
  /**
116
114
  * Send an error telemetry event with the logger
@@ -119,28 +117,41 @@ export class TelemetryLogger {
119
117
  * @param error - optional error object to log
120
118
  */
121
119
  sendErrorEvent(event, error) {
122
- this.sendTelemetryEventCore(Object.assign(Object.assign({
120
+ this.sendTelemetryEventCore({
123
121
  // ensure the error field has some value,
124
122
  // this can and will be overridden by event, or error
125
- error: event.eventName }, event), { category: "error" }), error);
123
+ error: event.eventName,
124
+ ...event,
125
+ category: "error",
126
+ }, error, LogLevel.error);
126
127
  }
127
128
  /**
128
129
  * Send a performance telemetry event with the logger
129
130
  *
130
131
  * @param event - Event to send
131
132
  * @param error - optional error object to log
133
+ * @param logLevel - optional level of the log. It category of event is set as error,
134
+ * then the logLevel will be upgraded to be an error.
132
135
  */
133
- sendPerformanceEvent(event, error) {
134
- var _a;
135
- const perfEvent = Object.assign(Object.assign({}, event), { category: (_a = event.category) !== null && _a !== void 0 ? _a : "performance" });
136
- this.sendTelemetryEventCore(perfEvent, error);
136
+ sendPerformanceEvent(event, error, logLevel = LogLevel.default) {
137
+ const perfEvent = {
138
+ ...event,
139
+ category: event.category ?? "performance",
140
+ };
141
+ this.sendTelemetryEventCore(perfEvent, error, perfEvent.category === "error" ? LogLevel.error : logLevel);
137
142
  }
138
143
  prepareEvent(event) {
139
144
  const includeErrorProps = event.category === "error" || event.error !== undefined;
140
- const newEvent = Object.assign({}, event);
145
+ const newEvent = {
146
+ ...event,
147
+ };
141
148
  if (this.namespace !== undefined) {
142
149
  newEvent.eventName = `${this.namespace}${TelemetryLogger.eventNamespaceSeparator}${newEvent.eventName}`;
143
150
  }
151
+ return this.extendProperties(newEvent, includeErrorProps);
152
+ }
153
+ extendProperties(toExtend, includeErrorProps) {
154
+ const eventLike = toExtend;
144
155
  if (this.properties) {
145
156
  const properties = [];
146
157
  properties.push(this.properties.all);
@@ -150,23 +161,23 @@ export class TelemetryLogger {
150
161
  for (const props of properties) {
151
162
  if (props !== undefined) {
152
163
  for (const key of Object.keys(props)) {
153
- if (event[key] !== undefined) {
164
+ if (eventLike[key] !== undefined) {
154
165
  continue;
155
166
  }
156
167
  const getterOrValue = props[key];
157
168
  // If this throws, hopefully it is handled elsewhere
158
169
  const value = typeof getterOrValue === "function" ? getterOrValue() : getterOrValue;
159
170
  if (value !== undefined) {
160
- newEvent[key] = value;
171
+ eventLike[key] = value;
161
172
  }
162
173
  }
163
174
  }
164
175
  }
165
176
  }
166
- return newEvent;
177
+ return toExtend;
167
178
  }
168
179
  }
169
- TelemetryLogger.eventNamespaceSeparator = ":";
180
+ TelemetryLogger.eventNamespaceSeparator = eventNamespaceSeparator;
170
181
  /**
171
182
  * @deprecated 0.56, remove TaggedLoggerAdapter once its usage is removed from
172
183
  * container-runtime. Issue: #8191
@@ -176,6 +187,9 @@ export class TaggedLoggerAdapter {
176
187
  constructor(logger) {
177
188
  this.logger = logger;
178
189
  }
190
+ /**
191
+ * {@inheritDoc @fluidframework/core-interfaces#ITelemetryBaseLogger.send}
192
+ */
179
193
  send(eventWithTagsMaybe) {
180
194
  const newEvent = {
181
195
  category: eventWithTagsMaybe.category,
@@ -212,6 +226,16 @@ export class TaggedLoggerAdapter {
212
226
  this.logger.send(newEvent);
213
227
  }
214
228
  }
229
+ /**
230
+ * Create a child logger based on the provided props object
231
+ * @param props - logger is the base logger the child will log to after it's processing, namespace will be prefixed to all event names, properties are default properties that will be applied events.
232
+ *
233
+ * @remarks
234
+ * Passing in no props object (i.e. undefined) will return a logger that is effectively a no-op.
235
+ */
236
+ export function createChildLogger(props) {
237
+ return ChildLogger.create(props?.logger, props?.namespace, props?.properties);
238
+ }
215
239
  /**
216
240
  * ChildLogger class contains various helper telemetry methods,
217
241
  * encoding in one place schemas for various types of Fluid telemetry events.
@@ -241,10 +265,16 @@ export class ChildLogger extends TelemetryLogger {
241
265
  for (const extendedProps of [baseLogger.properties, properties]) {
242
266
  if (extendedProps !== undefined) {
243
267
  if (extendedProps.all !== undefined) {
244
- combinedProperties.all = Object.assign(Object.assign({}, combinedProperties.all), extendedProps.all);
268
+ combinedProperties.all = {
269
+ ...combinedProperties.all,
270
+ ...extendedProps.all,
271
+ };
245
272
  }
246
273
  if (extendedProps.error !== undefined) {
247
- combinedProperties.error = Object.assign(Object.assign({}, combinedProperties.error), extendedProps.error);
274
+ combinedProperties.error = {
275
+ ...combinedProperties.error,
276
+ ...extendedProps.error,
277
+ };
248
278
  }
249
279
  }
250
280
  }
@@ -253,19 +283,43 @@ export class ChildLogger extends TelemetryLogger {
253
283
  : namespace === undefined
254
284
  ? baseLogger.namespace
255
285
  : `${baseLogger.namespace}${TelemetryLogger.eventNamespaceSeparator}${namespace}`;
256
- return new ChildLogger(baseLogger.baseLogger, combinedNamespace, combinedProperties);
286
+ const child = new ChildLogger(baseLogger.baseLogger, combinedNamespace, combinedProperties);
287
+ if (!loggerIsMonitoringContext(child) && loggerIsMonitoringContext(baseLogger)) {
288
+ mixinMonitoringContext(child, baseLogger.config);
289
+ }
290
+ return child;
257
291
  }
258
- return new ChildLogger(baseLogger ? baseLogger : new BaseTelemetryNullLogger(), namespace, properties);
292
+ return new ChildLogger(baseLogger ? baseLogger : { send() { } }, namespace, properties);
293
+ }
294
+ get minLogLevel() {
295
+ return this.baseLogger.minLogLevel;
296
+ }
297
+ shouldFilterOutEvent(event, logLevel) {
298
+ const eventLogLevel = logLevel ?? LogLevel.default;
299
+ const configLogLevel = this.baseLogger.minLogLevel ?? LogLevel.default;
300
+ // Filter out in case event log level is below what is wanted in config.
301
+ return eventLogLevel < configLogLevel;
259
302
  }
260
303
  /**
261
304
  * Send an event with the logger
262
305
  *
263
306
  * @param event - the event to send
264
307
  */
265
- send(event) {
266
- this.baseLogger.send(this.prepareEvent(event));
308
+ send(event, logLevel) {
309
+ if (this.shouldFilterOutEvent(event, logLevel)) {
310
+ return;
311
+ }
312
+ this.baseLogger.send(this.prepareEvent(event), logLevel);
267
313
  }
268
314
  }
315
+ /**
316
+ * Create a logger which logs to multiple other loggers based on the provided props object
317
+ * @param props - loggers are the base loggers that will logged to after it's processing, namespace will be prefixed to all event names, properties are default properties that will be applied events.
318
+ * tryInheritProperties will attempted to copy those loggers properties to this loggers if they are of a known type e.g. one from this package
319
+ */
320
+ export function createMultiSinkLogger(props) {
321
+ return new MultiSinkLogger(props.namespace, props.properties, props.loggers?.filter((l) => l !== undefined), props.tryInheritProperties);
322
+ }
269
323
  /**
270
324
  * Multi-sink logger
271
325
  * Takes multiple ITelemetryBaseLogger objects (sinks) and logs all events into each sink
@@ -275,10 +329,41 @@ export class MultiSinkLogger extends TelemetryLogger {
275
329
  * Create multiple sink logger (i.e. logger that sends events to multiple sinks)
276
330
  * @param namespace - Telemetry event name prefix to add to all events
277
331
  * @param properties - Base properties to add to all events
332
+ * @param loggers - The list of loggers to use as sinks
333
+ * @param tryInheritProperties - Will attempted to copy those loggers properties to this loggers if they are of a known type e.g. one from this package
278
334
  */
279
- constructor(namespace, properties) {
280
- super(namespace, properties);
281
- this.loggers = [];
335
+ constructor(namespace, properties, loggers = [], tryInheritProperties) {
336
+ let realProperties = properties !== undefined ? { ...properties } : undefined;
337
+ if (tryInheritProperties === true) {
338
+ const merge = (realProperties ?? (realProperties = {}));
339
+ loggers
340
+ .filter((l) => l instanceof TelemetryLogger)
341
+ .map((l) => l.properties ?? {})
342
+ // eslint-disable-next-line unicorn/no-array-for-each
343
+ .forEach((cv) => {
344
+ // eslint-disable-next-line unicorn/no-array-for-each
345
+ Object.keys(cv).forEach((k) => {
346
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
347
+ merge[k] = { ...cv[k], ...merge?.[k] };
348
+ });
349
+ });
350
+ }
351
+ super(namespace, realProperties);
352
+ this.loggers = loggers;
353
+ this._minLogLevelOfAllLoggers = LogLevel.default;
354
+ this.calculateMinLogLevel();
355
+ }
356
+ get minLogLevel() {
357
+ return this._minLogLevelOfAllLoggers;
358
+ }
359
+ calculateMinLogLevel() {
360
+ if (this.loggers.length > 0) {
361
+ const logLevels = [];
362
+ for (const logger of this.loggers) {
363
+ logLevels.push(logger.minLogLevel ?? LogLevel.default);
364
+ }
365
+ this._minLogLevelOfAllLoggers = Math.min(...logLevels);
366
+ }
282
367
  }
283
368
  /**
284
369
  * Add logger to send all events to
@@ -287,6 +372,8 @@ export class MultiSinkLogger extends TelemetryLogger {
287
372
  addLogger(logger) {
288
373
  if (logger !== undefined && logger !== null) {
289
374
  this.loggers.push(logger);
375
+ // Update in case the logLevel of added logger is less than the current.
376
+ this.calculateMinLogLevel();
290
377
  }
291
378
  }
292
379
  /**
@@ -296,9 +383,9 @@ export class MultiSinkLogger extends TelemetryLogger {
296
383
  */
297
384
  send(event) {
298
385
  const newEvent = this.prepareEvent(event);
299
- this.loggers.forEach((logger) => {
386
+ for (const logger of this.loggers) {
300
387
  logger.send(newEvent);
301
- });
388
+ }
302
389
  }
303
390
  }
304
391
  /**
@@ -306,17 +393,17 @@ export class MultiSinkLogger extends TelemetryLogger {
306
393
  */
307
394
  export class PerformanceEvent {
308
395
  constructor(logger, event, markers = { end: true, cancel: "generic" }, recordHeapSize = false) {
309
- var _a;
310
396
  this.logger = logger;
311
397
  this.markers = markers;
312
398
  this.recordHeapSize = recordHeapSize;
313
399
  this.startTime = performance.now();
314
400
  this.startMemoryCollection = 0;
315
- this.event = Object.assign({}, event);
401
+ this.event = { ...event };
316
402
  if (this.markers.start) {
317
403
  this.reportEvent("start");
318
404
  }
319
- if (typeof window === "object" && window != null && ((_a = window.performance) === null || _a === void 0 ? void 0 : _a.mark)) {
405
+ // eslint-disable-next-line unicorn/no-null
406
+ if (typeof window === "object" && window != null && window.performance?.mark) {
320
407
  this.startMark = `${event.eventName}-start`;
321
408
  window.performance.mark(this.startMark);
322
409
  }
@@ -377,7 +464,7 @@ export class PerformanceEvent {
377
464
  }
378
465
  cancel(props, error) {
379
466
  if (this.markers.cancel !== undefined) {
380
- this.reportEvent("cancel", Object.assign({ category: this.markers.cancel }, props), error);
467
+ this.reportEvent("cancel", { category: this.markers.cancel, ...props }, error);
381
468
  }
382
469
  this.event = undefined;
383
470
  }
@@ -385,19 +472,19 @@ export class PerformanceEvent {
385
472
  * Report the event, if it hasn't already been reported.
386
473
  */
387
474
  reportEvent(eventNameSuffix, props, error) {
388
- var _a, _b, _c, _d;
389
475
  // There are strange sequences involving multiple Promise chains
390
476
  // where the event can be cancelled and then later a callback is invoked
391
477
  // and the caller attempts to end directly, e.g. issue #3936. Just return.
392
478
  if (!this.event) {
393
479
  return;
394
480
  }
395
- const event = Object.assign(Object.assign({}, this.event), props);
481
+ const event = { ...this.event, ...props };
396
482
  event.eventName = `${event.eventName}_${eventNameSuffix}`;
397
483
  if (eventNameSuffix !== "start") {
398
484
  event.duration = this.duration;
399
485
  if (this.startMemoryCollection) {
400
- const currentMemory = (_b = (_a = performance) === null || _a === void 0 ? void 0 : _a.memory) === null || _b === void 0 ? void 0 : _b.usedJSHeapSize;
486
+ const currentMemory = performance?.memory
487
+ ?.usedJSHeapSize;
401
488
  const differenceInKBytes = Math.floor((currentMemory - this.startMemoryCollection) / 1024);
402
489
  if (differenceInKBytes > 0) {
403
490
  event.usedJSHeapSize = differenceInKBytes;
@@ -405,61 +492,17 @@ export class PerformanceEvent {
405
492
  }
406
493
  }
407
494
  else if (this.recordHeapSize) {
408
- this.startMemoryCollection = (_d = (_c = performance) === null || _c === void 0 ? void 0 : _c.memory) === null || _d === void 0 ? void 0 : _d.usedJSHeapSize;
495
+ this.startMemoryCollection = performance?.memory?.usedJSHeapSize;
409
496
  }
410
497
  this.logger.sendPerformanceEvent(event, error);
411
498
  }
412
499
  }
413
500
  /**
414
- * Logger that is useful for UT
415
- * It can be used in places where logger instance is required, but events should be not send over.
416
- */
417
- export class TelemetryUTLogger {
418
- send(event) { }
419
- sendTelemetryEvent(event, error) { }
420
- sendErrorEvent(event, error) {
421
- this.reportError("errorEvent in UT logger!", event, error);
422
- }
423
- sendPerformanceEvent(event, error) { }
424
- logGenericError(eventName, error) {
425
- this.reportError(`genericError in UT logger!`, { eventName }, error);
426
- }
427
- logException(event, exception) {
428
- this.reportError("exception in UT logger!", event, exception);
429
- }
430
- debugAssert(condition, event) {
431
- this.reportError("debugAssert in UT logger!");
432
- }
433
- shipAssert(condition, event) {
434
- this.reportError("shipAssert in UT logger!");
435
- }
436
- reportError(message, event, err) {
437
- const error = new Error(message);
438
- error.error = error;
439
- error.event = event;
440
- // report to console as exception can be eaten
441
- console.error(message);
442
- console.error(error);
443
- throw error;
444
- }
445
- }
446
- /**
447
- * Null logger
448
- * It can be used in places where logger instance is required, but events should be not send over.
449
- */
450
- export class BaseTelemetryNullLogger {
451
- /**
452
- * Send an event with the logger
453
- *
454
- * @param event - the event to send
455
- */
456
- send(event) {
457
- return;
458
- }
459
- }
460
- /**
461
- * Null logger
462
- * It can be used in places where logger instance is required, but events should be not send over.
501
+ * Null logger that no-ops for all telemetry events passed to it.
502
+ * @deprecated - This will be removed in a future release.
503
+ * For internal use within the FluidFramework codebase, use {@link createChildLogger} with no arguments instead.
504
+ * For external consumers we recommend writing a trivial implementation of {@link @fluidframework/core-interfaces#ITelemetryBaseLogger}
505
+ * where the send() method does nothing and using that.
463
506
  */
464
507
  export class TelemetryNullLogger {
465
508
  send(event) { }
@@ -472,8 +515,7 @@ export class TelemetryNullLogger {
472
515
  * In the case of an invalid property type, the value will be converted to an error string.
473
516
  * @param event - Event with fields you want to stringify.
474
517
  */
475
- function convertToBaseEvent(_a) {
476
- var { category, eventName } = _a, props = __rest(_a, ["category", "eventName"]);
518
+ function convertToBaseEvent({ category, eventName, ...props }) {
477
519
  const newEvent = { category, eventName };
478
520
  for (const key of Object.keys(props)) {
479
521
  newEvent[key] = convertToBasePropertyType(props[key]);
@@ -483,8 +525,8 @@ function convertToBaseEvent(_a) {
483
525
  /**
484
526
  * Takes in value, and does one of 4 things.
485
527
  * if value is of primitive type - returns the original value.
486
- * If the value is an array of primitives - returns a stringified version of the array.
487
- * If the value is an object of type ITaggedTelemetryPropertyType - returns the object
528
+ * If the value is a flat array or object - returns a stringified version of the array/object.
529
+ * If the value is an object of type Tagged<TelemetryEventPropertyType> - returns the object
488
530
  * with its values recursively converted to base property Type.
489
531
  * If none of these cases are reached - returns an error string
490
532
  * @param x - value passed in to convert to a base property type
@@ -513,4 +555,27 @@ function convertToBasePropertyTypeUntagged(x) {
513
555
  return `INVALID PROPERTY (typed as ${typeof x})`;
514
556
  }
515
557
  }
558
+ export const tagData = (tag, values) =>
559
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
560
+ Object.entries(values)
561
+ .filter((e) => e[1] !== undefined)
562
+ // eslint-disable-next-line unicorn/no-array-reduce, unicorn/prefer-object-from-entries
563
+ .reduce((pv, cv) => {
564
+ const [key, value] = cv;
565
+ if (typeof value === "function") {
566
+ // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
567
+ pv[key] = () => {
568
+ return { tag, value: value() };
569
+ };
570
+ }
571
+ else {
572
+ pv[key] = { tag, value };
573
+ }
574
+ return pv;
575
+ }, {});
576
+ /**
577
+ * Helper function to tag telemetry properties as CodeArtifacts. It supports properties of type
578
+ * TelemetryBaseEventPropertyType as well as getters that return TelemetryBaseEventPropertyType.
579
+ */
580
+ export const tagCodeArtifacts = (values) => tagData(TelemetryDataTag.CodeArtifact, values);
516
581
  //# sourceMappingURL=logger.js.map