@fluidframework/telemetry-utils 2.0.0-internal.6.1.1 → 2.0.0-internal.6.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +2 -1
- package/CHANGELOG.md +59 -0
- package/README.md +4 -3
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +9 -4
- 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 +34 -18
- package/dist/errorLogging.d.ts.map +1 -1
- package/dist/errorLogging.js +42 -17
- 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 +18 -11
- package/dist/fluidErrorBase.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +38 -22
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +68 -21
- package/dist/logger.js.map +1 -1
- package/dist/mockLogger.d.ts +17 -6
- package/dist/mockLogger.d.ts.map +1 -1
- package/dist/mockLogger.js +22 -9
- 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 +13 -11
- 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 +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js.map +1 -1
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +9 -4
- 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 +34 -18
- package/lib/errorLogging.d.ts.map +1 -1
- package/lib/errorLogging.js +42 -17
- 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 +18 -11
- package/lib/fluidErrorBase.js.map +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/logger.d.ts +38 -22
- package/lib/logger.d.ts.map +1 -1
- package/lib/logger.js +64 -17
- package/lib/logger.js.map +1 -1
- package/lib/mockLogger.d.ts +17 -6
- package/lib/mockLogger.d.ts.map +1 -1
- package/lib/mockLogger.js +22 -9
- 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 +11 -9
- 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 +1 -1
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js.map +1 -1
- package/package.json +15 -18
- package/src/config.ts +12 -7
- package/src/error.ts +202 -0
- package/src/errorLogging.ts +90 -52
- package/src/eventEmitterWithErrorHandling.ts +5 -3
- package/src/events.ts +3 -3
- package/src/fluidErrorBase.ts +62 -26
- package/src/index.ts +8 -0
- package/src/logger.ts +143 -45
- package/src/mockLogger.ts +33 -16
- package/src/sampledTelemetryHelper.ts +18 -14
- package/src/telemetryTypes.ts +29 -6
- package/src/thresholdCounter.ts +2 -2
- package/src/utils.ts +1 -1
package/src/mockLogger.ts
CHANGED
|
@@ -3,9 +3,13 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
import {
|
|
7
|
+
ITelemetryBaseEvent,
|
|
8
|
+
ITelemetryBaseLogger,
|
|
9
|
+
LogLevel,
|
|
10
|
+
} from "@fluidframework/core-interfaces";
|
|
11
|
+
import { assert } from "@fluidframework/core-utils";
|
|
12
|
+
import { ITelemetryLoggerExt, ITelemetryPropertiesExt } from "./telemetryTypes";
|
|
9
13
|
import { createChildLogger } from "./logger";
|
|
10
14
|
|
|
11
15
|
/**
|
|
@@ -15,11 +19,13 @@ import { createChildLogger } from "./logger";
|
|
|
15
19
|
export class MockLogger implements ITelemetryBaseLogger {
|
|
16
20
|
events: ITelemetryBaseEvent[] = [];
|
|
17
21
|
|
|
18
|
-
|
|
22
|
+
constructor(public readonly minLogLevel?: LogLevel) {}
|
|
23
|
+
|
|
24
|
+
clear(): void {
|
|
19
25
|
this.events = [];
|
|
20
26
|
}
|
|
21
27
|
|
|
22
|
-
toTelemetryLogger() {
|
|
28
|
+
toTelemetryLogger(): ITelemetryLoggerExt {
|
|
23
29
|
return createChildLogger({ logger: this });
|
|
24
30
|
}
|
|
25
31
|
|
|
@@ -48,12 +54,14 @@ export class MockLogger implements ITelemetryBaseLogger {
|
|
|
48
54
|
return unmatchedExpectedEventCount === 0;
|
|
49
55
|
}
|
|
50
56
|
|
|
51
|
-
/**
|
|
57
|
+
/**
|
|
58
|
+
* Asserts that matchEvents is true, and prints the actual/expected output if not.
|
|
59
|
+
*/
|
|
52
60
|
assertMatch(
|
|
53
61
|
expectedEvents: Omit<ITelemetryBaseEvent, "category">[],
|
|
54
62
|
message?: string,
|
|
55
63
|
inlineDetailsProp: boolean = false,
|
|
56
|
-
) {
|
|
64
|
+
): void {
|
|
57
65
|
const actualEvents = this.events;
|
|
58
66
|
if (!this.matchEvents(expectedEvents, inlineDetailsProp)) {
|
|
59
67
|
throw new Error(`${message}
|
|
@@ -85,12 +93,14 @@ ${JSON.stringify(actualEvents)}`);
|
|
|
85
93
|
return matchedExpectedEventCount > 0;
|
|
86
94
|
}
|
|
87
95
|
|
|
88
|
-
/**
|
|
96
|
+
/**
|
|
97
|
+
* Asserts that matchAnyEvent is true, and prints the actual/expected output if not.
|
|
98
|
+
*/
|
|
89
99
|
assertMatchAny(
|
|
90
100
|
expectedEvents: Omit<ITelemetryBaseEvent, "category">[],
|
|
91
101
|
message?: string,
|
|
92
102
|
inlineDetailsProp: boolean = false,
|
|
93
|
-
) {
|
|
103
|
+
): void {
|
|
94
104
|
const actualEvents = this.events;
|
|
95
105
|
if (!this.matchAnyEvent(expectedEvents, inlineDetailsProp)) {
|
|
96
106
|
throw new Error(`${message}
|
|
@@ -120,12 +130,14 @@ ${JSON.stringify(actualEvents)}`);
|
|
|
120
130
|
);
|
|
121
131
|
}
|
|
122
132
|
|
|
123
|
-
/**
|
|
133
|
+
/**
|
|
134
|
+
* Asserts that matchEvents is true, and prints the actual/expected output if not
|
|
135
|
+
*/
|
|
124
136
|
assertMatchStrict(
|
|
125
137
|
expectedEvents: Omit<ITelemetryBaseEvent, "category">[],
|
|
126
138
|
message?: string,
|
|
127
139
|
inlineDetailsProp: boolean = false,
|
|
128
|
-
) {
|
|
140
|
+
): void {
|
|
129
141
|
const actualEvents = this.events;
|
|
130
142
|
if (!this.matchEventStrict(expectedEvents, inlineDetailsProp)) {
|
|
131
143
|
throw new Error(`${message}
|
|
@@ -137,12 +149,14 @@ ${JSON.stringify(actualEvents)}`);
|
|
|
137
149
|
}
|
|
138
150
|
}
|
|
139
151
|
|
|
140
|
-
/**
|
|
152
|
+
/**
|
|
153
|
+
* Asserts that matchAnyEvent is false for the given events, and prints the actual/expected output if not
|
|
154
|
+
*/
|
|
141
155
|
assertMatchNone(
|
|
142
156
|
disallowedEvents: Omit<ITelemetryBaseEvent, "category">[],
|
|
143
157
|
message?: string,
|
|
144
158
|
inlineDetailsProp: boolean = false,
|
|
145
|
-
) {
|
|
159
|
+
): void {
|
|
146
160
|
const actualEvents = this.events;
|
|
147
161
|
if (this.matchAnyEvent(disallowedEvents, inlineDetailsProp)) {
|
|
148
162
|
throw new Error(`${message}
|
|
@@ -159,7 +173,7 @@ ${JSON.stringify(actualEvents)}`);
|
|
|
159
173
|
inlineDetailsProp: boolean,
|
|
160
174
|
): number {
|
|
161
175
|
let iExpectedEvent = 0;
|
|
162
|
-
this.events
|
|
176
|
+
for (const event of this.events) {
|
|
163
177
|
if (
|
|
164
178
|
iExpectedEvent < expectedEvents.length &&
|
|
165
179
|
MockLogger.eventsMatch(event, expectedEvents[iExpectedEvent], inlineDetailsProp)
|
|
@@ -167,7 +181,7 @@ ${JSON.stringify(actualEvents)}`);
|
|
|
167
181
|
// We found the next expected event; increment
|
|
168
182
|
++iExpectedEvent;
|
|
169
183
|
}
|
|
170
|
-
}
|
|
184
|
+
}
|
|
171
185
|
|
|
172
186
|
// Remove the events so far; next call will just compare subsequent events from here
|
|
173
187
|
this.events = [];
|
|
@@ -191,16 +205,19 @@ ${JSON.stringify(actualEvents)}`);
|
|
|
191
205
|
if (inlineDetailsProp && details !== undefined) {
|
|
192
206
|
assert(
|
|
193
207
|
typeof details === "string",
|
|
208
|
+
// eslint-disable-next-line unicorn/numeric-separators-style
|
|
194
209
|
0x6c9 /* Details should a JSON stringified string if inlineDetailsProp is true */,
|
|
195
210
|
);
|
|
211
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
196
212
|
const detailsExpanded = JSON.parse(details);
|
|
213
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
197
214
|
return matchObjects({ ...actualForMatching, ...detailsExpanded }, expected);
|
|
198
215
|
}
|
|
199
216
|
return matchObjects(actual, expected);
|
|
200
217
|
}
|
|
201
218
|
}
|
|
202
219
|
|
|
203
|
-
function matchObjects(actual: ITelemetryPropertiesExt, expected: ITelemetryPropertiesExt) {
|
|
220
|
+
function matchObjects(actual: ITelemetryPropertiesExt, expected: ITelemetryPropertiesExt): boolean {
|
|
204
221
|
for (const [expectedKey, expectedValue] of Object.entries(expected)) {
|
|
205
222
|
const actualValue = actual[expectedKey];
|
|
206
223
|
if (
|
|
@@ -9,14 +9,17 @@ import {
|
|
|
9
9
|
ITelemetryProperties,
|
|
10
10
|
IDisposable,
|
|
11
11
|
} from "@fluidframework/core-interfaces";
|
|
12
|
-
import { performance } from "@
|
|
12
|
+
import { performance } from "@fluid-internal/client-utils";
|
|
13
13
|
import { ITelemetryLoggerExt } from "./telemetryTypes";
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* @privateRemarks
|
|
17
|
+
*
|
|
18
|
+
* The names of the properties in this interface are the ones that will get stamped in the
|
|
19
|
+
* telemetry event, changes should be considered carefully. The optional properties should
|
|
20
|
+
* only be populated if 'includeAggregateMetrics' is true.
|
|
21
|
+
*/
|
|
15
22
|
interface Measurements {
|
|
16
|
-
// The names of the properties in this interface are the ones that will get stamped in the
|
|
17
|
-
// telemetry event, changes should be considered carefully. The optional properties should
|
|
18
|
-
// only be populated if 'includeAggregateMetrics' is true.
|
|
19
|
-
|
|
20
23
|
/**
|
|
21
24
|
* The duration of the latest execution.
|
|
22
25
|
*/
|
|
@@ -45,7 +48,7 @@ interface Measurements {
|
|
|
45
48
|
|
|
46
49
|
/**
|
|
47
50
|
* Helper class that executes a specified code block and writes an
|
|
48
|
-
* {@link @fluidframework/
|
|
51
|
+
* {@link @fluidframework/core-interfaces#ITelemetryPerformanceEvent} to a specified logger every time a specified
|
|
49
52
|
* number of executions is reached (or when the class is disposed). The `duration` field in the telemetry event is
|
|
50
53
|
* the duration of the latest execution (sample) of the specified function. See the documentation of the
|
|
51
54
|
* `includeAggregateMetrics` parameter for additional details that can be included.
|
|
@@ -82,12 +85,13 @@ export class SampledTelemetryHelper implements IDisposable {
|
|
|
82
85
|
) {}
|
|
83
86
|
|
|
84
87
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* value.
|
|
88
|
+
* Executes the specified code and keeps track of execution time statistics.
|
|
89
|
+
* If it's been called enough times (the sampleThreshold for the class) then it generates a log message with the necessary information.
|
|
90
|
+
*
|
|
91
|
+
* @param codeToMeasure - The code to be executed and measured.
|
|
92
|
+
* @param bucket - A key to track executions of the code block separately.
|
|
93
|
+
* Each different value of this parameter has a separate set of executions and metrics tracked by the class.
|
|
94
|
+
* If no such distinction needs to be made, do not provide a value.
|
|
91
95
|
* @returns Whatever the passed-in code block returns.
|
|
92
96
|
*/
|
|
93
97
|
public measure<T>(codeToMeasure: () => T, bucket: string = ""): T {
|
|
@@ -116,7 +120,7 @@ export class SampledTelemetryHelper implements IDisposable {
|
|
|
116
120
|
return returnValue;
|
|
117
121
|
}
|
|
118
122
|
|
|
119
|
-
private flushBucket(bucket: string) {
|
|
123
|
+
private flushBucket(bucket: string): void {
|
|
120
124
|
const measurements = this.measurementsMap.get(bucket);
|
|
121
125
|
if (measurements === undefined) {
|
|
122
126
|
return;
|
|
@@ -137,6 +141,6 @@ export class SampledTelemetryHelper implements IDisposable {
|
|
|
137
141
|
}
|
|
138
142
|
|
|
139
143
|
public dispose(error?: Error | undefined): void {
|
|
140
|
-
this.measurementsMap.
|
|
144
|
+
for (const [k] of this.measurementsMap.entries()) this.flushBucket(k);
|
|
141
145
|
}
|
|
142
146
|
}
|
package/src/telemetryTypes.ts
CHANGED
|
@@ -3,11 +3,20 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { ITelemetryBaseLogger,
|
|
6
|
+
import { ITelemetryBaseLogger, LogLevel, Tagged } from "@fluidframework/core-interfaces";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The categories FF uses when instrumenting the code.
|
|
10
|
+
*
|
|
11
|
+
* generic - Informational log event
|
|
12
|
+
* error - Error log event, ideally 0 of these are logged during a session
|
|
13
|
+
* performance - Includes duration, and often has _start, _end, or _cancel suffixes for activity tracking
|
|
14
|
+
*/
|
|
15
|
+
export type TelemetryEventCategory = "generic" | "error" | "performance";
|
|
7
16
|
|
|
8
17
|
/**
|
|
9
18
|
* Property types that can be logged.
|
|
10
|
-
* Includes extra types beyond
|
|
19
|
+
* Includes extra types beyond TelemetryBaseEventPropertyType, which must be converted before sending to a base logger
|
|
11
20
|
*/
|
|
12
21
|
export type TelemetryEventPropertyTypeExt =
|
|
13
22
|
| string
|
|
@@ -24,6 +33,8 @@ export type TelemetryEventPropertyTypeExt =
|
|
|
24
33
|
* A property to be logged to telemetry containing both the value and a tag. Tags are generic strings that can be used
|
|
25
34
|
* to mark pieces of information that should be organized or handled differently by loggers in various first or third
|
|
26
35
|
* party scenarios. For example, tags are used to mark personal information that should not be stored in logs.
|
|
36
|
+
*
|
|
37
|
+
* @deprecated Use Tagged<TelemetryEventPropertyTypeExt>
|
|
27
38
|
*/
|
|
28
39
|
export interface ITaggedTelemetryPropertyTypeExt {
|
|
29
40
|
value: TelemetryEventPropertyTypeExt;
|
|
@@ -34,7 +45,7 @@ export interface ITaggedTelemetryPropertyTypeExt {
|
|
|
34
45
|
* JSON-serializable properties, which will be logged with telemetry.
|
|
35
46
|
*/
|
|
36
47
|
export interface ITelemetryPropertiesExt {
|
|
37
|
-
[index: string]: TelemetryEventPropertyTypeExt |
|
|
48
|
+
[index: string]: TelemetryEventPropertyTypeExt | Tagged<TelemetryEventPropertyTypeExt>;
|
|
38
49
|
}
|
|
39
50
|
|
|
40
51
|
/**
|
|
@@ -83,18 +94,30 @@ export interface ITelemetryLoggerExt extends ITelemetryBaseLogger {
|
|
|
83
94
|
* Send information telemetry event
|
|
84
95
|
* @param event - Event to send
|
|
85
96
|
* @param error - optional error object to log
|
|
97
|
+
* @param logLevel - optional level of the log.
|
|
86
98
|
*/
|
|
87
|
-
sendTelemetryEvent(
|
|
99
|
+
sendTelemetryEvent(
|
|
100
|
+
event: ITelemetryGenericEventExt,
|
|
101
|
+
error?: unknown,
|
|
102
|
+
logLevel?: typeof LogLevel.verbose | typeof LogLevel.default,
|
|
103
|
+
): void;
|
|
88
104
|
|
|
89
105
|
/**
|
|
90
106
|
* Send error telemetry event
|
|
91
107
|
* @param event - Event to send
|
|
108
|
+
* @param error - optional error object to log
|
|
92
109
|
*/
|
|
93
|
-
sendErrorEvent(event: ITelemetryErrorEventExt, error?:
|
|
110
|
+
sendErrorEvent(event: ITelemetryErrorEventExt, error?: unknown): void;
|
|
94
111
|
|
|
95
112
|
/**
|
|
96
113
|
* Send performance telemetry event
|
|
97
114
|
* @param event - Event to send
|
|
115
|
+
* @param error - optional error object to log
|
|
116
|
+
* @param logLevel - optional level of the log.
|
|
98
117
|
*/
|
|
99
|
-
sendPerformanceEvent(
|
|
118
|
+
sendPerformanceEvent(
|
|
119
|
+
event: ITelemetryPerformanceEventExt,
|
|
120
|
+
error?: unknown,
|
|
121
|
+
logLevel?: typeof LogLevel.verbose | typeof LogLevel.default,
|
|
122
|
+
): void;
|
|
100
123
|
}
|
package/src/thresholdCounter.ts
CHANGED
|
@@ -19,7 +19,7 @@ export class ThresholdCounter {
|
|
|
19
19
|
/**
|
|
20
20
|
* Sends the value if it's above the treshold.
|
|
21
21
|
*/
|
|
22
|
-
public send(eventName: string, value: number) {
|
|
22
|
+
public send(eventName: string, value: number): void {
|
|
23
23
|
if (value < this.threshold) {
|
|
24
24
|
return;
|
|
25
25
|
}
|
|
@@ -36,7 +36,7 @@ export class ThresholdCounter {
|
|
|
36
36
|
* To be used in scenarios where we'd like to record a
|
|
37
37
|
* threshold violation while reducing telemetry noise.
|
|
38
38
|
*/
|
|
39
|
-
public sendIfMultiple(eventName: string, value: number) {
|
|
39
|
+
public sendIfMultiple(eventName: string, value: number): void {
|
|
40
40
|
if (value === this.thresholdMultiple) {
|
|
41
41
|
this.logger.sendPerformanceEvent({
|
|
42
42
|
eventName,
|
package/src/utils.ts
CHANGED