@fluidframework/telemetry-utils 2.0.0-rc.2.0.1 → 2.0.0-rc.3.0.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.
Files changed (132) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/api-report/telemetry-utils.api.md +6 -6
  3. package/dist/config.d.ts +2 -2
  4. package/dist/config.d.ts.map +1 -1
  5. package/dist/config.js +6 -2
  6. package/dist/config.js.map +1 -1
  7. package/dist/error.d.ts +4 -2
  8. package/dist/error.d.ts.map +1 -1
  9. package/dist/error.js +5 -5
  10. package/dist/error.js.map +1 -1
  11. package/dist/errorLogging.d.ts +3 -2
  12. package/dist/errorLogging.d.ts.map +1 -1
  13. package/dist/errorLogging.js.map +1 -1
  14. package/dist/eventEmitterWithErrorHandling.d.ts +1 -1
  15. package/dist/eventEmitterWithErrorHandling.d.ts.map +1 -1
  16. package/dist/eventEmitterWithErrorHandling.js +2 -2
  17. package/dist/eventEmitterWithErrorHandling.js.map +1 -1
  18. package/dist/events.d.ts +1 -1
  19. package/dist/events.d.ts.map +1 -1
  20. package/dist/events.js.map +1 -1
  21. package/dist/fluidErrorBase.d.ts.map +1 -1
  22. package/dist/fluidErrorBase.js.map +1 -1
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +2 -2
  25. package/dist/index.js.map +1 -1
  26. package/dist/legacy.d.ts +28 -0
  27. package/dist/logger.d.ts +2 -2
  28. package/dist/logger.d.ts.map +1 -1
  29. package/dist/logger.js +1 -1
  30. package/dist/logger.js.map +1 -1
  31. package/dist/mockLogger.d.ts +1 -1
  32. package/dist/mockLogger.d.ts.map +1 -1
  33. package/dist/mockLogger.js +3 -3
  34. package/dist/mockLogger.js.map +1 -1
  35. package/dist/public.d.ts +20 -0
  36. package/dist/sampledTelemetryHelper.d.ts +2 -2
  37. package/dist/sampledTelemetryHelper.d.ts.map +1 -1
  38. package/dist/sampledTelemetryHelper.js.map +1 -1
  39. package/dist/utils.d.ts +4 -0
  40. package/dist/utils.d.ts.map +1 -1
  41. package/dist/utils.js +4 -0
  42. package/dist/utils.js.map +1 -1
  43. package/internal.d.ts +11 -0
  44. package/legacy.d.ts +11 -0
  45. package/lib/config.d.ts +2 -2
  46. package/lib/config.d.ts.map +1 -1
  47. package/lib/config.js +5 -1
  48. package/lib/config.js.map +1 -1
  49. package/lib/error.d.ts +4 -2
  50. package/lib/error.d.ts.map +1 -1
  51. package/lib/error.js +1 -1
  52. package/lib/error.js.map +1 -1
  53. package/lib/errorLogging.d.ts +3 -2
  54. package/lib/errorLogging.d.ts.map +1 -1
  55. package/lib/errorLogging.js.map +1 -1
  56. package/lib/eventEmitterWithErrorHandling.d.ts +1 -1
  57. package/lib/eventEmitterWithErrorHandling.d.ts.map +1 -1
  58. package/lib/eventEmitterWithErrorHandling.js.map +1 -1
  59. package/lib/events.d.ts +1 -1
  60. package/lib/events.d.ts.map +1 -1
  61. package/lib/events.js.map +1 -1
  62. package/lib/fluidErrorBase.d.ts.map +1 -1
  63. package/lib/fluidErrorBase.js.map +1 -1
  64. package/lib/index.d.ts.map +1 -1
  65. package/lib/index.js.map +1 -1
  66. package/lib/legacy.d.ts +28 -0
  67. package/lib/logger.d.ts +2 -2
  68. package/lib/logger.d.ts.map +1 -1
  69. package/lib/logger.js +2 -2
  70. package/lib/logger.js.map +1 -1
  71. package/lib/mockLogger.d.ts +1 -1
  72. package/lib/mockLogger.d.ts.map +1 -1
  73. package/lib/mockLogger.js +2 -2
  74. package/lib/mockLogger.js.map +1 -1
  75. package/lib/public.d.ts +20 -0
  76. package/lib/sampledTelemetryHelper.d.ts +2 -2
  77. package/lib/sampledTelemetryHelper.d.ts.map +1 -1
  78. package/lib/sampledTelemetryHelper.js.map +1 -1
  79. package/lib/utils.d.ts +4 -0
  80. package/lib/utils.d.ts.map +1 -1
  81. package/lib/utils.js +4 -0
  82. package/lib/utils.js.map +1 -1
  83. package/package.json +27 -48
  84. package/src/config.ts +5 -3
  85. package/src/error.ts +4 -4
  86. package/src/errorLogging.ts +6 -8
  87. package/src/eventEmitterWithErrorHandling.ts +2 -1
  88. package/src/events.ts +2 -1
  89. package/src/fluidErrorBase.ts +1 -0
  90. package/src/index.ts +1 -0
  91. package/src/logger.ts +7 -6
  92. package/src/mockLogger.ts +4 -3
  93. package/src/sampledTelemetryHelper.ts +3 -2
  94. package/src/utils.ts +2 -0
  95. package/api-extractor-cjs.json +0 -8
  96. package/dist/telemetry-utils-alpha.d.ts +0 -282
  97. package/dist/telemetry-utils-beta.d.ts +0 -239
  98. package/dist/telemetry-utils-public.d.ts +0 -239
  99. package/dist/telemetry-utils-untrimmed.d.ts +0 -1077
  100. package/lib/telemetry-utils-alpha.d.ts +0 -282
  101. package/lib/telemetry-utils-beta.d.ts +0 -239
  102. package/lib/telemetry-utils-public.d.ts +0 -239
  103. package/lib/telemetry-utils-untrimmed.d.ts +0 -1077
  104. package/lib/test/EventEmitterWithErrorHandling.spec.js +0 -86
  105. package/lib/test/EventEmitterWithErrorHandling.spec.js.map +0 -1
  106. package/lib/test/childLogger.spec.js +0 -233
  107. package/lib/test/childLogger.spec.js.map +0 -1
  108. package/lib/test/config.spec.js +0 -229
  109. package/lib/test/config.spec.js.map +0 -1
  110. package/lib/test/error.spec.js +0 -161
  111. package/lib/test/error.spec.js.map +0 -1
  112. package/lib/test/errorLogging.spec.js +0 -801
  113. package/lib/test/errorLogging.spec.js.map +0 -1
  114. package/lib/test/errorTypeLoggingTest.spec.js +0 -107
  115. package/lib/test/errorTypeLoggingTest.spec.js.map +0 -1
  116. package/lib/test/mockLogger.spec.js +0 -164
  117. package/lib/test/mockLogger.spec.js.map +0 -1
  118. package/lib/test/multiSinkLogger.spec.js +0 -84
  119. package/lib/test/multiSinkLogger.spec.js.map +0 -1
  120. package/lib/test/performanceEvent.spec.js +0 -86
  121. package/lib/test/performanceEvent.spec.js.map +0 -1
  122. package/lib/test/sampledTelemetryHelper.spec.js +0 -169
  123. package/lib/test/sampledTelemetryHelper.spec.js.map +0 -1
  124. package/lib/test/telemetryLogger.spec.js +0 -357
  125. package/lib/test/telemetryLogger.spec.js.map +0 -1
  126. package/lib/test/thresholdCounter.spec.js +0 -51
  127. package/lib/test/thresholdCounter.spec.js.map +0 -1
  128. package/lib/test/types/validateTelemetryUtilsPrevious.generated.js +0 -132
  129. package/lib/test/types/validateTelemetryUtilsPrevious.generated.js.map +0 -1
  130. package/lib/test/utils.spec.js +0 -284
  131. package/lib/test/utils.spec.js.map +0 -1
  132. /package/{dist → lib}/tsdoc-metadata.json +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"file":"multiSinkLogger.spec.js","sourceRoot":"","sources":["../../src/test/multiSinkLogger.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\nimport { LogLevel } from \"@fluidframework/core-interfaces\";\nimport { MultiSinkLogger, createChildLogger, createMultiSinkLogger } from \"../logger.js\";\nimport { MockLogger } from \"../mockLogger.js\";\n\ndescribe(\"MultiSinkLogger\", () => {\n\tit(\"Pushes logs to all sinks\", () => {\n\t\tconst logger1 = new MockLogger();\n\t\tconst logger2 = new MockLogger();\n\t\tconst multiSink = createMultiSinkLogger({ loggers: [logger1, logger2] });\n\t\tmultiSink.sendTelemetryEvent({ eventName: \"test\" });\n\n\t\tlogger1.assertMatch([{ category: \"generic\", eventName: \"test\" }]);\n\t\tlogger2.assertMatch([{ category: \"generic\", eventName: \"test\" }]);\n\t});\n\n\tit(\"Appends namespace to all logged events\", () => {\n\t\tconst logger1 = new MockLogger();\n\t\tconst logger2 = new MockLogger();\n\t\tconst multiSink = createMultiSinkLogger({ loggers: [logger1, logger2], namespace: \"test\" });\n\t\tmultiSink.sendTelemetryEvent({ eventName: \"test\" });\n\n\t\tlogger1.assertMatch([{ category: \"generic\", eventName: \"test:test\" }]);\n\t\tlogger2.assertMatch([{ category: \"generic\", eventName: \"test:test\" }]);\n\t});\n\n\tit(\"Propagates Properties to sinks when tryInheritProperties true\", () => {\n\t\tconst logger1 = new MockLogger();\n\t\tconst logger2 = new MockLogger();\n\t\tconst multiSink = createMultiSinkLogger({\n\t\t\tloggers: [\n\t\t\t\tcreateChildLogger({ logger: logger1, properties: { all: { test: true } } }),\n\t\t\t\tlogger2,\n\t\t\t],\n\t\t\ttryInheritProperties: true,\n\t\t});\n\t\tmultiSink.sendTelemetryEvent({ eventName: \"test\" });\n\n\t\tlogger1.assertMatch([{ category: \"generic\", eventName: \"test\", test: true }]);\n\t\tlogger2.assertMatch([{ category: \"generic\", eventName: \"test\", test: true }]);\n\t});\n\n\tit(\"Does not Propagates Properties to sinks when tryInheritProperties not set\", () => {\n\t\tconst logger1 = new MockLogger();\n\t\tconst logger2 = new MockLogger();\n\t\tconst multiSink = createMultiSinkLogger({\n\t\t\tloggers: [\n\t\t\t\tcreateChildLogger({ logger: logger1, properties: { all: { test: true } } }),\n\t\t\t\tlogger2,\n\t\t\t],\n\t\t});\n\t\tmultiSink.sendTelemetryEvent({ eventName: \"test\" });\n\n\t\tlogger1.assertMatch([{ category: \"generic\", eventName: \"test\", test: true }]);\n\t\tlogger2.assertMatch([{ category: \"generic\", eventName: \"test\" }]);\n\t});\n\n\tit(\"MultiSink logger set the logLevel to min logLevel of all loggers\", () => {\n\t\tconst logger1 = new MockLogger(LogLevel.error);\n\t\tconst logger2 = new MockLogger(LogLevel.default);\n\t\tconst multiSink = createMultiSinkLogger({\n\t\t\tloggers: [createChildLogger({ logger: logger1 }), logger2],\n\t\t});\n\t\tassert.strictEqual(\n\t\t\tmultiSink.minLogLevel,\n\t\t\tLogLevel.default,\n\t\t\t\"Min loglevel should be set correctly\",\n\t\t);\n\n\t\t// Add logger with a log level as verbose\n\t\t(multiSink as MultiSinkLogger).addLogger(new MockLogger(LogLevel.verbose));\n\t\tassert.strictEqual(\n\t\t\tmultiSink.minLogLevel,\n\t\t\tLogLevel.verbose,\n\t\t\t\"Min loglevel should be set correctly to verbose\",\n\t\t);\n\t});\n\n\tit(\"MultiSink logger set the logLevel to default if not supplied with a log level\", () => {\n\t\tconst logger1 = new MockLogger();\n\t\tconst logger2 = new MockLogger();\n\t\tconst multiSink = createMultiSinkLogger({\n\t\t\tloggers: [createChildLogger({ logger: logger1 }), logger2],\n\t\t});\n\t\tassert.strictEqual(\n\t\t\tmultiSink.minLogLevel,\n\t\t\tLogLevel.default,\n\t\t\t\"Min loglevel should be set correctly to default\",\n\t\t);\n\t});\n\n\tit(\"MultiSink logger set the logLevel correctly when no initial loggers are supplied\", () => {\n\t\tconst multiSink = createMultiSinkLogger({\n\t\t\tloggers: [],\n\t\t});\n\n\t\t(multiSink as MultiSinkLogger).addLogger(new MockLogger());\n\t\tassert.strictEqual(\n\t\t\tmultiSink.minLogLevel,\n\t\t\tLogLevel.default,\n\t\t\t\"Min loglevel should be set correctly to default\",\n\t\t);\n\n\t\t(multiSink as MultiSinkLogger).addLogger(new MockLogger(LogLevel.default));\n\t\tassert.strictEqual(\n\t\t\tmultiSink.minLogLevel,\n\t\t\tLogLevel.default,\n\t\t\t\"Min loglevel should be set correctly to default\",\n\t\t);\n\n\t\t(multiSink as MultiSinkLogger).addLogger(new MockLogger(LogLevel.verbose));\n\t\tassert.strictEqual(\n\t\t\tmultiSink.minLogLevel,\n\t\t\tLogLevel.verbose,\n\t\t\t\"Min loglevel should be set correctly to verbose\",\n\t\t);\n\t});\n});\n"]}
