@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.
Files changed (155) hide show
  1. package/.eslintrc.js +12 -13
  2. package/.mocharc.js +12 -0
  3. package/CHANGELOG.md +249 -0
  4. package/README.md +68 -1
  5. package/api-extractor-lint.json +4 -0
  6. package/api-extractor.json +2 -2
  7. package/api-report/telemetry-utils.api.md +444 -0
  8. package/dist/config.d.ts +47 -16
  9. package/dist/config.d.ts.map +1 -1
  10. package/dist/config.js +88 -38
  11. package/dist/config.js.map +1 -1
  12. package/dist/error.d.ts +112 -0
  13. package/dist/error.d.ts.map +1 -0
  14. package/dist/error.js +159 -0
  15. package/dist/error.js.map +1 -0
  16. package/dist/errorLogging.d.ts +86 -20
  17. package/dist/errorLogging.d.ts.map +1 -1
  18. package/dist/errorLogging.js +190 -60
  19. package/dist/errorLogging.js.map +1 -1
  20. package/dist/eventEmitterWithErrorHandling.d.ts +9 -3
  21. package/dist/eventEmitterWithErrorHandling.d.ts.map +1 -1
  22. package/dist/eventEmitterWithErrorHandling.js +16 -3
  23. package/dist/eventEmitterWithErrorHandling.js.map +1 -1
  24. package/dist/events.d.ts +27 -3
  25. package/dist/events.d.ts.map +1 -1
  26. package/dist/events.js +26 -2
  27. package/dist/events.js.map +1 -1
  28. package/dist/fluidErrorBase.d.ts +57 -16
  29. package/dist/fluidErrorBase.d.ts.map +1 -1
  30. package/dist/fluidErrorBase.js +27 -14
  31. package/dist/fluidErrorBase.js.map +1 -1
  32. package/dist/index.d.ts +12 -11
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +55 -21
  35. package/dist/index.js.map +1 -1
  36. package/dist/logger.d.ts +267 -51
  37. package/dist/logger.d.ts.map +1 -1
  38. package/dist/logger.js +423 -132
  39. package/dist/logger.js.map +1 -1
  40. package/dist/mockLogger.d.ts +39 -12
  41. package/dist/mockLogger.d.ts.map +1 -1
  42. package/dist/mockLogger.js +105 -22
  43. package/dist/mockLogger.js.map +1 -1
  44. package/dist/sampledTelemetryHelper.d.ts +18 -12
  45. package/dist/sampledTelemetryHelper.d.ts.map +1 -1
  46. package/dist/sampledTelemetryHelper.js +28 -19
  47. package/dist/sampledTelemetryHelper.js.map +1 -1
  48. package/dist/telemetry-utils-alpha.d.ts +290 -0
  49. package/dist/telemetry-utils-beta.d.ts +264 -0
  50. package/dist/telemetry-utils-public.d.ts +264 -0
  51. package/dist/telemetry-utils-untrimmed.d.ts +1102 -0
  52. package/dist/telemetryTypes.d.ts +115 -0
  53. package/dist/telemetryTypes.d.ts.map +1 -0
  54. package/dist/telemetryTypes.js +7 -0
  55. package/dist/telemetryTypes.js.map +1 -0
  56. package/dist/thresholdCounter.d.ts +6 -5
  57. package/dist/thresholdCounter.d.ts.map +1 -1
  58. package/dist/thresholdCounter.js +4 -3
  59. package/dist/thresholdCounter.js.map +1 -1
  60. package/dist/tsdoc-metadata.json +11 -0
  61. package/dist/utils.d.ts +54 -3
  62. package/dist/utils.d.ts.map +1 -1
  63. package/dist/utils.js +58 -3
  64. package/dist/utils.js.map +1 -1
  65. package/lib/config.d.ts +47 -16
  66. package/lib/config.d.ts.map +1 -1
  67. package/lib/config.js +85 -36
  68. package/lib/config.js.map +1 -1
  69. package/lib/error.d.ts +112 -0
  70. package/lib/error.d.ts.map +1 -0
  71. package/lib/error.js +150 -0
  72. package/lib/error.js.map +1 -0
  73. package/lib/errorLogging.d.ts +86 -20
  74. package/lib/errorLogging.d.ts.map +1 -1
  75. package/lib/errorLogging.js +189 -60
  76. package/lib/errorLogging.js.map +1 -1
  77. package/lib/eventEmitterWithErrorHandling.d.ts +9 -3
  78. package/lib/eventEmitterWithErrorHandling.d.ts.map +1 -1
  79. package/lib/eventEmitterWithErrorHandling.js +15 -2
  80. package/lib/eventEmitterWithErrorHandling.js.map +1 -1
  81. package/lib/events.d.ts +27 -3
  82. package/lib/events.d.ts.map +1 -1
  83. package/lib/events.js +26 -2
  84. package/lib/events.js.map +1 -1
  85. package/lib/fluidErrorBase.d.ts +57 -16
  86. package/lib/fluidErrorBase.d.ts.map +1 -1
  87. package/lib/fluidErrorBase.js +27 -14
  88. package/lib/fluidErrorBase.js.map +1 -1
  89. package/lib/index.d.ts +12 -11
  90. package/lib/index.d.ts.map +1 -1
  91. package/lib/index.js +11 -11
  92. package/lib/index.js.map +1 -1
  93. package/lib/logger.d.ts +267 -51
  94. package/lib/logger.d.ts.map +1 -1
  95. package/lib/logger.js +415 -131
  96. package/lib/logger.js.map +1 -1
  97. package/lib/mockLogger.d.ts +39 -12
  98. package/lib/mockLogger.d.ts.map +1 -1
  99. package/lib/mockLogger.js +106 -23
  100. package/lib/mockLogger.js.map +1 -1
  101. package/lib/sampledTelemetryHelper.d.ts +18 -12
  102. package/lib/sampledTelemetryHelper.d.ts.map +1 -1
  103. package/lib/sampledTelemetryHelper.js +26 -17
  104. package/lib/sampledTelemetryHelper.js.map +1 -1
  105. package/lib/telemetry-utils-alpha.d.ts +290 -0
  106. package/lib/telemetry-utils-beta.d.ts +264 -0
  107. package/lib/telemetry-utils-public.d.ts +264 -0
  108. package/lib/telemetry-utils-untrimmed.d.ts +1102 -0
  109. package/lib/telemetryTypes.d.ts +115 -0
  110. package/lib/telemetryTypes.d.ts.map +1 -0
  111. package/lib/telemetryTypes.js +6 -0
  112. package/lib/telemetryTypes.js.map +1 -0
  113. package/lib/thresholdCounter.d.ts +6 -5
  114. package/lib/thresholdCounter.d.ts.map +1 -1
  115. package/lib/thresholdCounter.js +4 -3
  116. package/lib/thresholdCounter.js.map +1 -1
  117. package/lib/utils.d.ts +54 -3
  118. package/lib/utils.d.ts.map +1 -1
  119. package/lib/utils.js +56 -2
  120. package/lib/utils.js.map +1 -1
  121. package/package.json +86 -57
  122. package/prettier.config.cjs +8 -0
  123. package/src/config.ts +254 -189
  124. package/src/error.ts +235 -0
  125. package/src/errorLogging.ts +440 -290
  126. package/src/eventEmitterWithErrorHandling.ts +26 -14
  127. package/src/events.ts +54 -25
  128. package/src/fluidErrorBase.ts +94 -46
  129. package/src/index.ts +76 -17
  130. package/src/logger.ts +966 -505
  131. package/src/mockLogger.ts +225 -83
  132. package/src/sampledTelemetryHelper.ts +136 -128
  133. package/src/telemetryTypes.ts +140 -0
  134. package/src/thresholdCounter.ts +38 -37
  135. package/src/utils.ts +108 -17
  136. package/tsconfig.esnext.json +6 -6
  137. package/tsconfig.json +9 -13
  138. package/dist/debugLogger.d.ts +0 -39
  139. package/dist/debugLogger.d.ts.map +0 -1
  140. package/dist/debugLogger.js +0 -101
  141. package/dist/debugLogger.js.map +0 -1
  142. package/dist/packageVersion.d.ts +0 -9
  143. package/dist/packageVersion.d.ts.map +0 -1
  144. package/dist/packageVersion.js +0 -12
  145. package/dist/packageVersion.js.map +0 -1
  146. package/lib/debugLogger.d.ts +0 -39
  147. package/lib/debugLogger.d.ts.map +0 -1
  148. package/lib/debugLogger.js +0 -97
  149. package/lib/debugLogger.js.map +0 -1
  150. package/lib/packageVersion.d.ts +0 -9
  151. package/lib/packageVersion.d.ts.map +0 -1
  152. package/lib/packageVersion.js +0 -9
  153. package/lib/packageVersion.js.map +0 -1
  154. package/src/debugLogger.ts +0 -126
  155. package/src/packageVersion.ts +0 -9
