@fluidframework/telemetry-utils 2.0.0-internal.3.0.0 → 2.0.0-internal.3.1.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 +11 -13
- package/.mocharc.js +2 -2
- package/api-extractor.json +2 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -3
- package/dist/config.js.map +1 -1
- package/dist/debugLogger.d.ts.map +1 -1
- package/dist/debugLogger.js.map +1 -1
- package/dist/errorLogging.d.ts +5 -5
- package/dist/errorLogging.d.ts.map +1 -1
- package/dist/errorLogging.js +20 -18
- package/dist/errorLogging.js.map +1 -1
- package/dist/eventEmitterWithErrorHandling.d.ts.map +1 -1
- package/dist/eventEmitterWithErrorHandling.js.map +1 -1
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js.map +1 -1
- package/dist/fluidErrorBase.d.ts.map +1 -1
- package/dist/fluidErrorBase.js +4 -4
- package/dist/fluidErrorBase.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +13 -12
- package/dist/logger.js.map +1 -1
- package/dist/mockLogger.d.ts +5 -5
- package/dist/mockLogger.d.ts.map +1 -1
- package/dist/mockLogger.js +5 -5
- package/dist/mockLogger.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/sampledTelemetryHelper.d.ts.map +1 -1
- package/dist/sampledTelemetryHelper.js.map +1 -1
- 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.map +1 -1
- package/dist/utils.js.map +1 -1
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +3 -3
- package/lib/config.js.map +1 -1
- package/lib/debugLogger.d.ts.map +1 -1
- package/lib/debugLogger.js +1 -1
- package/lib/debugLogger.js.map +1 -1
- package/lib/errorLogging.d.ts +5 -5
- package/lib/errorLogging.d.ts.map +1 -1
- package/lib/errorLogging.js +20 -18
- package/lib/errorLogging.js.map +1 -1
- package/lib/eventEmitterWithErrorHandling.d.ts.map +1 -1
- package/lib/eventEmitterWithErrorHandling.js.map +1 -1
- package/lib/events.d.ts.map +1 -1
- package/lib/events.js.map +1 -1
- package/lib/fluidErrorBase.d.ts.map +1 -1
- package/lib/fluidErrorBase.js +4 -4
- package/lib/fluidErrorBase.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib/logger.d.ts.map +1 -1
- package/lib/logger.js +14 -13
- package/lib/logger.js.map +1 -1
- package/lib/mockLogger.d.ts +5 -5
- package/lib/mockLogger.d.ts.map +1 -1
- package/lib/mockLogger.js +5 -5
- package/lib/mockLogger.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/sampledTelemetryHelper.d.ts.map +1 -1
- package/lib/sampledTelemetryHelper.js.map +1 -1
- 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.map +1 -1
- package/lib/utils.js.map +1 -1
- package/package.json +107 -110
- package/prettier.config.cjs +1 -1
- package/src/config.ts +173 -172
- package/src/debugLogger.ts +118 -111
- package/src/errorLogging.ts +302 -299
- package/src/eventEmitterWithErrorHandling.ts +16 -12
- package/src/events.ts +26 -26
- package/src/fluidErrorBase.ts +42 -38
- package/src/index.ts +26 -16
- package/src/logger.ts +541 -533
- package/src/mockLogger.ts +113 -107
- package/src/packageVersion.ts +1 -1
- package/src/sampledTelemetryHelper.ts +122 -122
- package/src/telemetryTypes.ts +37 -37
- package/src/thresholdCounter.ts +34 -34
- package/src/utils.ts +15 -15
- package/tsconfig.esnext.json +6 -6
- package/tsconfig.json +9 -13
package/src/mockLogger.ts
CHANGED
|
@@ -11,131 +11,137 @@ import { TelemetryLogger } from "./logger";
|
|
|
11
11
|
* searching for a set of expected events to match against the logged events.
|
|
12
12
|
*/
|
|
13
13
|
export class MockLogger extends TelemetryLogger implements ITelemetryLogger {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
14
|
+
events: ITelemetryBaseEvent[] = [];
|
|
15
|
+
|
|
16
|
+
constructor() {
|
|
17
|
+
super();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
clear() {
|
|
21
|
+
this.events = [];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
send(event: ITelemetryBaseEvent): void {
|
|
25
|
+
this.events.push(event);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Search events logged since the last time matchEvents was called, looking for the given expected
|
|
30
|
+
* events in order.
|
|
31
|
+
* @param expectedEvents - events in order that are expected to appear in the recorded log.
|
|
32
|
+
* These event objects may be subsets of the logged events.
|
|
33
|
+
* Note: category is omitted from the type because it's usually uninteresting and tedious to type.
|
|
34
|
+
*/
|
|
35
|
+
matchEvents(expectedEvents: Omit<ITelemetryBaseEvent, "category">[]): boolean {
|
|
36
|
+
const matchedExpectedEventCount = this.getMatchedEventsCount(expectedEvents);
|
|
37
|
+
// How many expected events were left over? Hopefully none.
|
|
38
|
+
const unmatchedExpectedEventCount = expectedEvents.length - matchedExpectedEventCount;
|
|
39
|
+
return unmatchedExpectedEventCount === 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Asserts that matchEvents is true, and prints the actual/expected output if not */
|
|
43
|
+
assertMatch(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string) {
|
|
44
|
+
const actualEvents = this.events;
|
|
45
|
+
if (!this.matchEvents(expectedEvents)) {
|
|
46
|
+
throw new Error(`${message}
|
|
45
47
|
expected:
|
|
46
48
|
${JSON.stringify(expectedEvents)}
|
|
47
49
|
|
|
48
50
|
actual:
|
|
49
51
|
${JSON.stringify(actualEvents)}`);
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Search events logged since the last time matchEvents was called, looking for any of the given
|
|
57
|
+
* expected events.
|
|
58
|
+
* @param expectedEvents - events that are expected to appear in the recorded log.
|
|
59
|
+
* These event objects may be subsets of the logged events.
|
|
60
|
+
* Note: category is omitted from the type because it's usually uninteresting and tedious to type.
|
|
61
|
+
* @returns if any of the expected events is found.
|
|
62
|
+
*/
|
|
63
|
+
matchAnyEvent(expectedEvents: Omit<ITelemetryBaseEvent, "category">[]): boolean {
|
|
64
|
+
const matchedExpectedEventCount = this.getMatchedEventsCount(expectedEvents);
|
|
65
|
+
return matchedExpectedEventCount > 0;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Asserts that matchAnyEvent is true, and prints the actual/expected output if not */
|
|
69
|
+
assertMatchAny(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string) {
|
|
70
|
+
const actualEvents = this.events;
|
|
71
|
+
if (!this.matchAnyEvent(expectedEvents)) {
|
|
72
|
+
throw new Error(`${message}
|
|
71
73
|
expected:
|
|
72
74
|
${JSON.stringify(expectedEvents)}
|
|
73
75
|
|
|
74
76
|
actual:
|
|
75
77
|
${JSON.stringify(actualEvents)}`);
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Search events logged since the last time matchEvents was called, looking only for the given expected
|
|
83
|
+
* events in order.
|
|
84
|
+
* @param expectedEvents - events in order that are expected to be the only events in the recorded log.
|
|
85
|
+
* These event objects may be subsets of the logged events.
|
|
86
|
+
* Note: category is omitted from the type because it's usually uninteresting and tedious to type.
|
|
87
|
+
*/
|
|
88
|
+
matchEventStrict(expectedEvents: Omit<ITelemetryBaseEvent, "category">[]): boolean {
|
|
89
|
+
return expectedEvents.length === this.events.length && this.matchEvents(expectedEvents);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Asserts that matchEvents is true, and prints the actual/expected output if not */
|
|
93
|
+
assertMatchStrict(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string) {
|
|
94
|
+
const actualEvents = this.events;
|
|
95
|
+
if (!this.matchEventStrict(expectedEvents)) {
|
|
96
|
+
throw new Error(`${message}
|
|
95
97
|
expected:
|
|
96
98
|
${JSON.stringify(expectedEvents)}
|
|
97
99
|
|
|
98
100
|
actual:
|
|
99
101
|
${JSON.stringify(actualEvents)}`);
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Asserts that matchAnyEvent is false for the given events, and prints the actual/expected output if not */
|
|
106
|
+
assertMatchNone(disallowedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string) {
|
|
107
|
+
const actualEvents = this.events;
|
|
108
|
+
if (this.matchAnyEvent(disallowedEvents)) {
|
|
109
|
+
throw new Error(`${message}
|
|
108
110
|
disallowed events:
|
|
109
111
|
${JSON.stringify(disallowedEvents)}
|
|
110
112
|
|
|
111
113
|
actual:
|
|
112
114
|
${JSON.stringify(actualEvents)}`);
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private getMatchedEventsCount(expectedEvents: Omit<ITelemetryBaseEvent, "category">[]): number {
|
|
119
|
+
let iExpectedEvent = 0;
|
|
120
|
+
this.events.forEach((event) => {
|
|
121
|
+
if (
|
|
122
|
+
iExpectedEvent < expectedEvents.length &&
|
|
123
|
+
MockLogger.eventsMatch(event, expectedEvents[iExpectedEvent])
|
|
124
|
+
) {
|
|
125
|
+
// We found the next expected event; increment
|
|
126
|
+
++iExpectedEvent;
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// Remove the events so far; next call will just compare subsequent events from here
|
|
131
|
+
this.events = [];
|
|
132
|
+
|
|
133
|
+
// Return the count of matched events.
|
|
134
|
+
return iExpectedEvent;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Ensure the expected event is a strict subset of the actual event
|
|
139
|
+
*/
|
|
140
|
+
private static eventsMatch(
|
|
141
|
+
actual: ITelemetryBaseEvent,
|
|
142
|
+
expected: Omit<ITelemetryBaseEvent, "category">,
|
|
143
|
+
): boolean {
|
|
144
|
+
const masked = { ...actual, ...expected };
|
|
145
|
+
return JSON.stringify(masked) === JSON.stringify(actual);
|
|
146
|
+
}
|
|
141
147
|
}
|
package/src/packageVersion.ts
CHANGED
|
@@ -4,43 +4,43 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
IDisposable,
|
|
8
|
+
ITelemetryGenericEvent,
|
|
9
|
+
ITelemetryLogger,
|
|
10
|
+
ITelemetryPerformanceEvent,
|
|
11
|
+
ITelemetryProperties,
|
|
12
12
|
} from "@fluidframework/common-definitions";
|
|
13
13
|
import { performance } from "@fluidframework/common-utils";
|
|
14
14
|
|
|
15
15
|
interface Measurements {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
+
/**
|
|
21
|
+
* The duration of the latest execution.
|
|
22
|
+
*/
|
|
23
|
+
duration: number;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The number of executions since the last time an event was generated.
|
|
27
|
+
*/
|
|
28
|
+
count: number;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Total duration across all the executions since the last event was generated.
|
|
32
|
+
*/
|
|
33
|
+
totalDuration?: number;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Min duration across all the executions since the last event was generated.
|
|
37
|
+
*/
|
|
38
|
+
minDuration?: number;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Max duration across all the executions since the last event was generated.
|
|
42
|
+
*/
|
|
43
|
+
maxDuration?: number;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
/**
|
|
@@ -50,93 +50,93 @@ interface Measurements {
|
|
|
50
50
|
* the duration of the latest execution (sample) of the specified function. See the documentation of the
|
|
51
51
|
* `includeAggregateMetrics` parameter for additional details that can be included.
|
|
52
52
|
*/
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
53
|
+
export class SampledTelemetryHelper implements IDisposable {
|
|
54
|
+
disposed: boolean = false;
|
|
55
|
+
|
|
56
|
+
private readonly measurementsMap = new Map<string, Measurements>();
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @param eventBase -
|
|
60
|
+
* Custom properties to include in the telemetry performance event when it is written.
|
|
61
|
+
* @param logger -
|
|
62
|
+
* The logger to use to write the telemetry performance event.
|
|
63
|
+
* @param sampleThreshold -
|
|
64
|
+
* Telemetry performance events will be generated every time we hit this many executions of the code block.
|
|
65
|
+
* @param includeAggregateMetrics -
|
|
66
|
+
* If set to `true`, the telemetry performance event will include aggregated metrics (total duration, min duration,
|
|
67
|
+
* max duration) for all the executions in between generated events.
|
|
68
|
+
* @param perBucketProperties -
|
|
69
|
+
* Map of strings that represent different buckets (which can be specified when calling the 'measure' method), to
|
|
70
|
+
* properties which should be added to the telemetry event for that bucket. If a bucket being measured does not
|
|
71
|
+
* have an entry in this map, no additional properties will be added to its telemetry events. The following keys are
|
|
72
|
+
* reserved for use by this class: "duration", "count", "totalDuration", "minDuration", "maxDuration". If any of
|
|
73
|
+
* them is specified as a key in one of the ITelemetryProperties objects in this map, that key-value pair will be
|
|
74
|
+
* ignored.
|
|
75
|
+
*/
|
|
76
|
+
public constructor(
|
|
77
|
+
private readonly eventBase: ITelemetryGenericEvent,
|
|
78
|
+
private readonly logger: ITelemetryLogger,
|
|
79
|
+
private readonly sampleThreshold: number,
|
|
80
|
+
private readonly includeAggregateMetrics: boolean = false,
|
|
81
|
+
private readonly perBucketProperties = new Map<string, ITelemetryProperties>(),
|
|
82
|
+
) {}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @param codeToMeasure -
|
|
86
|
+
* The code to be executed and measured.
|
|
87
|
+
* @param bucket -
|
|
88
|
+
* A key to track executions of the code block separately. Each different value of this parameter has a separate
|
|
89
|
+
* set of executions and metrics tracked by the class. If no such distinction needs to be made, do not provide a
|
|
90
|
+
* value.
|
|
91
|
+
* @returns Whatever the passed-in code block returns.
|
|
92
|
+
*/
|
|
93
|
+
public measure<T>(codeToMeasure: () => T, bucket: string = ""): T {
|
|
94
|
+
const start = performance.now();
|
|
95
|
+
const returnValue = codeToMeasure();
|
|
96
|
+
const duration = performance.now() - start;
|
|
97
|
+
|
|
98
|
+
let m = this.measurementsMap.get(bucket);
|
|
99
|
+
if (m === undefined) {
|
|
100
|
+
m = { count: 0, duration: -1 };
|
|
101
|
+
this.measurementsMap.set(bucket, m);
|
|
102
|
+
}
|
|
103
|
+
m.count++;
|
|
104
|
+
m.duration = duration;
|
|
105
|
+
|
|
106
|
+
if (this.includeAggregateMetrics) {
|
|
107
|
+
m.totalDuration = (m.totalDuration ?? 0) + duration;
|
|
108
|
+
m.minDuration = Math.min(m.minDuration ?? duration, duration);
|
|
109
|
+
m.maxDuration = Math.max(m.maxDuration ?? 0, duration);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (m.count >= this.sampleThreshold) {
|
|
113
|
+
this.flushBucket(bucket);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return returnValue;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
private flushBucket(bucket: string) {
|
|
120
|
+
const measurements = this.measurementsMap.get(bucket);
|
|
121
|
+
if (measurements === undefined) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (measurements.count !== 0) {
|
|
126
|
+
const bucketProperties = this.perBucketProperties.get(bucket);
|
|
127
|
+
|
|
128
|
+
const telemetryEvent: ITelemetryPerformanceEvent = {
|
|
129
|
+
...this.eventBase,
|
|
130
|
+
...bucketProperties, // If the bucket doesn't exist and this is undefined, things work as expected
|
|
131
|
+
...measurements,
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
this.logger.sendPerformanceEvent(telemetryEvent);
|
|
135
|
+
this.measurementsMap.delete(bucket);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
public dispose(error?: Error | undefined): void {
|
|
140
|
+
this.measurementsMap.forEach((_, k) => this.flushBucket(k));
|
|
141
|
+
}
|
|
142
142
|
}
|
package/src/telemetryTypes.ts
CHANGED
|
@@ -10,27 +10,27 @@ import { ITelemetryBaseLogger, TelemetryEventCategory } from "@fluidframework/co
|
|
|
10
10
|
* Includes extra types beyond TelemetryEventPropertyType (which will be deprecated in favor of this one)
|
|
11
11
|
*/
|
|
12
12
|
export type TelemetryEventPropertyTypeExt =
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
| string
|
|
14
|
+
| number
|
|
15
|
+
| boolean
|
|
16
|
+
| undefined
|
|
17
|
+
| (string | number | boolean)[];
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
/**
|
|
20
|
+
* A property to be logged to telemetry containing both the value and a tag. Tags are generic strings that can be used
|
|
21
|
+
* to mark pieces of information that should be organized or handled differently by loggers in various first or third
|
|
22
|
+
* party scenarios. For example, tags are used to mark personal information that should not be stored in logs.
|
|
23
|
+
*/
|
|
24
24
|
export interface ITaggedTelemetryPropertyTypeExt {
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
value: TelemetryEventPropertyTypeExt;
|
|
26
|
+
tag: string;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* JSON-serializable properties, which will be logged with telemetry.
|
|
31
31
|
*/
|
|
32
32
|
export interface ITelemetryPropertiesExt {
|
|
33
|
-
|
|
33
|
+
[index: string]: TelemetryEventPropertyTypeExt | ITaggedTelemetryPropertyTypeExt;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
/**
|
|
@@ -39,18 +39,18 @@ export interface ITelemetryPropertiesExt {
|
|
|
39
39
|
* @param category - category of the event, like "error", "performance", "generic", etc.
|
|
40
40
|
* @param eventName - name of the event.
|
|
41
41
|
*/
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
export interface ITelemetryEventExt extends ITelemetryPropertiesExt {
|
|
43
|
+
category: string;
|
|
44
|
+
eventName: string;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
48
|
* Informational (non-error) telemetry event
|
|
49
49
|
* Maps to category = "generic"
|
|
50
50
|
*/
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
export interface ITelemetryGenericEventExt extends ITelemetryPropertiesExt {
|
|
52
|
+
eventName: string;
|
|
53
|
+
category?: TelemetryEventCategory;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
/**
|
|
@@ -58,7 +58,7 @@ export interface ITelemetryPropertiesExt {
|
|
|
58
58
|
* Maps to category = "error"
|
|
59
59
|
*/
|
|
60
60
|
export interface ITelemetryErrorEventExt extends ITelemetryPropertiesExt {
|
|
61
|
-
|
|
61
|
+
eventName: string;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
/**
|
|
@@ -66,7 +66,7 @@ export interface ITelemetryErrorEventExt extends ITelemetryPropertiesExt {
|
|
|
66
66
|
* Maps to category = "performance"
|
|
67
67
|
*/
|
|
68
68
|
export interface ITelemetryPerformanceEventExt extends ITelemetryGenericEventExt {
|
|
69
|
-
|
|
69
|
+
duration?: number; // Duration of event (optional)
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
/**
|
|
@@ -75,22 +75,22 @@ export interface ITelemetryPerformanceEventExt extends ITelemetryGenericEventExt
|
|
|
75
75
|
* and ITelemetryBaseLogger should be used when loggers are passed between layers.
|
|
76
76
|
*/
|
|
77
77
|
export interface ITelemetryLoggerExt extends ITelemetryBaseLogger {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Send information telemetry event
|
|
80
|
+
* @param event - Event to send
|
|
81
|
+
* @param error - optional error object to log
|
|
82
|
+
*/
|
|
83
|
+
sendTelemetryEvent(event: ITelemetryGenericEventExt, error?: any): void;
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
85
|
+
/**
|
|
86
|
+
* Send error telemetry event
|
|
87
|
+
* @param event - Event to send
|
|
88
|
+
*/
|
|
89
|
+
sendErrorEvent(event: ITelemetryErrorEventExt, error?: any): void;
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
91
|
+
/**
|
|
92
|
+
* Send performance telemetry event
|
|
93
|
+
* @param event - Event to send
|
|
94
|
+
*/
|
|
95
|
+
sendPerformanceEvent(event: ITelemetryPerformanceEventExt, error?: any): void;
|
|
96
96
|
}
|