@@ -1,86 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- import { strict as assert } from "node:assert";
6
- import { TelemetryLogger, PerformanceEvent } from "../logger.js";
7
- class MockLogger extends TelemetryLogger {
8
- constructor() {
9
- super();
10
- this.errorsLogged = 0;
11
- this.eventsLogged = 0;
12
- }
13
- send(event) {
14
- if (event.category === "error") {
15
- ++this.errorsLogged;
16
- }
17
- ++this.eventsLogged;
18
- }
19
- }
20
- describe("PerformanceEvent", () => {
21
- let logger;
22
- let callbackCalls = 0;
23
- const callback = () => {
24
- callbackCalls++;
25
- };
26
- const asyncCallback = async (event) => {
27
- const outerPromise = new Promise((resolve, reject) => {
28
- Promise.resolve("A")
29
- .finally(() => {
30
- reject(new Error("B"));
31
- })
32
- .then((val) => {
33
- event.end({ val });
34
- resolve("C");
35
- })
36
- .catch(() => { });
37
- });
38
- callbackCalls++;
39
- return outerPromise.catch(() => { });
40
- };
41
- beforeEach(() => {
42
- callbackCalls = 0;
43
- logger = new MockLogger();
44
- });
45
- it("Cancel then End", async () => {
46
- await PerformanceEvent.timedExecAsync(logger, { eventName: "Testing" }, asyncCallback, { start: true, end: true, cancel: "generic" }, true);
47
- assert.equal(logger.errorsLogged, 0, "Shouldn't have logged any errors");
48
- });
49
- describe("Event sampling", () => {
50
- it("Events are logged at least once", async () => {
51
- await PerformanceEvent.timedExecAsync(logger, { eventName: "TestingAsyncOnce" }, asyncCallback, { start: true, end: true, cancel: "generic" }, true, 100);
52
- PerformanceEvent.timedExec(logger, { eventName: "TestingSyncOnce" }, callback, { start: true, end: true, cancel: "generic" }, 100);
53
- assert.equal(callbackCalls, 2);
54
- assert.equal(logger.eventsLogged, 4);
55
- });
56
- it("No sampling by default", async () => {
57
- await Promise.all(Array.from({ length: 100 }).map(async (_) => PerformanceEvent.timedExecAsync(logger, { eventName: "TestingAsync" }, asyncCallback, { start: true, end: true, cancel: "generic" }, true)));
58
- Array.from({ length: 100 }).map((_) => PerformanceEvent.timedExec(logger, { eventName: "TestingSync" }, callback, {
59
- start: true,
60
- end: true,
61
- cancel: "generic",
62
- }));
63
- assert.equal(callbackCalls, 200);
64
- assert.equal(logger.eventsLogged, 200 * 2);
65
- });
66
- it("Sampling for async", async () => {
67
- await Promise.all(Array.from({ length: 100 }).map(async (_) => PerformanceEvent.timedExecAsync(logger, { eventName: "TestingAsync" }, asyncCallback, { start: true, end: true, cancel: "generic" }, true, 20)));
68
- assert.equal(callbackCalls, 100);
69
- assert.equal(logger.eventsLogged, 10, "With sampling threshold of 20, expecting 100 calls to produce 10 events (5 start, 5 cancel)");
70
- // Event with a different category gets logged
71
- await PerformanceEvent.timedExecAsync(logger, { eventName: "TestingAsync", category: "error" }, asyncCallback, { start: true, end: true, cancel: "generic" }, true, 20);
72
- assert.equal(callbackCalls, 101);
73
- assert.equal(logger.eventsLogged, 12, "Expecting two extra events");
74
- });
75
- it("Sampling for sync", async () => {
76
- Array.from({ length: 100 }).map((_) => PerformanceEvent.timedExec(logger, { eventName: "TestingSync" }, callback, { start: true, end: true, cancel: "generic" }, 20));
77
- assert.equal(callbackCalls, 100);
78
- assert.equal(logger.eventsLogged, 10, "With sampling threshold of 20, expecting 100 calls to produce 10 events (5 start, 5 cancel)");
79
- // Event with a different category gets logged
80
- PerformanceEvent.timedExec(logger, { eventName: "TestingSync", category: "error" }, callback, { start: true, end: true, cancel: "generic" }, 20);
81
- assert.equal(callbackCalls, 101);
82
- assert.equal(logger.eventsLogged, 12, "Expecting two extra events");
83
- });
84
- });
85
- });
86
- //# sourceMappingURL=performanceEvent.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"performanceEvent.spec.js","sourceRoot":"","sources":["../../src/test/performanceEvent.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\nimport { ITelemetryBaseEvent } from \"@fluidframework/core-interfaces\";\nimport { TelemetryLogger, PerformanceEvent } from \"../logger.js\";\nimport { ITelemetryLoggerExt } from \"../telemetryTypes.js\";\n\nclass MockLogger extends TelemetryLogger implements ITelemetryLoggerExt {\n\tpublic errorsLogged: number = 0;\n\tpublic eventsLogged: number = 0;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tsend(event: ITelemetryBaseEvent): void {\n\t\tif (event.category === \"error\") {\n\t\t\t++this.errorsLogged;\n\t\t}\n\n\t\t++this.eventsLogged;\n\t}\n}\n\ndescribe(\"PerformanceEvent\", () => {\n\tlet logger: MockLogger;\n\tlet callbackCalls = 0;\n\n\tconst callback = (): void => {\n\t\tcallbackCalls++;\n\t};\n\tconst asyncCallback = async (event: PerformanceEvent): Promise<string | void> => {\n\t\tconst outerPromise: Promise<string> = new Promise((resolve, reject) => {\n\t\t\tPromise.resolve(\"A\")\n\t\t\t\t.finally(() => {\n\t\t\t\t\treject(new Error(\"B\"));\n\t\t\t\t})\n\t\t\t\t.then((val) => {\n\t\t\t\t\tevent.end({ val });\n\t\t\t\t\tresolve(\"C\");\n\t\t\t\t})\n\t\t\t\t.catch(() => {});\n\t\t});\n\n\t\tcallbackCalls++;\n\t\treturn outerPromise.catch(() => {});\n\t};\n\n\tbeforeEach(() => {\n\t\tcallbackCalls = 0;\n\t\tlogger = new MockLogger();\n\t});\n\n\tit(\"Cancel then End\", async () => {\n\t\tawait PerformanceEvent.timedExecAsync(\n\t\t\tlogger,\n\t\t\t{ eventName: \"Testing\" },\n\t\t\tasyncCallback,\n\t\t\t{ start: true, end: true, cancel: \"generic\" },\n\t\t\ttrue,\n\t\t);\n\t\tassert.equal(logger.errorsLogged, 0, \"Shouldn't have logged any errors\");\n\t});\n\n\tdescribe(\"Event sampling\", () => {\n\t\tit(\"Events are logged at least once\", async () => {\n\t\t\tawait PerformanceEvent.timedExecAsync(\n\t\t\t\tlogger,\n\t\t\t\t{ eventName: \"TestingAsyncOnce\" },\n\t\t\t\tasyncCallback,\n\t\t\t\t{ start: true, end: true, cancel: \"generic\" },\n\t\t\t\ttrue,\n\t\t\t\t100, // sampleThreshold\n\t\t\t);\n\n\t\t\tPerformanceEvent.timedExec(\n\t\t\t\tlogger,\n\t\t\t\t{ eventName: \"TestingSyncOnce\" },\n\t\t\t\tcallback,\n\t\t\t\t{ start: true, end: true, cancel: \"generic\" },\n\t\t\t\t100, // sampleThreshold\n\t\t\t);\n\n\t\t\tassert.equal(callbackCalls, 2);\n\t\t\tassert.equal(logger.eventsLogged, 4);\n\t\t});\n\n\t\tit(\"No sampling by default\", async () => {\n\t\t\tawait Promise.all(\n\t\t\t\tArray.from({ length: 100 }).map(async (_) =>\n\t\t\t\t\tPerformanceEvent.timedExecAsync(\n\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t{ eventName: \"TestingAsync\" },\n\t\t\t\t\t\tasyncCallback,\n\t\t\t\t\t\t{ start: true, end: true, cancel: \"generic\" },\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\n\t\t\tArray.from({ length: 100 }).map((_) =>\n\t\t\t\tPerformanceEvent.timedExec(logger, { eventName: \"TestingSync\" }, callback, {\n\t\t\t\t\tstart: true,\n\t\t\t\t\tend: true,\n\t\t\t\t\tcancel: \"generic\",\n\t\t\t\t}),\n\t\t\t);\n\n\t\t\tassert.equal(callbackCalls, 200);\n\t\t\tassert.equal(logger.eventsLogged, 200 * 2);\n\t\t});\n\n\t\tit(\"Sampling for async\", async () => {\n\t\t\tawait Promise.all(\n\t\t\t\tArray.from({ length: 100 }).map(async (_) =>\n\t\t\t\t\tPerformanceEvent.timedExecAsync(\n\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t{ eventName: \"TestingAsync\" },\n\t\t\t\t\t\tasyncCallback,\n\t\t\t\t\t\t{ start: true, end: true, cancel: \"generic\" },\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t20, // sampleThreshold\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\n\t\t\tassert.equal(callbackCalls, 100);\n\t\t\tassert.equal(\n\t\t\t\tlogger.eventsLogged,\n\t\t\t\t10,\n\t\t\t\t\"With sampling threshold of 20, expecting 100 calls to produce 10 events (5 start, 5 cancel)\",\n\t\t\t);\n\n\t\t\t// Event with a different category gets logged\n\t\t\tawait PerformanceEvent.timedExecAsync(\n\t\t\t\tlogger,\n\t\t\t\t{ eventName: \"TestingAsync\", category: \"error\" },\n\t\t\t\tasyncCallback,\n\t\t\t\t{ start: true, end: true, cancel: \"generic\" },\n\t\t\t\ttrue,\n\t\t\t\t20, // sampleThreshold\n\t\t\t);\n\n\t\t\tassert.equal(callbackCalls, 101);\n\t\t\tassert.equal(logger.eventsLogged, 12, \"Expecting two extra events\");\n\t\t});\n\n\t\tit(\"Sampling for sync\", async () => {\n\t\t\tArray.from({ length: 100 }).map((_) =>\n\t\t\t\tPerformanceEvent.timedExec(\n\t\t\t\t\tlogger,\n\t\t\t\t\t{ eventName: \"TestingSync\" },\n\t\t\t\t\tcallback,\n\t\t\t\t\t{ start: true, end: true, cancel: \"generic\" },\n\t\t\t\t\t20, // sampleThreshold\n\t\t\t\t),\n\t\t\t);\n\n\t\t\tassert.equal(callbackCalls, 100);\n\t\t\tassert.equal(\n\t\t\t\tlogger.eventsLogged,\n\t\t\t\t10,\n\t\t\t\t\"With sampling threshold of 20, expecting 100 calls to produce 10 events (5 start, 5 cancel)\",\n\t\t\t);\n\n\t\t\t// Event with a different category gets logged\n\t\t\tPerformanceEvent.timedExec(\n\t\t\t\tlogger,\n\t\t\t\t{ eventName: \"TestingSync\", category: \"error\" },\n\t\t\t\tcallback,\n\t\t\t\t{ start: true, end: true, cancel: \"generic\" },\n\t\t\t\t20, // sampleThreshold\n\t\t\t);\n\n\t\t\tassert.equal(callbackCalls, 101);\n\t\t\tassert.equal(logger.eventsLogged, 12, \"Expecting two extra events\");\n\t\t});\n\t});\n});\n"]}
@@ -1,169 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- import assert from "node:assert";
6
- import { SampledTelemetryHelper } from "../sampledTelemetryHelper.js";
7
- /**
8
- * Test logger with only the necessary functionality used by the SampledTelemetryHelper
9
- * so we can test it.
10
- */
11
- class TestLogger {
12
- constructor() {
13
- this.events = [];
14
- }
15
- sendPerformanceEvent(event, error) {
16
- this.events.push(event);
17
- }
18
- send(event) {
19
- throw new Error("Method not implemented.");
20
- }
21
- sendTelemetryEvent(event, error) {
22
- throw new Error("Method not implemented.");
23
- }
24
- sendErrorEvent(event, error) {
25
- throw new Error("Method not implemented.");
26
- }
27
- }
28
- const standardEventProperties = ["eventName", "duration", "count"];
29
- const aggregateProperties = ["totalDuration", "minDuration", "maxDuration"];
30
- describe("SampledTelemetryHelper", () => {
31
- let logger;
32
- beforeEach(() => {
33
- logger = new TestLogger();
34
- });
35
- it("only writes event after correct number of samples", () => {
36
- const sampling = 10;
37
- const helper = new SampledTelemetryHelper({ eventName: "testEvent" }, logger, sampling);
38
- for (let i = 0; i < sampling - 1; i++) {
39
- helper.measure(() => { });
40
- }
41
- assert.strictEqual(logger.events.length, 0);
42
- helper.measure(() => { });
43
- assert.strictEqual(logger.events.length, 1);
44
- // Again to make sure the internal counter is reset correctly
45
- for (let i = 0; i < sampling - 1; i++) {
46
- helper.measure(() => { });
47
- }
48
- assert.strictEqual(logger.events.length, 1);
49
- helper.measure(() => { });
50
- assert.strictEqual(logger.events.length, 2);
51
- });
52
- it("does not include aggregate properties when it shouldn't", () => {
53
- const helper = new SampledTelemetryHelper({ eventName: "testEvent" }, logger, 1, false);
54
- helper.measure(() => { });
55
- assert.strictEqual(logger.events.length, 1);
56
- const event = logger.events[0];
57
- ensurePropertiesExist(event, standardEventProperties, true);
58
- assert.strictEqual(event.count, 1);
59
- });
60
- it("includes aggregate properties when it should", () => {
61
- const helper = new SampledTelemetryHelper({ eventName: "testEvent" }, logger, 1, true);
62
- helper.measure(() => { });
63
- assert.strictEqual(logger.events.length, 1);
64
- const event = logger.events[0];
65
- ensurePropertiesExist(event, [...standardEventProperties, ...aggregateProperties], true);
66
- assert.strictEqual(event.count, 1);
67
- });
68
- it("includes properties from base event when no aggregate properties are included", () => {
69
- const helper = new SampledTelemetryHelper({ eventName: "testEvent", myProp: "myValue" }, logger, 1, false);
70
- helper.measure(() => { });
71
- assert.strictEqual(logger.events.length, 1);
72
- const event = logger.events[0];
73
- ensurePropertiesExist(event, [...standardEventProperties, "myProp"], true);
74
- assert.strictEqual(event.count, 1);
75
- assert.strictEqual(event.myProp, "myValue");
76
- });
77
- it("includes properties from base event when aggregate properties are included", () => {
78
- const helper = new SampledTelemetryHelper({ eventName: "testEvent", myProp: "myValue" }, logger, 1, true);
79
- helper.measure(() => { });
80
- assert.strictEqual(logger.events.length, 1);
81
- const event = logger.events[0];
82
- ensurePropertiesExist(event, [...standardEventProperties, ...aggregateProperties, "myProp"], true);
83
- assert.strictEqual(event.count, 1);
84
- assert.strictEqual(event.myProp, "myValue");
85
- });
86
- it("tracks buckets separately and includes per-bucket properties", () => {
87
- const bucket1 = "bucket1";
88
- const bucket2 = "bucket2";
89
- const bucketProperties = new Map([
90
- [bucket1, { prop1: "value1" }],
91
- [bucket2, { prop2: "value2" }],
92
- ]);
93
- const helper = new SampledTelemetryHelper({ eventName: "testEvent" }, logger, 3, false, bucketProperties);
94
- for (let i = 0; i < 9; i++) {
95
- helper.measure(() => { }, bucket1);
96
- }
97
- for (let i = 0; i < 7; i++) {
98
- helper.measure(() => { }, bucket2);
99
- }
100
- assert.strictEqual(logger.events.filter((x) => x.prop1 === "value1").length, 3);
101
- assert.strictEqual(logger.events.filter((x) => x.prop2 === "value2").length, 2);
102
- });
103
- it("bucket properties do not override measurement properties", () => {
104
- // If the names of the properties specified by the consumers for a bucket overlap with the names
105
- // of the standard properties we put in the telemetry events, our values should not be overwritten
106
- // by the custom properties.
107
- const bucket1 = "bucket1";
108
- const bucketProperties = new Map([
109
- // Here just using a duration value that we can be sure will not be the actual value, to make sure the
110
- // actuals is different from this one (since it's much harder to guarantee an exact duration
111
- // value to test for equality).
112
- [bucket1, { duration: 1000, count: 1000 }],
113
- ]);
114
- const helper = new SampledTelemetryHelper({ eventName: "testEvent" }, logger, 1, false, bucketProperties);
115
- helper.measure(() => { }, bucket1);
116
- assert.strictEqual(logger.events.length, 1);
117
- const event = logger.events[0];
118
- assert.strictEqual(event.count, 1);
119
- assert(event.duration !== bucketProperties.get("bucket1").duration);
120
- });
121
- it("generates telemetry event from buffered data when disposed", () => {
122
- // Logging several buckets to make sure they are all flushed. We can only distingush the events based on the
123
- // custom properties added to the event for each bucket
124
- const bucket1 = "bucket1";
125
- const bucket2 = "bucket2";
126
- const bucketProperties = new Map([
127
- [bucket1, { prop1: "value1" }],
128
- [bucket2, { prop2: "value2" }],
129
- ]);
130
- const helper = new SampledTelemetryHelper({ eventName: "testEvent" }, logger, 5, false, bucketProperties);
131
- // Only measure 4 times when we need 5 samples before writing the telemetry event
132
- for (let i = 0; i < 4; i++) {
133
- helper.measure(() => { }, bucket1);
134
- helper.measure(() => { }, bucket2);
135
- }
136
- // Nothing should have been logged yet
137
- assert.strictEqual(logger.events.length, 0);
138
- // After disposing, there should be one event for each bucket
139
- helper.dispose();
140
- assert.strictEqual(logger.events.filter((x) => x.prop1 === "value1").length, 1);
141
- assert.strictEqual(logger.events.filter((x) => x.prop2 === "value2").length, 1);
142
- });
143
- it("no event is generated on dispose if there's no pending 'buffered' data", () => {
144
- const helper = new SampledTelemetryHelper({ eventName: "testEvent" }, logger, 2);
145
- // Nothing should have been logged after the first call
146
- helper.measure(() => { });
147
- assert.strictEqual(logger.events.length, 0);
148
- // On the second call, we should have 1 event
149
- helper.measure(() => { });
150
- assert.strictEqual(logger.events.length, 1);
151
- // After disposing, there should still be just one event
152
- helper.dispose();
153
- assert.strictEqual(logger.events.length, 1);
154
- });
155
- });
156
- function ensurePropertiesExist(object, propNames, noExtraProperties = false) {
157
- for (const name of propNames) {
158
- assert.strictEqual(object[name] !== undefined, true);
159
- }
160
- if (noExtraProperties) {
161
- const actualNumberOfProps = Object.keys(object).length;
162
- const expectedNumberOfProps = propNames.length;
163
- if (actualNumberOfProps !== expectedNumberOfProps) {
164
- assert.fail(`Object contains unexpected properties ` +
165
- `(${actualNumberOfProps} found, ${expectedNumberOfProps}) expected)`);
166
- }
167
- }
168
- }
169
- //# sourceMappingURL=sampledTelemetryHelper.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sampledTelemetryHelper.spec.js","sourceRoot":"","sources":["../../src/test/sampledTelemetryHelper.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport assert from \"node:assert\";\nimport type {\n\tITelemetryBaseEvent,\n\tITelemetryBaseProperties,\n} from \"@fluidframework/core-interfaces\";\n\nimport { SampledTelemetryHelper } from \"../sampledTelemetryHelper.js\";\nimport {\n\tITelemetryLoggerExt,\n\ttype ITelemetryErrorEventExt,\n\ttype ITelemetryPerformanceEventExt,\n\ttype ITelemetryGenericEventExt,\n} from \"../telemetryTypes.js\";\n\n/**\n * Test logger with only the necessary functionality used by the SampledTelemetryHelper\n * so we can test it.\n */\nclass TestLogger implements ITelemetryLoggerExt {\n\tpublic events: ITelemetryPerformanceEventExt[] = [];\n\n\tsendPerformanceEvent(event: ITelemetryPerformanceEventExt, error?: unknown): void {\n\t\tthis.events.push(event);\n\t}\n\n\tsend(event: ITelemetryBaseEvent): void {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\tsendTelemetryEvent(event: ITelemetryGenericEventExt, error?: unknown): void {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\tsendErrorEvent(event: ITelemetryErrorEventExt, error?: unknown): void {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\tsupportsTags?: true | undefined;\n}\n\nconst standardEventProperties = [\"eventName\", \"duration\", \"count\"];\nconst aggregateProperties = [\"totalDuration\", \"minDuration\", \"maxDuration\"];\n\ndescribe(\"SampledTelemetryHelper\", () => {\n\tlet logger: TestLogger;\n\n\tbeforeEach(() => {\n\t\tlogger = new TestLogger();\n\t});\n\n\tit(\"only writes event after correct number of samples\", () => {\n\t\tconst sampling = 10;\n\t\tconst helper = new SampledTelemetryHelper({ eventName: \"testEvent\" }, logger, sampling);\n\t\tfor (let i = 0; i < sampling - 1; i++) {\n\t\t\thelper.measure(() => {});\n\t\t}\n\t\tassert.strictEqual(logger.events.length, 0);\n\t\thelper.measure(() => {});\n\t\tassert.strictEqual(logger.events.length, 1);\n\n\t\t// Again to make sure the internal counter is reset correctly\n\t\tfor (let i = 0; i < sampling - 1; i++) {\n\t\t\thelper.measure(() => {});\n\t\t}\n\t\tassert.strictEqual(logger.events.length, 1);\n\t\thelper.measure(() => {});\n\t\tassert.strictEqual(logger.events.length, 2);\n\t});\n\n\tit(\"does not include aggregate properties when it shouldn't\", () => {\n\t\tconst helper = new SampledTelemetryHelper({ eventName: \"testEvent\" }, logger, 1, false);\n\t\thelper.measure(() => {});\n\t\tassert.strictEqual(logger.events.length, 1);\n\t\tconst event = logger.events[0];\n\t\tensurePropertiesExist(event, standardEventProperties, true);\n\t\tassert.strictEqual(event.count, 1);\n\t});\n\n\tit(\"includes aggregate properties when it should\", () => {\n\t\tconst helper = new SampledTelemetryHelper({ eventName: \"testEvent\" }, logger, 1, true);\n\t\thelper.measure(() => {});\n\t\tassert.strictEqual(logger.events.length, 1);\n\t\tconst event = logger.events[0];\n\t\tensurePropertiesExist(event, [...standardEventProperties, ...aggregateProperties], true);\n\t\tassert.strictEqual(event.count, 1);\n\t});\n\n\tit(\"includes properties from base event when no aggregate properties are included\", () => {\n\t\tconst helper = new SampledTelemetryHelper(\n\t\t\t{ eventName: \"testEvent\", myProp: \"myValue\" },\n\t\t\tlogger,\n\t\t\t1,\n\t\t\tfalse,\n\t\t);\n\t\thelper.measure(() => {});\n\t\tassert.strictEqual(logger.events.length, 1);\n\t\tconst event = logger.events[0];\n\t\tensurePropertiesExist(event, [...standardEventProperties, \"myProp\"], true);\n\t\tassert.strictEqual(event.count, 1);\n\t\tassert.strictEqual(event.myProp, \"myValue\");\n\t});\n\n\tit(\"includes properties from base event when aggregate properties are included\", () => {\n\t\tconst helper = new SampledTelemetryHelper(\n\t\t\t{ eventName: \"testEvent\", myProp: \"myValue\" },\n\t\t\tlogger,\n\t\t\t1,\n\t\t\ttrue,\n\t\t);\n\t\thelper.measure(() => {});\n\t\tassert.strictEqual(logger.events.length, 1);\n\t\tconst event = logger.events[0];\n\t\tensurePropertiesExist(\n\t\t\tevent,\n\t\t\t[...standardEventProperties, ...aggregateProperties, \"myProp\"],\n\t\t\ttrue,\n\t\t);\n\t\tassert.strictEqual(event.count, 1);\n\t\tassert.strictEqual(event.myProp, \"myValue\");\n\t});\n\n\tit(\"tracks buckets separately and includes per-bucket properties\", () => {\n\t\tconst bucket1 = \"bucket1\";\n\t\tconst bucket2 = \"bucket2\";\n\t\tconst bucketProperties: Map<string, ITelemetryBaseProperties> = new Map<\n\t\t\tstring,\n\t\t\tITelemetryBaseProperties\n\t\t>([\n\t\t\t[bucket1, { prop1: \"value1\" }],\n\t\t\t[bucket2, { prop2: \"value2\" }],\n\t\t]);\n\n\t\tconst helper = new SampledTelemetryHelper(\n\t\t\t{ eventName: \"testEvent\" },\n\t\t\tlogger,\n\t\t\t3,\n\t\t\tfalse,\n\t\t\tbucketProperties,\n\t\t);\n\n\t\tfor (let i = 0; i < 9; i++) {\n\t\t\thelper.measure(() => {}, bucket1);\n\t\t}\n\t\tfor (let i = 0; i < 7; i++) {\n\t\t\thelper.measure(() => {}, bucket2);\n\t\t}\n\n\t\tassert.strictEqual(logger.events.filter((x) => x.prop1 === \"value1\").length, 3);\n\t\tassert.strictEqual(logger.events.filter((x) => x.prop2 === \"value2\").length, 2);\n\t});\n\n\tit(\"bucket properties do not override measurement properties\", () => {\n\t\t// If the names of the properties specified by the consumers for a bucket overlap with the names\n\t\t// of the standard properties we put in the telemetry events, our values should not be overwritten\n\t\t// by the custom properties.\n\n\t\tconst bucket1 = \"bucket1\";\n\t\tconst bucketProperties: Map<string, ITelemetryBaseProperties> = new Map<\n\t\t\tstring,\n\t\t\tITelemetryBaseProperties\n\t\t>([\n\t\t\t// Here just using a duration value that we can be sure will not be the actual value, to make sure the\n\t\t\t// actuals is different from this one (since it's much harder to guarantee an exact duration\n\t\t\t// value to test for equality).\n\t\t\t[bucket1, { duration: 1000, count: 1000 }],\n\t\t]);\n\n\t\tconst helper = new SampledTelemetryHelper(\n\t\t\t{ eventName: \"testEvent\" },\n\t\t\tlogger,\n\t\t\t1,\n\t\t\tfalse,\n\t\t\tbucketProperties,\n\t\t);\n\t\thelper.measure(() => {}, bucket1);\n\t\tassert.strictEqual(logger.events.length, 1);\n\t\tconst event = logger.events[0];\n\t\tassert.strictEqual(event.count, 1);\n\t\tassert(event.duration !== bucketProperties.get(\"bucket1\")!.duration);\n\t});\n\n\tit(\"generates telemetry event from buffered data when disposed\", () => {\n\t\t// Logging several buckets to make sure they are all flushed. We can only distingush the events based on the\n\t\t// custom properties added to the event for each bucket\n\t\tconst bucket1 = \"bucket1\";\n\t\tconst bucket2 = \"bucket2\";\n\t\tconst bucketProperties: Map<string, ITelemetryBaseProperties> = new Map<\n\t\t\tstring,\n\t\t\tITelemetryBaseProperties\n\t\t>([\n\t\t\t[bucket1, { prop1: \"value1\" }],\n\t\t\t[bucket2, { prop2: \"value2\" }],\n\t\t]);\n\n\t\tconst helper = new SampledTelemetryHelper(\n\t\t\t{ eventName: \"testEvent\" },\n\t\t\tlogger,\n\t\t\t5,\n\t\t\tfalse,\n\t\t\tbucketProperties,\n\t\t);\n\n\t\t// Only measure 4 times when we need 5 samples before writing the telemetry event\n\t\tfor (let i = 0; i < 4; i++) {\n\t\t\thelper.measure(() => {}, bucket1);\n\t\t\thelper.measure(() => {}, bucket2);\n\t\t}\n\n\t\t// Nothing should have been logged yet\n\t\tassert.strictEqual(logger.events.length, 0);\n\n\t\t// After disposing, there should be one event for each bucket\n\t\thelper.dispose();\n\t\tassert.strictEqual(logger.events.filter((x) => x.prop1 === \"value1\").length, 1);\n\t\tassert.strictEqual(logger.events.filter((x) => x.prop2 === \"value2\").length, 1);\n\t});\n\n\tit(\"no event is generated on dispose if there's no pending 'buffered' data\", () => {\n\t\tconst helper = new SampledTelemetryHelper({ eventName: \"testEvent\" }, logger, 2);\n\n\t\t// Nothing should have been logged after the first call\n\t\thelper.measure(() => {});\n\t\tassert.strictEqual(logger.events.length, 0);\n\n\t\t// On the second call, we should have 1 event\n\t\thelper.measure(() => {});\n\t\tassert.strictEqual(logger.events.length, 1);\n\n\t\t// After disposing, there should still be just one event\n\t\thelper.dispose();\n\t\tassert.strictEqual(logger.events.length, 1);\n\t});\n});\n\nfunction ensurePropertiesExist(\n\tobject: ITelemetryPerformanceEventExt,\n\tpropNames: string[],\n\tnoExtraProperties: boolean = false,\n): void {\n\tfor (const name of propNames) {\n\t\tassert.strictEqual(object[name] !== undefined, true);\n\t}\n\n\tif (noExtraProperties) {\n\t\tconst actualNumberOfProps = Object.keys(object).length;\n\t\tconst expectedNumberOfProps = propNames.length;\n\t\tif (actualNumberOfProps !== expectedNumberOfProps) {\n\t\t\tassert.fail(\n\t\t\t\t`Object contains unexpected properties ` +\n\t\t\t\t\t`(${actualNumberOfProps} found, ${expectedNumberOfProps}) expected)`,\n\t\t\t);\n\t\t}\n\t}\n}\n"]}