package/src/error.ts ADDED
@@ -0,0 +1,235 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import {
7
+ FluidErrorTypes,
8
+ IGenericError,
9
+ IErrorBase,
10
+ ITelemetryBaseProperties,
11
+ IUsageError,
12
+ } from "@fluidframework/core-interfaces";
13
+ import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
14
+
15
+ import {
16
+ LoggingError,
17
+ NORMALIZED_ERROR_TYPE,
18
+ isExternalError,
19
+ normalizeError,
20
+ wrapError,
21
+ } from "./errorLogging";
22
+ import { IFluidErrorBase } from "./fluidErrorBase";
23
+
24
+ /**
25
+ * Throws a UsageError with the given message if the condition is not met.
26
+ * Use this API when `false` indicates a precondition is not met on a public API (for any FF layer).
27
+ *
28
+ * @param condition - The condition that should be true, if the condition is false a UsageError will be thrown.
29
+ * @param message - The message to include in the error when the condition does not hold.
30
+ * @param props - Telemetry props to include on the error when the condition does not hold.
31
+ * @internal
32
+ */
33
+ export function validatePrecondition(
34
+ condition: boolean,
35
+ message: string,
36
+ props?: ITelemetryBaseProperties,
37
+ ): asserts condition {
38
+ if (!condition) {
39
+ throw new UsageError(message, props);
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Generic wrapper for an unrecognized/uncategorized error object
45
+ *
46
+ * @internal
47
+ */
48
+ export class GenericError extends LoggingError implements IGenericError, IFluidErrorBase {
49
+ readonly errorType = FluidErrorTypes.genericError;
50
+
51
+ /**
52
+ * Create a new GenericError
53
+ * @param message - Error message
54
+ * @param error - inner error object
55
+ * @param props - Telemetry props to include when the error is logged
56
+ */
57
+ constructor(
58
+ message: string,
59
+ // TODO: Use `unknown` instead (API breaking change because error is not just an input parameter, but a public member of the class)
60
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
61
+ public readonly error?: any,
62
+ props?: ITelemetryBaseProperties,
63
+ ) {
64
+ // Don't try to log the inner error
65
+ super(message, props, new Set(["error"]));
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Error indicating an API is being used improperly resulting in an invalid operation.
71
+ *
72
+ * @internal
73
+ */
74
+ export class UsageError extends LoggingError implements IUsageError, IFluidErrorBase {
75
+ readonly errorType = FluidErrorTypes.usageError;
76
+
77
+ constructor(message: string, props?: ITelemetryBaseProperties) {
78
+ super(message, { ...props, usageError: true });
79
+ }
80
+ }
81
+
82
+ /**
83
+ * DataCorruptionError indicates that we encountered definitive evidence that the data at rest
84
+ * backing this container is corrupted, and this container would never be expected to load properly again
85
+ *
86
+ * @internal
87
+ */
88
+ export class DataCorruptionError extends LoggingError implements IErrorBase, IFluidErrorBase {
89
+ readonly errorType = FluidErrorTypes.dataCorruptionError;
90
+ readonly canRetry = false;
91
+
92
+ constructor(message: string, props: ITelemetryBaseProperties) {
93
+ super(message, { ...props, dataProcessingError: 1 });
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Indicates we hit a fatal error while processing incoming data from the Fluid Service.
99
+ *
100
+ * @remarks
101
+ *
102
+ * The error will often originate in the dataStore or DDS implementation that is responding to incoming changes.
103
+ * This differs from {@link DataCorruptionError} in that this may be a transient error that will not repro in another
104
+ * client or session.
105
+ *
106
+ * @internal
107
+ */
108
+ export class DataProcessingError extends LoggingError implements IErrorBase, IFluidErrorBase {
109
+ /**
110
+ * {@inheritDoc IFluidErrorBase.errorType}
111
+ */
112
+ public readonly errorType = FluidErrorTypes.dataProcessingError;
113
+
114
+ public readonly canRetry = false;
115
+
116
+ private constructor(errorMessage: string, props?: ITelemetryBaseProperties) {
117
+ super(errorMessage, props);
118
+ }
119
+
120
+ /**
121
+ * Create a new `DataProcessingError` detected and raised within the Fluid Framework.
122
+ */
123
+ public static create(
124
+ errorMessage: string,
125
+ dataProcessingCodepath: string,
126
+ sequencedMessage?: ISequencedDocumentMessage,
127
+ props: ITelemetryBaseProperties = {},
128
+ ): IFluidErrorBase {
129
+ const dataProcessingError = DataProcessingError.wrapIfUnrecognized(
130
+ errorMessage,
131
+ dataProcessingCodepath,
132
+ sequencedMessage,
133
+ );
134
+ dataProcessingError.addTelemetryProperties(props);
135
+
136
+ return dataProcessingError;
137
+ }
138
+
139
+ /**
140
+ * Wrap the given error in a `DataProcessingError`, unless the error is already of a known type
141
+ * with the exception of a normalized {@link LoggingError}, which will still be wrapped.
142
+ *
143
+ * In either case, the error will have some relevant properties added for telemetry.
144
+ *
145
+ * @remarks
146
+ *
147
+ * We wrap conditionally since known error types represent well-understood failure modes, and ideally
148
+ * one day we will move away from throwing these errors but rather we'll return them.
149
+ * But an unrecognized error needs to be classified as `DataProcessingError`.
150
+ *
151
+ * @param originalError - The error to be converted.
152
+ * @param dataProcessingCodepath - Which code-path failed while processing data.
153
+ * @param messageLike - Message to include info about via telemetry props.
154
+ *
155
+ * @returns Either a new `DataProcessingError`, or (if wrapping is deemed unnecessary) the given error.
156
+ */
157
+ public static wrapIfUnrecognized(
158
+ originalError: unknown,
159
+ dataProcessingCodepath: string,
160
+ messageLike?: Partial<
161
+ Pick<
162
+ ISequencedDocumentMessage,
163
+ | "clientId"
164
+ | "sequenceNumber"
165
+ | "clientSequenceNumber"
166
+ | "referenceSequenceNumber"
167
+ | "minimumSequenceNumber"
168
+ | "timestamp"
169
+ >
170
+ >,
171
+ ): IFluidErrorBase {
172
+ const props = {
173
+ dataProcessingError: 1,
174
+ dataProcessingCodepath,
175
+ ...(messageLike === undefined
176
+ ? undefined
177
+ : extractSafePropertiesFromMessage(messageLike)),
178
+ };
179
+
180
+ const normalizedError = normalizeError(originalError, { props });
181
+ // Note that other errors may have the NORMALIZED_ERROR_TYPE errorType,
182
+ // but if so they are still suitable to be wrapped as DataProcessingError.
183
+ if (
184
+ isExternalError(normalizedError) ||
185
+ normalizedError.errorType === NORMALIZED_ERROR_TYPE
186
+ ) {
187
+ // Create a new DataProcessingError to wrap this external error
188
+ const dataProcessingError = wrapError(
189
+ normalizedError,
190
+ (message: string) => new DataProcessingError(message),
191
+ );
192
+
193
+ // Copy over the props above and any others added to this error since first being normalized
194
+ dataProcessingError.addTelemetryProperties(normalizedError.getTelemetryProperties());
195
+
196
+ return dataProcessingError;
197
+ }
198
+ return normalizedError;
199
+ }
200
+ }
201
+
202
+ /**
203
+ * Extracts specific properties from the provided message that we know are safe to log.
204
+ *
205
+ * @param messageLike - Message to include info about via telemetry props.
206
+ *
207
+ * @internal
208
+ */
209
+ export const extractSafePropertiesFromMessage = (
210
+ messageLike: Partial<
211
+ Pick<
212
+ ISequencedDocumentMessage,
213
+ | "clientId"
214
+ | "sequenceNumber"
215
+ | "clientSequenceNumber"
216
+ | "referenceSequenceNumber"
217
+ | "minimumSequenceNumber"
218
+ | "timestamp"
219
+ >
220
+ >,
221
+ ): {
222
+ messageClientId: string | undefined;
223
+ messageSequenceNumber: number | undefined;
224
+ messageClientSequenceNumber: number | undefined;
225
+ messageReferenceSequenceNumber: number | undefined;
226
+ messageMinimumSequenceNumber: number | undefined;
227
+ messageTimestamp: number | undefined;
228
+ } => ({
229
+ messageClientId: messageLike.clientId === null ? "null" : messageLike.clientId,
230
+ messageSequenceNumber: messageLike.sequenceNumber,
231
+ messageClientSequenceNumber: messageLike.clientSequenceNumber,
232
+ messageReferenceSequenceNumber: messageLike.referenceSequenceNumber,
233
+ messageMinimumSequenceNumber: messageLike.minimumSequenceNumber,
234
+ messageTimestamp: messageLike.timestamp,
235
+ });