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