@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
@@ -5,13 +5,17 @@
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.SampledTelemetryHelper = void 0;
8
- const common_utils_1 = require("@fluidframework/common-utils");
8
+ const client_utils_1 = require("@fluid-internal/client-utils");
9
9
  /**
10
10
  * Helper class that executes a specified code block and writes an
11
- * {@link @fluidframework/common-definitions#ITelemetryPerformanceEvent} to a specified logger every time a specified
12
- * number of executions is reached (or when the class is disposed). The `duration` field in the telemetry event is
13
- * the duration of the latest execution (sample) of the specified function. See the documentation of the
14
- * `includeAggregateMetrics` parameter for additional details that can be included.
11
+ * {@link @fluidframework/core-interfaces#ITelemetryPerformanceEvent} to a specified logger every time a specified
12
+ * number of executions is reached (or when the class is disposed).
13
+ *
14
+ * The `duration` field in the telemetry event is the duration of the latest execution (sample) of the specified
15
+ * function. See the documentation of the `includeAggregateMetrics` parameter for additional details that can be
16
+ * included.
17
+ *
18
+ * @internal
15
19
  */
16
20
  class SampledTelemetryHelper {
17
21
  /**
@@ -42,19 +46,19 @@ class SampledTelemetryHelper {
42
46
  this.measurementsMap = new Map();
43
47
  }
44
48
  /**
45
- * @param codeToMeasure -
46
- * The code to be executed and measured.
47
- * @param bucket -
48
- * A key to track executions of the code block separately. Each different value of this parameter has a separate
49
- * set of executions and metrics tracked by the class. If no such distinction needs to be made, do not provide a
50
- * value.
49
+ * Executes the specified code and keeps track of execution time statistics.
50
+ * If it's been called enough times (the sampleThreshold for the class) then it generates a log message with the necessary information.
51
+ *
52
+ * @param codeToMeasure - The code to be executed and measured.
53
+ * @param bucket - A key to track executions of the code block separately.
54
+ * Each different value of this parameter has a separate set of executions and metrics tracked by the class.
55
+ * If no such distinction needs to be made, do not provide a value.
51
56
  * @returns Whatever the passed-in code block returns.
52
57
  */
53
58
  measure(codeToMeasure, bucket = "") {
54
- var _a, _b, _c;
55
- const start = common_utils_1.performance.now();
59
+ const start = client_utils_1.performance.now();
56
60
  const returnValue = codeToMeasure();
57
- const duration = common_utils_1.performance.now() - start;
61
+ const duration = client_utils_1.performance.now() - start;
58
62
  let m = this.measurementsMap.get(bucket);
59
63
  if (m === undefined) {
60
64
  m = { count: 0, duration: -1 };
@@ -63,9 +67,9 @@ class SampledTelemetryHelper {
63
67
  m.count++;
64
68
  m.duration = duration;
65
69
  if (this.includeAggregateMetrics) {
66
- m.totalDuration = ((_a = m.totalDuration) !== null && _a !== void 0 ? _a : 0) + duration;
67
- m.minDuration = Math.min((_b = m.minDuration) !== null && _b !== void 0 ? _b : duration, duration);
68
- m.maxDuration = Math.max((_c = m.maxDuration) !== null && _c !== void 0 ? _c : 0, duration);
70
+ m.totalDuration = (m.totalDuration ?? 0) + duration;
71
+ m.minDuration = Math.min(m.minDuration ?? duration, duration);
72
+ m.maxDuration = Math.max(m.maxDuration ?? 0, duration);
69
73
  }
70
74
  if (m.count >= this.sampleThreshold) {
71
75
  this.flushBucket(bucket);
@@ -79,13 +83,18 @@ class SampledTelemetryHelper {
79
83
  }
80
84
  if (measurements.count !== 0) {
81
85
  const bucketProperties = this.perBucketProperties.get(bucket);
82
- const telemetryEvent = Object.assign(Object.assign(Object.assign({}, this.eventBase), bucketProperties), measurements);
86
+ const telemetryEvent = {
87
+ ...this.eventBase,
88
+ ...bucketProperties,
89
+ ...measurements,
90
+ };
83
91
  this.logger.sendPerformanceEvent(telemetryEvent);
84
92
  this.measurementsMap.delete(bucket);
85
93
  }
86
94
  }
87
95
  dispose(error) {
88
- this.measurementsMap.forEach((_, k) => this.flushBucket(k));
96
+ for (const [k] of this.measurementsMap.entries())
97
+ this.flushBucket(k);
89
98
  }
90
99
  }
91
100
  exports.SampledTelemetryHelper = SampledTelemetryHelper;
@@ -1 +1 @@
1
- {"version":3,"file":"sampledTelemetryHelper.js","sourceRoot":"","sources":["../src/sampledTelemetryHelper.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AASH,+DAA2D;AAiC3D;;;;;;GAMG;AACF,MAAa,sBAAsB;IAKhC;;;;;;;;;;;;;;;;;OAiBG;IACH,YACqB,SAAiC,EACjC,MAAwB,EACxB,eAAuB,EACvB,0BAAmC,KAAK,EACxC,sBAAsB,IAAI,GAAG,EAAgC;QAJ7D,cAAS,GAAT,SAAS,CAAwB;QACjC,WAAM,GAAN,MAAM,CAAkB;QACxB,oBAAe,GAAf,eAAe,CAAQ;QACvB,4BAAuB,GAAvB,uBAAuB,CAAiB;QACxC,wBAAmB,GAAnB,mBAAmB,CAA0C;QA3BlF,aAAQ,GAAY,KAAK,CAAC;QAET,oBAAe,GAAG,IAAI,GAAG,EAAwB,CAAC;IA0BnE,CAAC;IAED;;;;;;;;OAQG;IACI,OAAO,CAAI,aAAsB,EAAE,SAAiB,EAAE;;QACzD,MAAM,KAAK,GAAG,0BAAW,CAAC,GAAG,EAAE,CAAC;QAChC,MAAM,WAAW,GAAG,aAAa,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,0BAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QAE3C,IAAI,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,CAAC,KAAK,SAAS,EAAE;YACjB,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;SACvC;QACD,CAAC,CAAC,KAAK,EAAE,CAAC;QACV,CAAC,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAEtB,IAAI,IAAI,CAAC,uBAAuB,EAAE;YAC9B,CAAC,CAAC,aAAa,GAAG,CAAC,MAAA,CAAC,CAAC,aAAa,mCAAI,CAAC,CAAC,GAAG,QAAQ,CAAC;YACpD,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,MAAA,CAAC,CAAC,WAAW,mCAAI,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAC9D,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,MAAA,CAAC,CAAC,WAAW,mCAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;SAC1D;QAED,IAAI,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,eAAe,EAAE;YACjC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;SAC5B;QAED,OAAO,WAAW,CAAC;IACvB,CAAC;IAEO,WAAW,CAAC,MAAc;QAC9B,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtD,IAAI,YAAY,KAAK,SAAS,EAAE;YAC5B,OAAO;SACV;QAED,IAAI,YAAY,CAAC,KAAK,KAAK,CAAC,EAAE;YAC1B,MAAM,gBAAgB,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAE9D,MAAM,cAAc,iDACb,IAAI,CAAC,SAAS,GACd,gBAAgB,GAChB,YAAY,CAClB,CAAC;YAEF,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAC;YACjD,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;SACvC;IACL,CAAC;IAEM,OAAO,CAAC,KAAyB;QACpC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IAChE,CAAC;CACJ;AAzFA,wDAyFA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n IDisposable,\n ITelemetryGenericEvent,\n ITelemetryLogger,\n ITelemetryPerformanceEvent,\n ITelemetryProperties,\n} from \"@fluidframework/common-definitions\";\nimport { performance } from \"@fluidframework/common-utils\";\n\ninterface Measurements {\n // The names of the properties in this interface are the ones that will get stamped in the\n // telemetry event, changes should be considered carefully. The optional properties should\n // only be populated if 'includeAggregateMetrics' is true.\n\n /**\n * The duration of the latest execution.\n */\n duration: number;\n\n /**\n * The number of executions since the last time an event was generated.\n */\n count: number;\n\n /**\n * Total duration across all the executions since the last event was generated.\n */\n totalDuration?: number;\n\n /**\n * Min duration across all the executions since the last event was generated.\n */\n minDuration?: number;\n\n /**\n * Max duration across all the executions since the last event was generated.\n */\n maxDuration?: number;\n}\n\n/**\n * Helper class that executes a specified code block and writes an\n * {@link @fluidframework/common-definitions#ITelemetryPerformanceEvent} to a specified logger every time a specified\n * number of executions is reached (or when the class is disposed). The `duration` field in the telemetry event is\n * the duration of the latest execution (sample) of the specified function. See the documentation of the\n * `includeAggregateMetrics` parameter for additional details that can be included.\n */\n export class SampledTelemetryHelper implements IDisposable {\n disposed: boolean = false;\n\n private readonly measurementsMap = new Map<string, Measurements>();\n\n /**\n * @param eventBase -\n * Custom properties to include in the telemetry performance event when it is written.\n * @param logger -\n * The logger to use to write the telemetry performance event.\n * @param sampleThreshold -\n * Telemetry performance events will be generated every time we hit this many executions of the code block.\n * @param includeAggregateMetrics -\n * If set to `true`, the telemetry performance event will include aggregated metrics (total duration, min duration,\n * max duration) for all the executions in between generated events.\n * @param perBucketProperties -\n * Map of strings that represent different buckets (which can be specified when calling the 'measure' method), to\n * properties which should be added to the telemetry event for that bucket. If a bucket being measured does not\n * have an entry in this map, no additional properties will be added to its telemetry events. The following keys are\n * reserved for use by this class: \"duration\", \"count\", \"totalDuration\", \"minDuration\", \"maxDuration\". If any of\n * them is specified as a key in one of the ITelemetryProperties objects in this map, that key-value pair will be\n * ignored.\n */\n public constructor(\n private readonly eventBase: ITelemetryGenericEvent,\n private readonly logger: ITelemetryLogger,\n private readonly sampleThreshold: number,\n private readonly includeAggregateMetrics: boolean = false,\n private readonly perBucketProperties = new Map<string, ITelemetryProperties>()) {\n }\n\n /**\n * @param codeToMeasure -\n * The code to be executed and measured.\n * @param bucket -\n * A key to track executions of the code block separately. Each different value of this parameter has a separate\n * set of executions and metrics tracked by the class. If no such distinction needs to be made, do not provide a\n * value.\n * @returns Whatever the passed-in code block returns.\n */\n public measure<T>(codeToMeasure: () => T, bucket: string = \"\"): T {\n const start = performance.now();\n const returnValue = codeToMeasure();\n const duration = performance.now() - start;\n\n let m = this.measurementsMap.get(bucket);\n if (m === undefined) {\n m = { count: 0, duration: -1 };\n this.measurementsMap.set(bucket, m);\n }\n m.count++;\n m.duration = duration;\n\n if (this.includeAggregateMetrics) {\n m.totalDuration = (m.totalDuration ?? 0) + duration;\n m.minDuration = Math.min(m.minDuration ?? duration, duration);\n m.maxDuration = Math.max(m.maxDuration ?? 0, duration);\n }\n\n if (m.count >= this.sampleThreshold) {\n this.flushBucket(bucket);\n }\n\n return returnValue;\n }\n\n private flushBucket(bucket: string) {\n const measurements = this.measurementsMap.get(bucket);\n if (measurements === undefined) {\n return;\n }\n\n if (measurements.count !== 0) {\n const bucketProperties = this.perBucketProperties.get(bucket);\n\n const telemetryEvent: ITelemetryPerformanceEvent = {\n ...this.eventBase,\n ...bucketProperties, // If the bucket doesn't exist and this is undefined, things work as expected\n ...measurements,\n };\n\n this.logger.sendPerformanceEvent(telemetryEvent);\n this.measurementsMap.delete(bucket);\n }\n }\n\n public dispose(error?: Error | undefined): void {\n this.measurementsMap.forEach((_, k) => this.flushBucket(k));\n }\n}\n"]}
1
+ {"version":3,"file":"sampledTelemetryHelper.js","sourceRoot":"","sources":["../src/sampledTelemetryHelper.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAQH,+DAA2D;AAqC3D;;;;;;;;;;GAUG;AACH,MAAa,sBAAsB;IAKlC;;;;;;;;;;;;;;;;;OAiBG;IACH,YACkB,SAAiC,EACjC,MAA2B,EAC3B,eAAuB,EACvB,0BAAmC,KAAK,EACxC,sBAAsB,IAAI,GAAG,EAAgC;QAJ7D,cAAS,GAAT,SAAS,CAAwB;QACjC,WAAM,GAAN,MAAM,CAAqB;QAC3B,oBAAe,GAAf,eAAe,CAAQ;QACvB,4BAAuB,GAAvB,uBAAuB,CAAiB;QACxC,wBAAmB,GAAnB,mBAAmB,CAA0C;QA3B/E,aAAQ,GAAY,KAAK,CAAC;QAET,oBAAe,GAAG,IAAI,GAAG,EAAwB,CAAC;IA0BhE,CAAC;IAEJ;;;;;;;;;OASG;IACI,OAAO,CAAI,aAAsB,EAAE,SAAiB,EAAE;QAC5D,MAAM,KAAK,GAAG,0BAAW,CAAC,GAAG,EAAE,CAAC;QAChC,MAAM,WAAW,GAAG,aAAa,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,0BAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QAE3C,IAAI,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,CAAC,KAAK,SAAS,EAAE;YACpB,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;SACpC;QACD,CAAC,CAAC,KAAK,EAAE,CAAC;QACV,CAAC,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAEtB,IAAI,IAAI,CAAC,uBAAuB,EAAE;YACjC,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,GAAG,QAAQ,CAAC;YACpD,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,IAAI,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAC9D,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;SACvD;QAED,IAAI,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,eAAe,EAAE;YACpC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;SACzB;QAED,OAAO,WAAW,CAAC;IACpB,CAAC;IAEO,WAAW,CAAC,MAAc;QACjC,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtD,IAAI,YAAY,KAAK,SAAS,EAAE;YAC/B,OAAO;SACP;QAED,IAAI,YAAY,CAAC,KAAK,KAAK,CAAC,EAAE;YAC7B,MAAM,gBAAgB,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAE9D,MAAM,cAAc,GAA+B;gBAClD,GAAG,IAAI,CAAC,SAAS;gBACjB,GAAG,gBAAgB;gBACnB,GAAG,YAAY;aACf,CAAC;YAEF,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAC;YACjD,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;SACpC;IACF,CAAC;IAEM,OAAO,CAAC,KAAyB;QACvC,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE;YAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IACvE,CAAC;CACD;AA1FD,wDA0FC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tITelemetryGenericEvent,\n\tITelemetryPerformanceEvent,\n\tITelemetryProperties,\n\tIDisposable,\n} from \"@fluidframework/core-interfaces\";\nimport { performance } from \"@fluid-internal/client-utils\";\nimport { ITelemetryLoggerExt } from \"./telemetryTypes\";\n\n/**\n * @privateRemarks\n *\n * The names of the properties in this interface are the ones that will get stamped in the\n * telemetry event, changes should be considered carefully. The optional properties should\n * only be populated if 'includeAggregateMetrics' is true.\n */\ninterface Measurements {\n\t/**\n\t * The duration of the latest execution.\n\t */\n\tduration: number;\n\n\t/**\n\t * The number of executions since the last time an event was generated.\n\t */\n\tcount: number;\n\n\t/**\n\t * Total duration across all the executions since the last event was generated.\n\t */\n\ttotalDuration?: number;\n\n\t/**\n\t * Min duration across all the executions since the last event was generated.\n\t */\n\tminDuration?: number;\n\n\t/**\n\t * Max duration across all the executions since the last event was generated.\n\t */\n\tmaxDuration?: number;\n}\n\n/**\n * Helper class that executes a specified code block and writes an\n * {@link @fluidframework/core-interfaces#ITelemetryPerformanceEvent} to a specified logger every time a specified\n * number of executions is reached (or when the class is disposed).\n *\n * The `duration` field in the telemetry event is the duration of the latest execution (sample) of the specified\n * function. See the documentation of the `includeAggregateMetrics` parameter for additional details that can be\n * included.\n *\n * @internal\n */\nexport class SampledTelemetryHelper implements IDisposable {\n\tdisposed: boolean = false;\n\n\tprivate readonly measurementsMap = new Map<string, Measurements>();\n\n\t/**\n\t * @param eventBase -\n\t * Custom properties to include in the telemetry performance event when it is written.\n\t * @param logger -\n\t * The logger to use to write the telemetry performance event.\n\t * @param sampleThreshold -\n\t * Telemetry performance events will be generated every time we hit this many executions of the code block.\n\t * @param includeAggregateMetrics -\n\t * If set to `true`, the telemetry performance event will include aggregated metrics (total duration, min duration,\n\t * max duration) for all the executions in between generated events.\n\t * @param perBucketProperties -\n\t * Map of strings that represent different buckets (which can be specified when calling the 'measure' method), to\n\t * properties which should be added to the telemetry event for that bucket. If a bucket being measured does not\n\t * have an entry in this map, no additional properties will be added to its telemetry events. The following keys are\n\t * reserved for use by this class: \"duration\", \"count\", \"totalDuration\", \"minDuration\", \"maxDuration\". If any of\n\t * them is specified as a key in one of the ITelemetryProperties objects in this map, that key-value pair will be\n\t * ignored.\n\t */\n\tpublic constructor(\n\t\tprivate readonly eventBase: ITelemetryGenericEvent,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t\tprivate readonly sampleThreshold: number,\n\t\tprivate readonly includeAggregateMetrics: boolean = false,\n\t\tprivate readonly perBucketProperties = new Map<string, ITelemetryProperties>(),\n\t) {}\n\n\t/**\n\t * Executes the specified code and keeps track of execution time statistics.\n\t * If it's been called enough times (the sampleThreshold for the class) then it generates a log message with the necessary information.\n\t *\n\t * @param codeToMeasure - The code to be executed and measured.\n\t * @param bucket - A key to track executions of the code block separately.\n\t * Each different value of this parameter has a separate set of executions and metrics tracked by the class.\n\t * If no such distinction needs to be made, do not provide a value.\n\t * @returns Whatever the passed-in code block returns.\n\t */\n\tpublic measure<T>(codeToMeasure: () => T, bucket: string = \"\"): T {\n\t\tconst start = performance.now();\n\t\tconst returnValue = codeToMeasure();\n\t\tconst duration = performance.now() - start;\n\n\t\tlet m = this.measurementsMap.get(bucket);\n\t\tif (m === undefined) {\n\t\t\tm = { count: 0, duration: -1 };\n\t\t\tthis.measurementsMap.set(bucket, m);\n\t\t}\n\t\tm.count++;\n\t\tm.duration = duration;\n\n\t\tif (this.includeAggregateMetrics) {\n\t\t\tm.totalDuration = (m.totalDuration ?? 0) + duration;\n\t\t\tm.minDuration = Math.min(m.minDuration ?? duration, duration);\n\t\t\tm.maxDuration = Math.max(m.maxDuration ?? 0, duration);\n\t\t}\n\n\t\tif (m.count >= this.sampleThreshold) {\n\t\t\tthis.flushBucket(bucket);\n\t\t}\n\n\t\treturn returnValue;\n\t}\n\n\tprivate flushBucket(bucket: string): void {\n\t\tconst measurements = this.measurementsMap.get(bucket);\n\t\tif (measurements === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (measurements.count !== 0) {\n\t\t\tconst bucketProperties = this.perBucketProperties.get(bucket);\n\n\t\t\tconst telemetryEvent: ITelemetryPerformanceEvent = {\n\t\t\t\t...this.eventBase,\n\t\t\t\t...bucketProperties, // If the bucket doesn't exist and this is undefined, things work as expected\n\t\t\t\t...measurements,\n\t\t\t};\n\n\t\t\tthis.logger.sendPerformanceEvent(telemetryEvent);\n\t\t\tthis.measurementsMap.delete(bucket);\n\t\t}\n\t}\n\n\tpublic dispose(error?: Error | undefined): void {\n\t\tfor (const [k] of this.measurementsMap.entries()) this.flushBucket(k);\n\t}\n}\n"]}
@@ -0,0 +1,290 @@
1
+ /// <reference types="node" />
2
+
3
+ import { EventEmitter } from 'events';
4
+ import { EventEmitterEventType } from '@fluid-internal/client-utils';
5
+ import { IConfigProviderBase } from '@fluidframework/core-interfaces';
6
+ import { IDisposable } from '@fluidframework/core-interfaces';
7
+ import { IErrorBase } from '@fluidframework/core-interfaces';
8
+ import { IEvent } from '@fluidframework/core-interfaces';
9
+ import { IGenericError } from '@fluidframework/core-interfaces';
10
+ import { ILoggingError } from '@fluidframework/core-interfaces';
11
+ import { ISequencedDocumentMessage } from '@fluidframework/protocol-definitions';
12
+ import { ITelemetryBaseEvent } from '@fluidframework/core-interfaces';
13
+ import { ITelemetryBaseLogger } from '@fluidframework/core-interfaces';
14
+ import { ITelemetryBaseProperties } from '@fluidframework/core-interfaces';
15
+ import { ITelemetryErrorEvent } from '@fluidframework/core-interfaces';
16
+ import { ITelemetryGenericEvent } from '@fluidframework/core-interfaces';
17
+ import { ITelemetryPerformanceEvent } from '@fluidframework/core-interfaces';
18
+ import { ITelemetryProperties } from '@fluidframework/core-interfaces';
19
+ import { IUsageError } from '@fluidframework/core-interfaces';
20
+ import { Lazy } from '@fluidframework/core-utils';
21
+ import { LogLevel } from '@fluidframework/core-interfaces';
22
+ import { Tagged } from '@fluidframework/core-interfaces';
23
+ import { TelemetryBaseEventPropertyType } from '@fluidframework/core-interfaces';
24
+ import { TelemetryEventPropertyType } from '@fluidframework/core-interfaces';
25
+ import { TypedEventEmitter } from '@fluid-internal/client-utils';
26
+
27
+ /* Excluded from this release type: connectedEventName */
28
+
29
+ /**
30
+ * Create a child logger based on the provided props object.
31
+ *
32
+ * @remarks
33
+ * Passing in no props object (i.e. undefined) will return a logger that is effectively a no-op.
34
+ *
35
+ * @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.
36
+ *
37
+ * @alpha
38
+ */
39
+ export declare function createChildLogger(props?: {
40
+ logger?: ITelemetryBaseLogger;
41
+ namespace?: string;
42
+ properties?: ITelemetryLoggerPropertyBags;
43
+ }): ITelemetryLoggerExt;
44
+
45
+ /* Excluded from this release type: createChildMonitoringContext */
46
+
47
+ /* Excluded from this release type: createMultiSinkLogger */
48
+
49
+ /* Excluded from this release type: createSampledLogger */
50
+
51
+ /* Excluded from this release type: DataCorruptionError */
52
+
53
+ /* Excluded from this release type: DataProcessingError */
54
+
55
+ /* Excluded from this release type: disconnectedEventName */
56
+
57
+ /**
58
+ * Event Emitter helper class
59
+ *
60
+ * @remarks
61
+ * Any exceptions thrown by listeners will be caught and raised through "error" event.
62
+ * Any exception thrown by "error" listeners will propagate to the caller.
63
+ * @privateRemarks
64
+ * This probably doesn't belong in this package, as it is not telemetry-specific, and is really only intended for internal fluid-framework use.
65
+ * We should consider moving it to the `core-utils` package.
66
+ * @public
67
+ */
68
+ export declare class EventEmitterWithErrorHandling<TEvent extends IEvent = IEvent> extends TypedEventEmitter<TEvent> {
69
+ private readonly errorHandler;
70
+ constructor(errorHandler: (eventName: EventEmitterEventType, error: any) => void);
71
+ emit(event: EventEmitterEventType, ...args: unknown[]): boolean;
72
+ }
73
+
74
+ /* Excluded from this release type: eventNamespaceSeparator */
75
+
76
+ /* Excluded from this release type: extractLogSafeErrorProperties */
77
+
78
+ /* Excluded from this release type: extractSafePropertiesFromMessage */
79
+
80
+ /* Excluded from this release type: formatTick */
81
+
82
+ /* Excluded from this release type: generateErrorWithStack */
83
+
84
+ /* Excluded from this release type: generateStack */
85
+
86
+ /* Excluded from this release type: GenericError */
87
+
88
+ /* Excluded from this release type: getCircularReplacer */
89
+
90
+ /* Excluded from this release type: hasErrorInstanceId */
91
+
92
+ /* Excluded from this release type: IConfigProvider */
93
+
94
+ /* Excluded from this release type: IEventSampler */
95
+
96
+ /* Excluded from this release type: IFluidErrorAnnotations */
97
+
98
+ /* Excluded from this release type: IFluidErrorBase */
99
+
100
+ /* Excluded from this release type: IGenericError */
101
+
102
+ /* Excluded from this release type: ILoggingError */
103
+
104
+ /* Excluded from this release type: IPerformanceEventMarkers */
105
+
106
+ /* Excluded from this release type: ISampledTelemetryLogger */
107
+
108
+ /* Excluded from this release type: isExternalError */
109
+
110
+ /* Excluded from this release type: isFluidError */
111
+
112
+ /* Excluded from this release type: isILoggingError */
113
+
114
+ /* Excluded from this release type: isTaggedTelemetryPropertyValue */
115
+
116
+ /* Excluded from this release type: isValidLegacyError */
117
+
118
+ /* Excluded from this release type: ITaggedTelemetryPropertyTypeExt */
119
+
120
+ /**
121
+ * Error telemetry event.
122
+ * @remarks Maps to category = "error"
123
+ * @public
124
+ */
125
+ export declare interface ITelemetryErrorEventExt extends ITelemetryPropertiesExt {
126
+ eventName: string;
127
+ }
128
+
129
+ /* Excluded from this release type: ITelemetryEventExt */
130
+
131
+ /**
132
+ * Informational (non-error) telemetry event
133
+ * @remarks Maps to category = "generic"
134
+ * @public
135
+ */
136
+ export declare interface ITelemetryGenericEventExt extends ITelemetryPropertiesExt {
137
+ eventName: string;
138
+ category?: TelemetryEventCategory;
139
+ }
140
+
141
+ /**
142
+ * An extended {@link @fluidframework/core-interfaces#ITelemetryBaseLogger} which allows for more lenient event types.
143
+ *
144
+ * @remarks
145
+ * This interface is meant to be used internally within the Fluid Framework,
146
+ * and `ITelemetryBaseLogger` should be used when loggers are passed between layers.
147
+ * @public
148
+ */
149
+ export declare interface ITelemetryLoggerExt extends ITelemetryBaseLogger {
150
+ /**
151
+ * Send information telemetry event
152
+ * @param event - Event to send
153
+ * @param error - optional error object to log
154
+ * @param logLevel - optional level of the log.
155
+ */
156
+ sendTelemetryEvent(event: ITelemetryGenericEventExt, error?: unknown, logLevel?: typeof LogLevel.verbose | typeof LogLevel.default): void;
157
+ /**
158
+ * Send error telemetry event
159
+ * @param event - Event to send
160
+ * @param error - optional error object to log
161
+ */
162
+ sendErrorEvent(event: ITelemetryErrorEventExt, error?: unknown): void;
163
+ /**
164
+ * Send performance telemetry event
165
+ * @param event - Event to send
166
+ * @param error - optional error object to log
167
+ * @param logLevel - optional level of the log.
168
+ */
169
+ sendPerformanceEvent(event: ITelemetryPerformanceEventExt, error?: unknown, logLevel?: typeof LogLevel.verbose | typeof LogLevel.default): void;
170
+ }
171
+
172
+ /**
173
+ * @alpha
174
+ */
175
+ export declare interface ITelemetryLoggerPropertyBag {
176
+ [index: string]: TelemetryEventPropertyTypes | (() => TelemetryEventPropertyTypes);
177
+ }
178
+
179
+ /**
180
+ * @alpha
181
+ */
182
+ export declare interface ITelemetryLoggerPropertyBags {
183
+ all?: ITelemetryLoggerPropertyBag;
184
+ error?: ITelemetryLoggerPropertyBag;
185
+ }
186
+
187
+ /**
188
+ * Performance telemetry event.
189
+ * @remarks Maps to category = "performance"
190
+ * @public
191
+ */
192
+ export declare interface ITelemetryPerformanceEventExt extends ITelemetryGenericEventExt {
193
+ duration?: number;
194
+ }
195
+
196
+ /**
197
+ * JSON-serializable properties, which will be logged with telemetry.
198
+ * @public
199
+ */
200
+ export declare interface ITelemetryPropertiesExt {
201
+ [index: string]: TelemetryEventPropertyTypeExt | Tagged<TelemetryEventPropertyTypeExt>;
202
+ }
203
+
204
+ /* Excluded from this release type: IUsageError */
205
+
206
+ /* Excluded from this release type: Lazy */
207
+
208
+ /* Excluded from this release type: loggerToMonitoringContext */
209
+
210
+ /* Excluded from this release type: LoggingError */
211
+
212
+ /* Excluded from this release type: logIfFalse */
213
+
214
+ /* Excluded from this release type: mixinMonitoringContext */
215
+
216
+ /* Excluded from this release type: MockLogger */
217
+
218
+ /* Excluded from this release type: MonitoringContext */
219
+
220
+ /* Excluded from this release type: MultiSinkLoggerProperties */
221
+
222
+ /* Excluded from this release type: NORMALIZED_ERROR_TYPE */
223
+
224
+ /* Excluded from this release type: normalizeError */
225
+
226
+ /* Excluded from this release type: numberFromString */
227
+
228
+ /* Excluded from this release type: overwriteStack */
229
+
230
+ /* Excluded from this release type: PerformanceEvent */
231
+
232
+ /* Excluded from this release type: raiseConnectedEvent */
233
+
234
+ /* Excluded from this release type: safeRaiseEvent */
235
+
236
+ /* Excluded from this release type: SampledTelemetryHelper */
237
+
238
+ /* Excluded from this release type: sessionStorageConfigProvider */
239
+
240
+ /* Excluded from this release type: tagCodeArtifacts */
241
+
242
+ /* Excluded from this release type: tagData */
243
+
244
+ /* Excluded from this release type: TaggedLoggerAdapter */
245
+
246
+ /* Excluded from this release type: TelemetryDataTag */
247
+
248
+ /**
249
+ * The categories FF uses when instrumenting the code.
250
+ *
251
+ * generic - Informational log event
252
+ *
253
+ * error - Error log event, ideally 0 of these are logged during a session
254
+ *
255
+ * performance - Includes duration, and often has _start, _end, or _cancel suffixes for activity tracking
256
+ * @public
257
+ */
258
+ export declare type TelemetryEventCategory = "generic" | "error" | "performance";
259
+
260
+ /**
261
+ * Property types that can be logged.
262
+ *
263
+ * @remarks
264
+ * Includes extra types beyond {@link @fluidframework/core-interfaces#TelemetryBaseEventPropertyType}, which must be
265
+ * converted before sending to a base logger.
266
+ * @public
267
+ */
268
+ export declare type TelemetryEventPropertyTypeExt = string | number | boolean | undefined | (string | number | boolean)[] | {
269
+ [key: string]: // Flat objects can have the same properties as the event itself
270
+ string | number | boolean | undefined | (string | number | boolean)[];
271
+ };
272
+
273
+ /**
274
+ * @alpha
275
+ */
276
+ export declare type TelemetryEventPropertyTypes = ITelemetryBaseProperties[string];
277
+
278
+ /* Excluded from this release type: TelemetryNullLogger */
279
+
280
+ /* Excluded from this release type: ThresholdCounter */
281
+
282
+ /* Excluded from this release type: UsageError */
283
+
284
+ /* Excluded from this release type: validatePrecondition */
285
+
286
+ /* Excluded from this release type: wrapError */
287
+
288
+ /* Excluded from this release type: wrapErrorAndLog */
289
+
290
+ export { }