@fluidframework/telemetry-utils 1.4.0-121020 → 2.0.0-dev-rc.1.0.0.224419
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 +12 -13
- package/.mocharc.js +12 -0
- package/CHANGELOG.md +249 -0
- package/README.md +68 -1
- package/api-extractor-lint.json +4 -0
- package/api-extractor.json +2 -2
- package/api-report/telemetry-utils.api.md +444 -0
- package/dist/config.d.ts +47 -16
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +88 -38
- package/dist/config.js.map +1 -1
- package/dist/error.d.ts +112 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +159 -0
- package/dist/error.js.map +1 -0
- package/dist/errorLogging.d.ts +86 -20
- package/dist/errorLogging.d.ts.map +1 -1
- package/dist/errorLogging.js +190 -60
- package/dist/errorLogging.js.map +1 -1
- package/dist/eventEmitterWithErrorHandling.d.ts +9 -3
- package/dist/eventEmitterWithErrorHandling.d.ts.map +1 -1
- package/dist/eventEmitterWithErrorHandling.js +16 -3
- package/dist/eventEmitterWithErrorHandling.js.map +1 -1
- package/dist/events.d.ts +27 -3
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +26 -2
- package/dist/events.js.map +1 -1
- package/dist/fluidErrorBase.d.ts +57 -16
- package/dist/fluidErrorBase.d.ts.map +1 -1
- package/dist/fluidErrorBase.js +27 -14
- package/dist/fluidErrorBase.js.map +1 -1
- package/dist/index.d.ts +12 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +55 -21
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +267 -51
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +423 -132
- package/dist/logger.js.map +1 -1
- package/dist/mockLogger.d.ts +39 -12
- package/dist/mockLogger.d.ts.map +1 -1
- package/dist/mockLogger.js +105 -22
- package/dist/mockLogger.js.map +1 -1
- package/dist/sampledTelemetryHelper.d.ts +18 -12
- package/dist/sampledTelemetryHelper.d.ts.map +1 -1
- package/dist/sampledTelemetryHelper.js +28 -19
- package/dist/sampledTelemetryHelper.js.map +1 -1
- package/dist/telemetry-utils-alpha.d.ts +290 -0
- package/dist/telemetry-utils-beta.d.ts +264 -0
- package/dist/telemetry-utils-public.d.ts +264 -0
- package/dist/telemetry-utils-untrimmed.d.ts +1102 -0
- package/dist/telemetryTypes.d.ts +115 -0
- package/dist/telemetryTypes.d.ts.map +1 -0
- package/dist/telemetryTypes.js +7 -0
- package/dist/telemetryTypes.js.map +1 -0
- package/dist/thresholdCounter.d.ts +6 -5
- package/dist/thresholdCounter.d.ts.map +1 -1
- package/dist/thresholdCounter.js +4 -3
- package/dist/thresholdCounter.js.map +1 -1
- package/dist/tsdoc-metadata.json +11 -0
- package/dist/utils.d.ts +54 -3
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +58 -3
- package/dist/utils.js.map +1 -1
- package/lib/config.d.ts +47 -16
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +85 -36
- package/lib/config.js.map +1 -1
- package/lib/error.d.ts +112 -0
- package/lib/error.d.ts.map +1 -0
- package/lib/error.js +150 -0
- package/lib/error.js.map +1 -0
- package/lib/errorLogging.d.ts +86 -20
- package/lib/errorLogging.d.ts.map +1 -1
- package/lib/errorLogging.js +189 -60
- package/lib/errorLogging.js.map +1 -1
- package/lib/eventEmitterWithErrorHandling.d.ts +9 -3
- package/lib/eventEmitterWithErrorHandling.d.ts.map +1 -1
- package/lib/eventEmitterWithErrorHandling.js +15 -2
- package/lib/eventEmitterWithErrorHandling.js.map +1 -1
- package/lib/events.d.ts +27 -3
- package/lib/events.d.ts.map +1 -1
- package/lib/events.js +26 -2
- package/lib/events.js.map +1 -1
- package/lib/fluidErrorBase.d.ts +57 -16
- package/lib/fluidErrorBase.d.ts.map +1 -1
- package/lib/fluidErrorBase.js +27 -14
- package/lib/fluidErrorBase.js.map +1 -1
- package/lib/index.d.ts +12 -11
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +11 -11
- package/lib/index.js.map +1 -1
- package/lib/logger.d.ts +267 -51
- package/lib/logger.d.ts.map +1 -1
- package/lib/logger.js +415 -131
- package/lib/logger.js.map +1 -1
- package/lib/mockLogger.d.ts +39 -12
- package/lib/mockLogger.d.ts.map +1 -1
- package/lib/mockLogger.js +106 -23
- package/lib/mockLogger.js.map +1 -1
- package/lib/sampledTelemetryHelper.d.ts +18 -12
- package/lib/sampledTelemetryHelper.d.ts.map +1 -1
- package/lib/sampledTelemetryHelper.js +26 -17
- package/lib/sampledTelemetryHelper.js.map +1 -1
- package/lib/telemetry-utils-alpha.d.ts +290 -0
- package/lib/telemetry-utils-beta.d.ts +264 -0
- package/lib/telemetry-utils-public.d.ts +264 -0
- package/lib/telemetry-utils-untrimmed.d.ts +1102 -0
- package/lib/telemetryTypes.d.ts +115 -0
- package/lib/telemetryTypes.d.ts.map +1 -0
- package/lib/telemetryTypes.js +6 -0
- package/lib/telemetryTypes.js.map +1 -0
- package/lib/thresholdCounter.d.ts +6 -5
- package/lib/thresholdCounter.d.ts.map +1 -1
- package/lib/thresholdCounter.js +4 -3
- package/lib/thresholdCounter.js.map +1 -1
- package/lib/utils.d.ts +54 -3
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +56 -2
- package/lib/utils.js.map +1 -1
- package/package.json +86 -57
- package/prettier.config.cjs +8 -0
- package/src/config.ts +254 -189
- package/src/error.ts +235 -0
- package/src/errorLogging.ts +440 -290
- package/src/eventEmitterWithErrorHandling.ts +26 -14
- package/src/events.ts +54 -25
- package/src/fluidErrorBase.ts +94 -46
- package/src/index.ts +76 -17
- package/src/logger.ts +966 -505
- package/src/mockLogger.ts +225 -83
- package/src/sampledTelemetryHelper.ts +136 -128
- package/src/telemetryTypes.ts +140 -0
- package/src/thresholdCounter.ts +38 -37
- package/src/utils.ts +108 -17
- package/tsconfig.esnext.json +6 -6
- package/tsconfig.json +9 -13
- package/dist/debugLogger.d.ts +0 -39
- package/dist/debugLogger.d.ts.map +0 -1
- package/dist/debugLogger.js +0 -101
- package/dist/debugLogger.js.map +0 -1
- package/dist/packageVersion.d.ts +0 -9
- package/dist/packageVersion.d.ts.map +0 -1
- package/dist/packageVersion.js +0 -12
- package/dist/packageVersion.js.map +0 -1
- package/lib/debugLogger.d.ts +0 -39
- package/lib/debugLogger.d.ts.map +0 -1
- package/lib/debugLogger.js +0 -97
- package/lib/debugLogger.js.map +0 -1
- package/lib/packageVersion.d.ts +0 -9
- package/lib/packageVersion.d.ts.map +0 -1
- package/lib/packageVersion.js +0 -9
- package/lib/packageVersion.js.map +0 -1
- package/src/debugLogger.ts +0 -126
- package/src/packageVersion.ts +0 -9
package/dist/logger.js
CHANGED
|
@@ -4,52 +4,68 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.
|
|
8
|
-
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");
|
|
9
10
|
const config_1 = require("./config");
|
|
10
11
|
const errorLogging_1 = require("./errorLogging");
|
|
11
12
|
/**
|
|
12
13
|
* Broad classifications to be applied to individual properties as they're prepared to be logged to telemetry.
|
|
13
|
-
*
|
|
14
|
+
*
|
|
15
|
+
* @privateRemarks Please do not modify existing entries, to maintain backwards compatibility.
|
|
16
|
+
*
|
|
17
|
+
* @internal
|
|
14
18
|
*/
|
|
15
19
|
var TelemetryDataTag;
|
|
16
20
|
(function (TelemetryDataTag) {
|
|
17
21
|
/**
|
|
18
|
-
* Data containing terms from code packages that may have been dynamically loaded
|
|
19
|
-
* @deprecated 1.0, will be removed in next release (see issue #6603). Use `TelemetryDataTag.CodeArtifact` instead.
|
|
22
|
+
* Data containing terms or IDs from code packages that may have been dynamically loaded
|
|
20
23
|
*/
|
|
21
|
-
TelemetryDataTag["PackageData"] = "PackageData";
|
|
22
|
-
/** Data containing terms or IDs from code packages that may have been dynamically loaded */
|
|
23
24
|
TelemetryDataTag["CodeArtifact"] = "CodeArtifact";
|
|
24
|
-
/**
|
|
25
|
+
/**
|
|
26
|
+
* Personal data of a variety of classifications that pertains to the user
|
|
27
|
+
*/
|
|
25
28
|
TelemetryDataTag["UserData"] = "UserData";
|
|
26
|
-
})(TelemetryDataTag
|
|
29
|
+
})(TelemetryDataTag || (exports.TelemetryDataTag = TelemetryDataTag = {}));
|
|
30
|
+
/**
|
|
31
|
+
* Attempts to parse number from string.
|
|
32
|
+
* If it fails, it will return the original string.
|
|
33
|
+
*
|
|
34
|
+
* @remarks
|
|
35
|
+
* Used to make telemetry data typed (and support math operations, like comparison),
|
|
36
|
+
* in places where we do expect numbers (like contentsize/duration property in http header).
|
|
37
|
+
*
|
|
38
|
+
* @internal
|
|
39
|
+
*/
|
|
40
|
+
// eslint-disable-next-line @rushstack/no-new-null
|
|
41
|
+
function numberFromString(str) {
|
|
42
|
+
if (str === undefined || str === null) {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
const num = Number(str);
|
|
46
|
+
return Number.isNaN(num) ? str : num;
|
|
47
|
+
}
|
|
48
|
+
exports.numberFromString = numberFromString;
|
|
49
|
+
// TODO: add docs
|
|
50
|
+
// eslint-disable-next-line jsdoc/require-description
|
|
51
|
+
/**
|
|
52
|
+
* @internal
|
|
53
|
+
*/
|
|
54
|
+
function formatTick(tick) {
|
|
55
|
+
return Math.floor(tick);
|
|
56
|
+
}
|
|
57
|
+
exports.formatTick = formatTick;
|
|
58
|
+
/**
|
|
59
|
+
* String used to concatenate the namespace of parent loggers and their child loggers.
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
62
|
+
exports.eventNamespaceSeparator = ":";
|
|
27
63
|
/**
|
|
28
64
|
* TelemetryLogger class contains various helper telemetry methods,
|
|
29
65
|
* encoding in one place schemas for various types of Fluid telemetry events.
|
|
30
66
|
* Creates sub-logger that appends properties to all events
|
|
31
67
|
*/
|
|
32
68
|
class TelemetryLogger {
|
|
33
|
-
constructor(namespace, properties) {
|
|
34
|
-
this.namespace = namespace;
|
|
35
|
-
this.properties = properties;
|
|
36
|
-
}
|
|
37
|
-
static formatTick(tick) {
|
|
38
|
-
return Math.floor(tick);
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Attempts to parse number from string.
|
|
42
|
-
* If fails,returns original string.
|
|
43
|
-
* Used to make telemetry data typed (and support math operations, like comparison),
|
|
44
|
-
* in places where we do expect numbers (like contentsize/duration property in http header)
|
|
45
|
-
*/
|
|
46
|
-
static numberFromString(str) {
|
|
47
|
-
if (str === undefined || str === null) {
|
|
48
|
-
return undefined;
|
|
49
|
-
}
|
|
50
|
-
const num = Number(str);
|
|
51
|
-
return Number.isNaN(num) ? str : num;
|
|
52
|
-
}
|
|
53
69
|
static sanitizePkgName(name) {
|
|
54
70
|
return name.replace("@", "").replace("/", "-");
|
|
55
71
|
}
|
|
@@ -82,32 +98,38 @@ class TelemetryLogger {
|
|
|
82
98
|
event.stack = (0, errorLogging_1.generateStack)();
|
|
83
99
|
}
|
|
84
100
|
}
|
|
101
|
+
constructor(namespace, properties) {
|
|
102
|
+
this.namespace = namespace;
|
|
103
|
+
this.properties = properties;
|
|
104
|
+
}
|
|
85
105
|
/**
|
|
86
106
|
* Send a telemetry event with the logger
|
|
87
107
|
*
|
|
88
108
|
* @param event - the event to send
|
|
89
109
|
* @param error - optional error object to log
|
|
110
|
+
* @param logLevel - optional level of the log. It category of event is set as error,
|
|
111
|
+
* then the logLevel will be upgraded to be an error.
|
|
90
112
|
*/
|
|
91
|
-
sendTelemetryEvent(event, error) {
|
|
92
|
-
|
|
93
|
-
this.sendTelemetryEventCore(Object.assign(Object.assign({}, event), { category: (_a = event.category) !== null && _a !== void 0 ? _a : "generic" }), error);
|
|
113
|
+
sendTelemetryEvent(event, error, logLevel = core_interfaces_1.LogLevel.default) {
|
|
114
|
+
this.sendTelemetryEventCore({ ...event, category: event.category ?? "generic" }, error, event.category === "error" ? core_interfaces_1.LogLevel.error : logLevel);
|
|
94
115
|
}
|
|
95
116
|
/**
|
|
96
117
|
* Send a telemetry event with the logger
|
|
97
118
|
*
|
|
98
119
|
* @param event - the event to send
|
|
99
120
|
* @param error - optional error object to log
|
|
121
|
+
* @param logLevel - optional level of the log.
|
|
100
122
|
*/
|
|
101
|
-
sendTelemetryEventCore(event, error) {
|
|
102
|
-
const newEvent =
|
|
123
|
+
sendTelemetryEventCore(event, error, logLevel) {
|
|
124
|
+
const newEvent = convertToBaseEvent(event);
|
|
103
125
|
if (error !== undefined) {
|
|
104
126
|
TelemetryLogger.prepareErrorObject(newEvent, error, false);
|
|
105
127
|
}
|
|
106
128
|
// Will include Nan & Infinity, but probably we do not care
|
|
107
129
|
if (typeof newEvent.duration === "number") {
|
|
108
|
-
newEvent.duration =
|
|
130
|
+
newEvent.duration = formatTick(newEvent.duration);
|
|
109
131
|
}
|
|
110
|
-
this.send(newEvent);
|
|
132
|
+
this.send(newEvent, logLevel);
|
|
111
133
|
}
|
|
112
134
|
/**
|
|
113
135
|
* Send an error telemetry event with the logger
|
|
@@ -116,28 +138,41 @@ class TelemetryLogger {
|
|
|
116
138
|
* @param error - optional error object to log
|
|
117
139
|
*/
|
|
118
140
|
sendErrorEvent(event, error) {
|
|
119
|
-
this.sendTelemetryEventCore(
|
|
141
|
+
this.sendTelemetryEventCore({
|
|
120
142
|
// ensure the error field has some value,
|
|
121
143
|
// this can and will be overridden by event, or error
|
|
122
|
-
error: event.eventName
|
|
144
|
+
error: event.eventName,
|
|
145
|
+
...event,
|
|
146
|
+
category: "error",
|
|
147
|
+
}, error, core_interfaces_1.LogLevel.error);
|
|
123
148
|
}
|
|
124
149
|
/**
|
|
125
150
|
* Send a performance telemetry event with the logger
|
|
126
151
|
*
|
|
127
152
|
* @param event - Event to send
|
|
128
153
|
* @param error - optional error object to log
|
|
154
|
+
* @param logLevel - optional level of the log. It category of event is set as error,
|
|
155
|
+
* then the logLevel will be upgraded to be an error.
|
|
129
156
|
*/
|
|
130
|
-
sendPerformanceEvent(event, error) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
157
|
+
sendPerformanceEvent(event, error, logLevel = core_interfaces_1.LogLevel.default) {
|
|
158
|
+
const perfEvent = {
|
|
159
|
+
...event,
|
|
160
|
+
category: event.category ?? "performance",
|
|
161
|
+
};
|
|
162
|
+
this.sendTelemetryEventCore(perfEvent, error, perfEvent.category === "error" ? core_interfaces_1.LogLevel.error : logLevel);
|
|
134
163
|
}
|
|
135
164
|
prepareEvent(event) {
|
|
136
165
|
const includeErrorProps = event.category === "error" || event.error !== undefined;
|
|
137
|
-
const newEvent =
|
|
166
|
+
const newEvent = {
|
|
167
|
+
...event,
|
|
168
|
+
};
|
|
138
169
|
if (this.namespace !== undefined) {
|
|
139
170
|
newEvent.eventName = `${this.namespace}${TelemetryLogger.eventNamespaceSeparator}${newEvent.eventName}`;
|
|
140
171
|
}
|
|
172
|
+
return this.extendProperties(newEvent, includeErrorProps);
|
|
173
|
+
}
|
|
174
|
+
extendProperties(toExtend, includeErrorProps) {
|
|
175
|
+
const eventLike = toExtend;
|
|
141
176
|
if (this.properties) {
|
|
142
177
|
const properties = [];
|
|
143
178
|
properties.push(this.properties.all);
|
|
@@ -147,33 +182,41 @@ class TelemetryLogger {
|
|
|
147
182
|
for (const props of properties) {
|
|
148
183
|
if (props !== undefined) {
|
|
149
184
|
for (const key of Object.keys(props)) {
|
|
150
|
-
if (
|
|
185
|
+
if (eventLike[key] !== undefined) {
|
|
151
186
|
continue;
|
|
152
187
|
}
|
|
153
188
|
const getterOrValue = props[key];
|
|
154
189
|
// If this throws, hopefully it is handled elsewhere
|
|
155
190
|
const value = typeof getterOrValue === "function" ? getterOrValue() : getterOrValue;
|
|
156
191
|
if (value !== undefined) {
|
|
157
|
-
|
|
192
|
+
eventLike[key] = value;
|
|
158
193
|
}
|
|
159
194
|
}
|
|
160
195
|
}
|
|
161
196
|
}
|
|
162
197
|
}
|
|
163
|
-
return
|
|
198
|
+
return toExtend;
|
|
164
199
|
}
|
|
165
200
|
}
|
|
166
201
|
exports.TelemetryLogger = TelemetryLogger;
|
|
167
|
-
|
|
202
|
+
/**
|
|
203
|
+
* {@inheritDoc eventNamespaceSeparator}
|
|
204
|
+
*/
|
|
205
|
+
TelemetryLogger.eventNamespaceSeparator = exports.eventNamespaceSeparator;
|
|
168
206
|
/**
|
|
169
207
|
* @deprecated 0.56, remove TaggedLoggerAdapter once its usage is removed from
|
|
170
208
|
* container-runtime. Issue: #8191
|
|
171
209
|
* TaggedLoggerAdapter class can add tag handling to your logger.
|
|
210
|
+
*
|
|
211
|
+
* @internal
|
|
172
212
|
*/
|
|
173
213
|
class TaggedLoggerAdapter {
|
|
174
214
|
constructor(logger) {
|
|
175
215
|
this.logger = logger;
|
|
176
216
|
}
|
|
217
|
+
/**
|
|
218
|
+
* {@inheritDoc @fluidframework/core-interfaces#ITelemetryBaseLogger.send}
|
|
219
|
+
*/
|
|
177
220
|
send(eventWithTagsMaybe) {
|
|
178
221
|
const newEvent = {
|
|
179
222
|
category: eventWithTagsMaybe.category,
|
|
@@ -181,56 +224,66 @@ class TaggedLoggerAdapter {
|
|
|
181
224
|
};
|
|
182
225
|
for (const key of Object.keys(eventWithTagsMaybe)) {
|
|
183
226
|
const taggableProp = eventWithTagsMaybe[key];
|
|
184
|
-
const { value, tag } =
|
|
227
|
+
const { value, tag } = typeof taggableProp === "object"
|
|
185
228
|
? taggableProp
|
|
186
229
|
: { value: taggableProp, tag: undefined };
|
|
187
230
|
switch (tag) {
|
|
188
|
-
case undefined:
|
|
231
|
+
case undefined: {
|
|
189
232
|
// No tag means we can log plainly
|
|
190
233
|
newEvent[key] = value;
|
|
191
234
|
break;
|
|
192
|
-
|
|
193
|
-
|
|
235
|
+
}
|
|
236
|
+
case "PackageData": // For back-compat
|
|
237
|
+
case TelemetryDataTag.CodeArtifact: {
|
|
238
|
+
// For Microsoft applications, CodeArtifact is safe for now
|
|
194
239
|
// (we don't load 3P code in 1P apps)
|
|
195
240
|
newEvent[key] = value;
|
|
196
241
|
break;
|
|
197
|
-
|
|
198
|
-
|
|
242
|
+
}
|
|
243
|
+
case TelemetryDataTag.UserData: {
|
|
244
|
+
// Strip out anything tagged explicitly as UserData.
|
|
199
245
|
// Alternate strategy would be to hash these props
|
|
200
246
|
newEvent[key] = "REDACTED (UserData)";
|
|
201
247
|
break;
|
|
202
|
-
|
|
248
|
+
}
|
|
249
|
+
default: {
|
|
203
250
|
// If we encounter a tag we don't recognize
|
|
204
251
|
// then we must assume we should scrub.
|
|
205
252
|
newEvent[key] = "REDACTED (unknown tag)";
|
|
206
253
|
break;
|
|
254
|
+
}
|
|
207
255
|
}
|
|
208
256
|
}
|
|
209
257
|
this.logger.send(newEvent);
|
|
210
258
|
}
|
|
211
259
|
}
|
|
212
260
|
exports.TaggedLoggerAdapter = TaggedLoggerAdapter;
|
|
261
|
+
/**
|
|
262
|
+
* Create a child logger based on the provided props object.
|
|
263
|
+
*
|
|
264
|
+
* @remarks
|
|
265
|
+
* Passing in no props object (i.e. undefined) will return a logger that is effectively a no-op.
|
|
266
|
+
*
|
|
267
|
+
* @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.
|
|
268
|
+
*
|
|
269
|
+
* @alpha
|
|
270
|
+
*/
|
|
271
|
+
function createChildLogger(props) {
|
|
272
|
+
return ChildLogger.create(props?.logger, props?.namespace, props?.properties);
|
|
273
|
+
}
|
|
274
|
+
exports.createChildLogger = createChildLogger;
|
|
213
275
|
/**
|
|
214
276
|
* ChildLogger class contains various helper telemetry methods,
|
|
215
277
|
* encoding in one place schemas for various types of Fluid telemetry events.
|
|
216
|
-
* Creates sub-logger that appends properties to all events
|
|
278
|
+
* Creates sub-logger that appends properties to all events.
|
|
217
279
|
*/
|
|
218
280
|
class ChildLogger extends TelemetryLogger {
|
|
219
|
-
constructor(baseLogger, namespace, properties) {
|
|
220
|
-
super(namespace, properties);
|
|
221
|
-
this.baseLogger = baseLogger;
|
|
222
|
-
// propagate the monitoring context
|
|
223
|
-
if ((0, config_1.loggerIsMonitoringContext)(baseLogger)) {
|
|
224
|
-
(0, config_1.mixinMonitoringContext)(this, new config_1.CachedConfigProvider(baseLogger.config));
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
281
|
/**
|
|
228
282
|
* Create child logger
|
|
229
283
|
* @param baseLogger - Base logger to use to output events. If undefined, proper child logger
|
|
230
|
-
* is created, but it does not
|
|
284
|
+
* is created, but it does not send telemetry events anywhere.
|
|
231
285
|
* @param namespace - Telemetry event name prefix to add to all events
|
|
232
286
|
* @param properties - Base properties to add to all events
|
|
233
|
-
* @param propertyGetters - Getters to add additional properties to all events
|
|
234
287
|
*/
|
|
235
288
|
static create(baseLogger, namespace, properties) {
|
|
236
289
|
// if we are creating a child of a child, rather than nest, which will increase
|
|
@@ -240,10 +293,16 @@ class ChildLogger extends TelemetryLogger {
|
|
|
240
293
|
for (const extendedProps of [baseLogger.properties, properties]) {
|
|
241
294
|
if (extendedProps !== undefined) {
|
|
242
295
|
if (extendedProps.all !== undefined) {
|
|
243
|
-
combinedProperties.all =
|
|
296
|
+
combinedProperties.all = {
|
|
297
|
+
...combinedProperties.all,
|
|
298
|
+
...extendedProps.all,
|
|
299
|
+
};
|
|
244
300
|
}
|
|
245
301
|
if (extendedProps.error !== undefined) {
|
|
246
|
-
combinedProperties.error =
|
|
302
|
+
combinedProperties.error = {
|
|
303
|
+
...combinedProperties.error,
|
|
304
|
+
...extendedProps.error,
|
|
305
|
+
};
|
|
247
306
|
}
|
|
248
307
|
}
|
|
249
308
|
}
|
|
@@ -252,35 +311,97 @@ class ChildLogger extends TelemetryLogger {
|
|
|
252
311
|
: namespace === undefined
|
|
253
312
|
? baseLogger.namespace
|
|
254
313
|
: `${baseLogger.namespace}${TelemetryLogger.eventNamespaceSeparator}${namespace}`;
|
|
255
|
-
|
|
314
|
+
const child = new ChildLogger(baseLogger.baseLogger, combinedNamespace, combinedProperties);
|
|
315
|
+
if (!(0, config_1.loggerIsMonitoringContext)(child) && (0, config_1.loggerIsMonitoringContext)(baseLogger)) {
|
|
316
|
+
(0, config_1.mixinMonitoringContext)(child, baseLogger.config);
|
|
317
|
+
}
|
|
318
|
+
return child;
|
|
256
319
|
}
|
|
257
|
-
return new ChildLogger(baseLogger
|
|
320
|
+
return new ChildLogger(baseLogger ?? { send() { } }, namespace, properties);
|
|
321
|
+
}
|
|
322
|
+
constructor(baseLogger, namespace, properties) {
|
|
323
|
+
super(namespace, properties);
|
|
324
|
+
this.baseLogger = baseLogger;
|
|
325
|
+
// propagate the monitoring context
|
|
326
|
+
if ((0, config_1.loggerIsMonitoringContext)(baseLogger)) {
|
|
327
|
+
(0, config_1.mixinMonitoringContext)(this, new config_1.CachedConfigProvider(this, baseLogger.config));
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
get minLogLevel() {
|
|
331
|
+
return this.baseLogger.minLogLevel;
|
|
332
|
+
}
|
|
333
|
+
shouldFilterOutEvent(event, logLevel) {
|
|
334
|
+
const eventLogLevel = logLevel ?? core_interfaces_1.LogLevel.default;
|
|
335
|
+
const configLogLevel = this.baseLogger.minLogLevel ?? core_interfaces_1.LogLevel.default;
|
|
336
|
+
// Filter out in case event log level is below what is wanted in config.
|
|
337
|
+
return eventLogLevel < configLogLevel;
|
|
258
338
|
}
|
|
259
339
|
/**
|
|
260
340
|
* Send an event with the logger
|
|
261
341
|
*
|
|
262
342
|
* @param event - the event to send
|
|
263
343
|
*/
|
|
264
|
-
send(event) {
|
|
265
|
-
|
|
344
|
+
send(event, logLevel) {
|
|
345
|
+
if (this.shouldFilterOutEvent(event, logLevel)) {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
this.baseLogger.send(this.prepareEvent(event), logLevel);
|
|
266
349
|
}
|
|
267
350
|
}
|
|
268
351
|
exports.ChildLogger = ChildLogger;
|
|
352
|
+
/**
|
|
353
|
+
* Create a logger which logs to multiple other loggers based on the provided props object.
|
|
354
|
+
*
|
|
355
|
+
* @internal
|
|
356
|
+
*/
|
|
357
|
+
function createMultiSinkLogger(props) {
|
|
358
|
+
return new MultiSinkLogger(props.namespace, props.properties, props.loggers?.filter((l) => l !== undefined), props.tryInheritProperties);
|
|
359
|
+
}
|
|
360
|
+
exports.createMultiSinkLogger = createMultiSinkLogger;
|
|
269
361
|
/**
|
|
270
362
|
* Multi-sink logger
|
|
271
363
|
* Takes multiple ITelemetryBaseLogger objects (sinks) and logs all events into each sink
|
|
272
|
-
* Implements ITelemetryBaseLogger (through static create() method)
|
|
273
364
|
*/
|
|
274
365
|
class MultiSinkLogger extends TelemetryLogger {
|
|
275
366
|
/**
|
|
276
367
|
* Create multiple sink logger (i.e. logger that sends events to multiple sinks)
|
|
277
368
|
* @param namespace - Telemetry event name prefix to add to all events
|
|
278
369
|
* @param properties - Base properties to add to all events
|
|
279
|
-
* @param
|
|
370
|
+
* @param loggers - The list of loggers to use as sinks
|
|
371
|
+
* @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
|
|
280
372
|
*/
|
|
281
|
-
constructor(namespace, properties) {
|
|
282
|
-
|
|
283
|
-
|
|
373
|
+
constructor(namespace, properties, loggers = [], tryInheritProperties) {
|
|
374
|
+
let realProperties = properties === undefined ? undefined : { ...properties };
|
|
375
|
+
if (tryInheritProperties === true) {
|
|
376
|
+
const merge = (realProperties ?? (realProperties = {}));
|
|
377
|
+
loggers
|
|
378
|
+
.filter((l) => l instanceof TelemetryLogger)
|
|
379
|
+
.map((l) => l.properties ?? {})
|
|
380
|
+
// eslint-disable-next-line unicorn/no-array-for-each
|
|
381
|
+
.forEach((cv) => {
|
|
382
|
+
// eslint-disable-next-line unicorn/no-array-for-each
|
|
383
|
+
Object.keys(cv).forEach((k) => {
|
|
384
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
385
|
+
merge[k] = { ...cv[k], ...merge?.[k] };
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
super(namespace, realProperties);
|
|
390
|
+
this.loggers = loggers;
|
|
391
|
+
this._minLogLevelOfAllLoggers = core_interfaces_1.LogLevel.default;
|
|
392
|
+
this.calculateMinLogLevel();
|
|
393
|
+
}
|
|
394
|
+
get minLogLevel() {
|
|
395
|
+
return this._minLogLevelOfAllLoggers;
|
|
396
|
+
}
|
|
397
|
+
calculateMinLogLevel() {
|
|
398
|
+
if (this.loggers.length > 0) {
|
|
399
|
+
const logLevels = [];
|
|
400
|
+
for (const logger of this.loggers) {
|
|
401
|
+
logLevels.push(logger.minLogLevel ?? core_interfaces_1.LogLevel.default);
|
|
402
|
+
}
|
|
403
|
+
this._minLogLevelOfAllLoggers = Math.min(...logLevels);
|
|
404
|
+
}
|
|
284
405
|
}
|
|
285
406
|
/**
|
|
286
407
|
* Add logger to send all events to
|
|
@@ -289,6 +410,8 @@ class MultiSinkLogger extends TelemetryLogger {
|
|
|
289
410
|
addLogger(logger) {
|
|
290
411
|
if (logger !== undefined && logger !== null) {
|
|
291
412
|
this.loggers.push(logger);
|
|
413
|
+
// Update in case the logLevel of added logger is less than the current.
|
|
414
|
+
this.calculateMinLogLevel();
|
|
292
415
|
}
|
|
293
416
|
}
|
|
294
417
|
/**
|
|
@@ -298,34 +421,49 @@ class MultiSinkLogger extends TelemetryLogger {
|
|
|
298
421
|
*/
|
|
299
422
|
send(event) {
|
|
300
423
|
const newEvent = this.prepareEvent(event);
|
|
301
|
-
this.loggers
|
|
424
|
+
for (const logger of this.loggers) {
|
|
302
425
|
logger.send(newEvent);
|
|
303
|
-
}
|
|
426
|
+
}
|
|
304
427
|
}
|
|
305
428
|
}
|
|
306
429
|
exports.MultiSinkLogger = MultiSinkLogger;
|
|
307
430
|
/**
|
|
308
|
-
* Helper class to log performance events
|
|
431
|
+
* Helper class to log performance events.
|
|
432
|
+
*
|
|
433
|
+
* @internal
|
|
309
434
|
*/
|
|
310
435
|
class PerformanceEvent {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
}
|
|
324
|
-
static start(logger, event, markers) {
|
|
325
|
-
return new PerformanceEvent(logger, event, markers);
|
|
436
|
+
/**
|
|
437
|
+
* Creates an instance of {@link PerformanceEvent} and starts measurements
|
|
438
|
+
* @param logger - the logger to be used for publishing events
|
|
439
|
+
* @param event - the logging event details which will be published with the performance measurements
|
|
440
|
+
* @param markers - See {@link IPerformanceEventMarkers}
|
|
441
|
+
* @param recordHeapSize - whether or not to also record memory performance
|
|
442
|
+
* @param emitLogs - should this instance emit logs. If set to false, logs will not be emitted to the logger,
|
|
443
|
+
* but measurements will still be performed and any specified markers will be generated.
|
|
444
|
+
* @returns An instance of {@link PerformanceEvent}
|
|
445
|
+
*/
|
|
446
|
+
static start(logger, event, markers, recordHeapSize = false, emitLogs = true) {
|
|
447
|
+
return new PerformanceEvent(logger, event, markers, recordHeapSize, emitLogs);
|
|
326
448
|
}
|
|
327
|
-
|
|
328
|
-
|
|
449
|
+
/**
|
|
450
|
+
* Measure a synchronous task
|
|
451
|
+
* @param logger - the logger to be used for publishing events
|
|
452
|
+
* @param event - the logging event details which will be published with the performance measurements
|
|
453
|
+
* @param callback - the task to be executed and measured
|
|
454
|
+
* @param markers - See {@link IPerformanceEventMarkers}
|
|
455
|
+
* @param sampleThreshold - events with the same name and category will be sent to the logger
|
|
456
|
+
* only when we hit this many executions of the task. If unspecified, all events will be sent.
|
|
457
|
+
* @returns The results of the executed task
|
|
458
|
+
*
|
|
459
|
+
* @remarks Note that if the "same" event (category + eventName) would be emitted by different
|
|
460
|
+
* tasks (`callback`), `sampleThreshold` is still applied only based on the event's category + eventName,
|
|
461
|
+
* so executing either of the tasks will increase the internal counter and they
|
|
462
|
+
* effectively "share" the sampling rate for the event.
|
|
463
|
+
*/
|
|
464
|
+
static timedExec(logger, event, callback, markers, sampleThreshold = 1) {
|
|
465
|
+
const perfEvent = PerformanceEvent.start(logger, event, markers, undefined, // recordHeapSize
|
|
466
|
+
PerformanceEvent.shouldReport(event, sampleThreshold));
|
|
329
467
|
try {
|
|
330
468
|
const ret = callback(perfEvent);
|
|
331
469
|
perfEvent.autoEnd();
|
|
@@ -336,8 +474,24 @@ class PerformanceEvent {
|
|
|
336
474
|
throw error;
|
|
337
475
|
}
|
|
338
476
|
}
|
|
339
|
-
|
|
340
|
-
|
|
477
|
+
/**
|
|
478
|
+
* Measure an asynchronous task
|
|
479
|
+
* @param logger - the logger to be used for publishing events
|
|
480
|
+
* @param event - the logging event details which will be published with the performance measurements
|
|
481
|
+
* @param callback - the task to be executed and measured
|
|
482
|
+
* @param markers - See {@link IPerformanceEventMarkers}
|
|
483
|
+
* @param recordHeapSize - whether or not to also record memory performance
|
|
484
|
+
* @param sampleThreshold - events with the same name and category will be sent to the logger
|
|
485
|
+
* only when we hit this many executions of the task. If unspecified, all events will be sent.
|
|
486
|
+
* @returns The results of the executed task
|
|
487
|
+
*
|
|
488
|
+
* @remarks Note that if the "same" event (category + eventName) would be emitted by different
|
|
489
|
+
* tasks (`callback`), `sampleThreshold` is still applied only based on the event's category + eventName,
|
|
490
|
+
* so executing either of the tasks will increase the internal counter and they
|
|
491
|
+
* effectively "share" the sampling rate for the event.
|
|
492
|
+
*/
|
|
493
|
+
static async timedExecAsync(logger, event, callback, markers, recordHeapSize, sampleThreshold = 1) {
|
|
494
|
+
const perfEvent = PerformanceEvent.start(logger, event, markers, recordHeapSize, PerformanceEvent.shouldReport(event, sampleThreshold));
|
|
341
495
|
try {
|
|
342
496
|
const ret = await callback(perfEvent);
|
|
343
497
|
perfEvent.autoEnd();
|
|
@@ -348,7 +502,25 @@ class PerformanceEvent {
|
|
|
348
502
|
throw error;
|
|
349
503
|
}
|
|
350
504
|
}
|
|
351
|
-
get duration() {
|
|
505
|
+
get duration() {
|
|
506
|
+
return client_utils_1.performance.now() - this.startTime;
|
|
507
|
+
}
|
|
508
|
+
constructor(logger, event, markers = { end: true, cancel: "generic" }, recordHeapSize = false, emitLogs = true) {
|
|
509
|
+
this.logger = logger;
|
|
510
|
+
this.markers = markers;
|
|
511
|
+
this.recordHeapSize = recordHeapSize;
|
|
512
|
+
this.emitLogs = emitLogs;
|
|
513
|
+
this.startTime = client_utils_1.performance.now();
|
|
514
|
+
this.startMemoryCollection = 0;
|
|
515
|
+
this.event = { ...event };
|
|
516
|
+
if (this.markers.start) {
|
|
517
|
+
this.reportEvent("start");
|
|
518
|
+
}
|
|
519
|
+
if (typeof window === "object" && window?.performance?.mark) {
|
|
520
|
+
this.startMark = `${event.eventName}-start`;
|
|
521
|
+
window.performance.mark(this.startMark);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
352
524
|
reportProgress(props, eventNameSuffix = "update") {
|
|
353
525
|
this.reportEvent(eventNameSuffix, props);
|
|
354
526
|
}
|
|
@@ -375,7 +547,7 @@ class PerformanceEvent {
|
|
|
375
547
|
}
|
|
376
548
|
cancel(props, error) {
|
|
377
549
|
if (this.markers.cancel !== undefined) {
|
|
378
|
-
this.reportEvent("cancel",
|
|
550
|
+
this.reportEvent("cancel", { category: this.markers.cancel, ...props }, error);
|
|
379
551
|
}
|
|
380
552
|
this.event = undefined;
|
|
381
553
|
}
|
|
@@ -389,50 +561,169 @@ class PerformanceEvent {
|
|
|
389
561
|
if (!this.event) {
|
|
390
562
|
return;
|
|
391
563
|
}
|
|
392
|
-
|
|
564
|
+
if (!this.emitLogs) {
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
const event = { ...this.event, ...props };
|
|
393
568
|
event.eventName = `${event.eventName}_${eventNameSuffix}`;
|
|
394
569
|
if (eventNameSuffix !== "start") {
|
|
395
570
|
event.duration = this.duration;
|
|
571
|
+
if (this.startMemoryCollection) {
|
|
572
|
+
const currentMemory = client_utils_1.performance?.memory
|
|
573
|
+
?.usedJSHeapSize;
|
|
574
|
+
const differenceInKBytes = Math.floor((currentMemory - this.startMemoryCollection) / 1024);
|
|
575
|
+
if (differenceInKBytes > 0) {
|
|
576
|
+
event.usedJSHeapSize = differenceInKBytes;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
else if (this.recordHeapSize) {
|
|
581
|
+
this.startMemoryCollection = client_utils_1.performance?.memory
|
|
582
|
+
?.usedJSHeapSize;
|
|
396
583
|
}
|
|
397
584
|
this.logger.sendPerformanceEvent(event, error);
|
|
398
585
|
}
|
|
586
|
+
static shouldReport(event, sampleThreshold) {
|
|
587
|
+
const eventKey = `.${event.category}.${event.eventName}`;
|
|
588
|
+
const hitCount = PerformanceEvent.eventHits.get(eventKey) ?? 0;
|
|
589
|
+
PerformanceEvent.eventHits.set(eventKey, hitCount >= sampleThreshold ? 1 : hitCount + 1);
|
|
590
|
+
return hitCount % sampleThreshold === 0;
|
|
591
|
+
}
|
|
399
592
|
}
|
|
400
593
|
exports.PerformanceEvent = PerformanceEvent;
|
|
594
|
+
PerformanceEvent.eventHits = new Map();
|
|
401
595
|
/**
|
|
402
|
-
*
|
|
403
|
-
*
|
|
596
|
+
* Null logger that no-ops for all telemetry events passed to it.
|
|
597
|
+
*
|
|
598
|
+
* @deprecated This will be removed in a future release.
|
|
599
|
+
* For internal use within the FluidFramework codebase, use {@link createChildLogger} with no arguments instead.
|
|
600
|
+
* For external consumers we recommend writing a trivial implementation of {@link @fluidframework/core-interfaces#ITelemetryBaseLogger}
|
|
601
|
+
* where the send() method does nothing and using that.
|
|
602
|
+
*
|
|
603
|
+
* @internal
|
|
404
604
|
*/
|
|
405
|
-
class
|
|
406
|
-
send(event) {
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
605
|
+
class TelemetryNullLogger {
|
|
606
|
+
send(event) { }
|
|
607
|
+
sendTelemetryEvent(event, error) { }
|
|
608
|
+
sendErrorEvent(event, error) { }
|
|
609
|
+
sendPerformanceEvent(event, error) { }
|
|
610
|
+
}
|
|
611
|
+
exports.TelemetryNullLogger = TelemetryNullLogger;
|
|
612
|
+
/**
|
|
613
|
+
* Takes in an event object, and converts all of its values to a basePropertyType.
|
|
614
|
+
* In the case of an invalid property type, the value will be converted to an error string.
|
|
615
|
+
* @param event - Event with fields you want to stringify.
|
|
616
|
+
*/
|
|
617
|
+
function convertToBaseEvent({ category, eventName, ...props }) {
|
|
618
|
+
const newEvent = { category, eventName };
|
|
619
|
+
for (const key of Object.keys(props)) {
|
|
620
|
+
newEvent[key] = convertToBasePropertyType(props[key]);
|
|
420
621
|
}
|
|
421
|
-
|
|
422
|
-
|
|
622
|
+
return newEvent;
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* Takes in value, and does one of 4 things.
|
|
626
|
+
* if value is of primitive type - returns the original value.
|
|
627
|
+
* If the value is a flat array or object - returns a stringified version of the array/object.
|
|
628
|
+
* If the value is an object of type Tagged<TelemetryEventPropertyType> - returns the object
|
|
629
|
+
* with its values recursively converted to base property Type.
|
|
630
|
+
* If none of these cases are reached - returns an error string
|
|
631
|
+
* @param x - value passed in to convert to a base property type
|
|
632
|
+
*/
|
|
633
|
+
function convertToBasePropertyType(x) {
|
|
634
|
+
return (0, errorLogging_1.isTaggedTelemetryPropertyValue)(x)
|
|
635
|
+
? {
|
|
636
|
+
value: convertToBasePropertyTypeUntagged(x.value),
|
|
637
|
+
tag: x.tag,
|
|
638
|
+
}
|
|
639
|
+
: convertToBasePropertyTypeUntagged(x);
|
|
640
|
+
}
|
|
641
|
+
exports.convertToBasePropertyType = convertToBasePropertyType;
|
|
642
|
+
function convertToBasePropertyTypeUntagged(x) {
|
|
643
|
+
switch (typeof x) {
|
|
644
|
+
case "string":
|
|
645
|
+
case "number":
|
|
646
|
+
case "boolean":
|
|
647
|
+
case "undefined": {
|
|
648
|
+
return x;
|
|
649
|
+
}
|
|
650
|
+
case "object": {
|
|
651
|
+
// We assume this is an array or flat object based on the input types
|
|
652
|
+
return JSON.stringify(x);
|
|
653
|
+
}
|
|
654
|
+
default: {
|
|
655
|
+
// should never reach this case based on the input types
|
|
656
|
+
console.error(`convertToBasePropertyTypeUntagged: INVALID PROPERTY (typed as ${typeof x})`);
|
|
657
|
+
return `INVALID PROPERTY (typed as ${typeof x})`;
|
|
658
|
+
}
|
|
423
659
|
}
|
|
424
|
-
|
|
425
|
-
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* Tags all given `values` with the same `tag`.
|
|
663
|
+
*
|
|
664
|
+
* @param tag - The tag with which all `values` will be annotated.
|
|
665
|
+
* @param values - The values to be tagged.
|
|
666
|
+
*
|
|
667
|
+
* @remarks
|
|
668
|
+
* It supports properties of type {@link @fluidframework/core-interfaces#TelemetryBaseEventPropertyType},
|
|
669
|
+
* as well as callbacks that return that type.
|
|
670
|
+
*
|
|
671
|
+
* @example Sample usage
|
|
672
|
+
* ```typescript
|
|
673
|
+
* {
|
|
674
|
+
* // ...Other properties being added to a telemetry event
|
|
675
|
+
* ...tagData("someTag", {foo: 1, bar: 2}),
|
|
676
|
+
* // ...
|
|
677
|
+
* }
|
|
678
|
+
* ```
|
|
679
|
+
* This will result in `foo` and `bar` added to the event with their values tagged.
|
|
680
|
+
*
|
|
681
|
+
* @internal
|
|
682
|
+
*/
|
|
683
|
+
const tagData = (tag, values) =>
|
|
684
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
685
|
+
Object.entries(values)
|
|
686
|
+
.filter((e) => e[1] !== undefined)
|
|
687
|
+
// eslint-disable-next-line unicorn/no-array-reduce, unicorn/prefer-object-from-entries
|
|
688
|
+
.reduce((pv, cv) => {
|
|
689
|
+
const [key, value] = cv;
|
|
690
|
+
// The ternary form is less legible in this case.
|
|
691
|
+
// eslint-disable-next-line unicorn/prefer-ternary
|
|
692
|
+
if (typeof value === "function") {
|
|
693
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
694
|
+
pv[key] = () => {
|
|
695
|
+
return { tag, value: value() };
|
|
696
|
+
};
|
|
426
697
|
}
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
error.error = error;
|
|
430
|
-
error.event = event;
|
|
431
|
-
// report to console as exception can be eaten
|
|
432
|
-
console.error(message);
|
|
433
|
-
console.error(error);
|
|
434
|
-
throw error;
|
|
698
|
+
else {
|
|
699
|
+
pv[key] = { tag, value };
|
|
435
700
|
}
|
|
436
|
-
|
|
437
|
-
|
|
701
|
+
return pv;
|
|
702
|
+
}, {});
|
|
703
|
+
exports.tagData = tagData;
|
|
704
|
+
/**
|
|
705
|
+
* Tags all provided `values` as {@link TelemetryDataTag.CodeArtifact}.
|
|
706
|
+
*
|
|
707
|
+
* @param values - The values to be tagged.
|
|
708
|
+
*
|
|
709
|
+
* @remarks
|
|
710
|
+
* It supports properties of type {@link @fluidframework/core-interfaces#TelemetryBaseEventPropertyType},
|
|
711
|
+
* as well as callbacks that return that type.
|
|
712
|
+
*
|
|
713
|
+
* @example Sample usage
|
|
714
|
+
* ```typescript
|
|
715
|
+
* {
|
|
716
|
+
* // ...Other properties being added to a telemetry event
|
|
717
|
+
* ...tagCodeArtifacts("someTag", {foo: 1, bar: 2}),
|
|
718
|
+
* // ...
|
|
719
|
+
* }
|
|
720
|
+
* ```
|
|
721
|
+
* This will result in `foo` and `bar` added to the event with their values tagged as {@link TelemetryDataTag.CodeArtifact}.
|
|
722
|
+
*
|
|
723
|
+
* @see {@link tagData}
|
|
724
|
+
*
|
|
725
|
+
* @internal
|
|
726
|
+
*/
|
|
727
|
+
const tagCodeArtifacts = (values) => (0, exports.tagData)(TelemetryDataTag.CodeArtifact, values);
|
|
728
|
+
exports.tagCodeArtifacts = tagCodeArtifacts;
|
|
438
729
|
//# sourceMappingURL=logger.js.map
|