@fluidframework/telemetry-utils 2.100.0 → 2.101.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/CHANGELOG.md +4 -0
- package/api-report/telemetry-utils.legacy.beta.api.md +2 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -1
- package/dist/config.js.map +1 -1
- package/dist/logger.d.ts +21 -16
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +32 -25
- package/dist/logger.js.map +1 -1
- package/dist/mockLogger.js +2 -2
- package/dist/mockLogger.js.map +1 -1
- package/dist/sampledTelemetryHelper.d.ts +3 -0
- package/dist/sampledTelemetryHelper.d.ts.map +1 -1
- package/dist/sampledTelemetryHelper.js +6 -1
- package/dist/sampledTelemetryHelper.js.map +1 -1
- package/dist/telemetryTypes.d.ts +12 -8
- package/dist/telemetryTypes.d.ts.map +1 -1
- package/dist/telemetryTypes.js.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +8 -8
- package/dist/utils.js.map +1 -1
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +2 -1
- package/lib/config.js.map +1 -1
- package/lib/logger.d.ts +21 -16
- package/lib/logger.d.ts.map +1 -1
- package/lib/logger.js +32 -25
- package/lib/logger.js.map +1 -1
- package/lib/mockLogger.js +2 -2
- package/lib/mockLogger.js.map +1 -1
- package/lib/sampledTelemetryHelper.d.ts +3 -0
- package/lib/sampledTelemetryHelper.d.ts.map +1 -1
- package/lib/sampledTelemetryHelper.js +6 -1
- package/lib/sampledTelemetryHelper.js.map +1 -1
- package/lib/telemetryTypes.d.ts +12 -8
- package/lib/telemetryTypes.d.ts.map +1 -1
- package/lib/telemetryTypes.js.map +1 -1
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +8 -8
- package/lib/utils.js.map +1 -1
- package/package.json +6 -6
- package/src/config.ts +12 -8
- package/src/logger.ts +41 -23
- package/src/mockLogger.ts +2 -2
- package/src/sampledTelemetryHelper.ts +9 -1
- package/src/telemetryTypes.ts +12 -8
- package/src/utils.ts +17 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telemetryTypes.js","sourceRoot":"","sources":["../src/telemetryTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { ITelemetryBaseLogger, LogLevel, Tagged } from \"@fluidframework/core-interfaces\";\n\n/**\n * The categories FF uses when instrumenting the code.\n *\n * generic - Informational log event\n *\n * error - Error log event, ideally 0 of these are logged during a session\n *\n * performance - Includes duration, and often has _start, _end, or _cancel suffixes for activity tracking\n * @deprecated This type is being removed without a replacement.\n * @see {@link https://github.com/microsoft/FluidFramework/issues/26910 | Issue #26910} for details.\n * @legacy @beta\n */\nexport type TelemetryEventCategory = \"generic\" | \"error\" | \"performance\";\n\n/**\n * Property types that can be logged.\n *\n * @remarks\n * Includes extra types beyond {@link @fluidframework/core-interfaces#TelemetryBaseEventPropertyType}, which must be\n * converted before sending to a base logger.\n * @legacy @beta\n */\nexport type TelemetryEventPropertyTypeExt =\n\t| string\n\t| number\n\t| boolean\n\t| undefined\n\t| (string | number | boolean)[]\n\t| Record<string, string | number | boolean | undefined | (string | number | boolean)[]>;\n\n/**\n * JSON-serializable properties, which will be logged with telemetry.\n * @legacy @beta\n */\nexport type ITelemetryPropertiesExt = Record<\n\tstring,\n\tTelemetryEventPropertyTypeExt | Tagged<TelemetryEventPropertyTypeExt>\n>;\n\n/**\n * Interface for logging telemetry statements.\n * @remarks May contain any number of properties that get serialized as json payload.\n * @param category - category of the event, like \"error\", \"performance\", \"generic\", etc.\n * @param eventName - name of the event.\n *\n * @internal\n */\nexport interface ITelemetryEventExt extends ITelemetryPropertiesExt {\n\t/**\n\t * {@inheritDoc @fluidframework/core-interfaces#ITelemetryBaseEvent.category}\n\t */\n\tcategory: string;\n\n\t/**\n\t * {@inheritDoc @fluidframework/core-interfaces#ITelemetryBaseEvent.eventName}\n\t */\n\teventName: string;\n}\n\n/**\n * Informational (non-error) telemetry event\n * @remarks Maps to category = \"generic\"\n * @deprecated This type is being removed without a replacement.\n * @see {@link https://github.com/microsoft/FluidFramework/issues/26910 | Issue #26910} for details.\n * @legacy @beta\n */\nexport interface ITelemetryGenericEventExt extends ITelemetryPropertiesExt {\n\t/**\n\t * {@inheritDoc @fluidframework/core-interfaces#ITelemetryBaseEvent.eventName}\n\t */\n\teventName: string;\n\n\t/**\n\t * Optional event {@link @fluidframework/core-interfaces#ITelemetryBaseEvent.category}.\n\t * @defaultValue \"generic\"\n\t */\n\tcategory?: TelemetryEventCategory;\n}\n\n/**\n * Error telemetry event.\n * @remarks Maps to category = \"error\"\n * @deprecated This type is being removed without a replacement.\n * @see {@link https://github.com/microsoft/FluidFramework/issues/26910 | Issue #26910} for details.\n * @legacy @beta\n */\nexport interface ITelemetryErrorEventExt extends ITelemetryPropertiesExt {\n\t/**\n\t * {@inheritDoc @fluidframework/core-interfaces#ITelemetryBaseEvent.eventName}\n\t */\n\teventName: string;\n}\n\n/**\n * Performance telemetry event.\n * @remarks Maps to category = \"performance\"\n * @deprecated This type is being removed without a replacement.\n * @see {@link https://github.com/microsoft/FluidFramework/issues/26910 | Issue #26910} for details.\n * @legacy @beta\n */\nexport interface ITelemetryPerformanceEventExt extends ITelemetryGenericEventExt {\n\t/**\n\t * Duration of event (optional)\n\t */\n\tduration?: number;\n}\n\n/**\n * This is the externally facing type for a FluidFramework internal telemetry logger wrapper.\n *\n * @remarks\n * The methods if this interface are not to be used directly by consumers and are all\n * deprecated to removed without replacement. This type is not deprecated and will\n * transition to an erased type to handle cases where \"internal\" `ITelemetryLoggerExt`\n * previously leaked out.\n *\n * @see {@link https://github.com/microsoft/FluidFramework/issues/26910 | Issue #26910} for deprecation and breaking change details.\n *\n * @privateRemarks\n * External APIs taking in an `ITelemetryLoggerExt` ideally should be updated to\n * accept `ITelemetryBaseLogger` instead.\n *\n * @sealed\n * @legacy\n * @beta\n */\nexport interface ITelemetryLoggerExt extends ITelemetryBaseLogger {\n\t/**\n\t * Send an information telemetry event.\n\t * @param event - Event to send.\n\t * @param error - Optional error object to log.\n\t * @param logLevel - Optional level of the log.
|
|
1
|
+
{"version":3,"file":"telemetryTypes.js","sourceRoot":"","sources":["../src/telemetryTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { ITelemetryBaseLogger, LogLevel, Tagged } from \"@fluidframework/core-interfaces\";\n\n/**\n * The categories FF uses when instrumenting the code.\n *\n * generic - Informational log event\n *\n * error - Error log event, ideally 0 of these are logged during a session\n *\n * performance - Includes duration, and often has _start, _end, or _cancel suffixes for activity tracking\n * @deprecated This type is being removed without a replacement.\n * @see {@link https://github.com/microsoft/FluidFramework/issues/26910 | Issue #26910} for details.\n * @legacy @beta\n */\nexport type TelemetryEventCategory = \"generic\" | \"error\" | \"performance\";\n\n/**\n * Property types that can be logged.\n *\n * @remarks\n * Includes extra types beyond {@link @fluidframework/core-interfaces#TelemetryBaseEventPropertyType}, which must be\n * converted before sending to a base logger.\n * @legacy @beta\n */\nexport type TelemetryEventPropertyTypeExt =\n\t| string\n\t| number\n\t| boolean\n\t| undefined\n\t| (string | number | boolean)[]\n\t| Record<string, string | number | boolean | undefined | (string | number | boolean)[]>;\n\n/**\n * JSON-serializable properties, which will be logged with telemetry.\n * @legacy @beta\n */\nexport type ITelemetryPropertiesExt = Record<\n\tstring,\n\tTelemetryEventPropertyTypeExt | Tagged<TelemetryEventPropertyTypeExt>\n>;\n\n/**\n * Interface for logging telemetry statements.\n * @remarks May contain any number of properties that get serialized as json payload.\n * @param category - category of the event, like \"error\", \"performance\", \"generic\", etc.\n * @param eventName - name of the event.\n *\n * @internal\n */\nexport interface ITelemetryEventExt extends ITelemetryPropertiesExt {\n\t/**\n\t * {@inheritDoc @fluidframework/core-interfaces#ITelemetryBaseEvent.category}\n\t */\n\tcategory: string;\n\n\t/**\n\t * {@inheritDoc @fluidframework/core-interfaces#ITelemetryBaseEvent.eventName}\n\t */\n\teventName: string;\n}\n\n/**\n * Informational (non-error) telemetry event\n * @remarks Maps to category = \"generic\"\n * @deprecated This type is being removed without a replacement.\n * @see {@link https://github.com/microsoft/FluidFramework/issues/26910 | Issue #26910} for details.\n * @legacy @beta\n */\nexport interface ITelemetryGenericEventExt extends ITelemetryPropertiesExt {\n\t/**\n\t * {@inheritDoc @fluidframework/core-interfaces#ITelemetryBaseEvent.eventName}\n\t */\n\teventName: string;\n\n\t/**\n\t * Optional event {@link @fluidframework/core-interfaces#ITelemetryBaseEvent.category}.\n\t * @defaultValue \"generic\"\n\t */\n\tcategory?: TelemetryEventCategory;\n}\n\n/**\n * Error telemetry event.\n * @remarks Maps to category = \"error\"\n * @deprecated This type is being removed without a replacement.\n * @see {@link https://github.com/microsoft/FluidFramework/issues/26910 | Issue #26910} for details.\n * @legacy @beta\n */\nexport interface ITelemetryErrorEventExt extends ITelemetryPropertiesExt {\n\t/**\n\t * {@inheritDoc @fluidframework/core-interfaces#ITelemetryBaseEvent.eventName}\n\t */\n\teventName: string;\n}\n\n/**\n * Performance telemetry event.\n * @remarks Maps to category = \"performance\"\n * @deprecated This type is being removed without a replacement.\n * @see {@link https://github.com/microsoft/FluidFramework/issues/26910 | Issue #26910} for details.\n * @legacy @beta\n */\nexport interface ITelemetryPerformanceEventExt extends ITelemetryGenericEventExt {\n\t/**\n\t * Duration of event (optional)\n\t */\n\tduration?: number;\n}\n\n/**\n * This is the externally facing type for a FluidFramework internal telemetry logger wrapper.\n *\n * @remarks\n * The methods if this interface are not to be used directly by consumers and are all\n * deprecated to removed without replacement. This type is not deprecated and will\n * transition to an erased type to handle cases where \"internal\" `ITelemetryLoggerExt`\n * previously leaked out.\n *\n * @see {@link https://github.com/microsoft/FluidFramework/issues/26910 | Issue #26910} for deprecation and breaking change details.\n *\n * @privateRemarks\n * External APIs taking in an `ITelemetryLoggerExt` ideally should be updated to\n * accept `ITelemetryBaseLogger` instead.\n *\n * @sealed\n * @legacy\n * @beta\n */\nexport interface ITelemetryLoggerExt extends ITelemetryBaseLogger {\n\t/**\n\t * Send an information telemetry event.\n\t * @param event - Event to send.\n\t * @param error - Optional error object to log.\n\t * @param logLevel - Optional level of the log. If undefined, the logLevel should be treated as {@link @fluidframework/core-interfaces#LogLevel.essential}.\n\t * If the event's category is `error`, the logLevel will be upgraded to {@link @fluidframework/core-interfaces#LogLevel.essential}.\n\t * @deprecated This method is being removed without a replacement.\n\t * @see {@link https://github.com/microsoft/FluidFramework/issues/26910 | Issue #26910} for details.\n\t */\n\tsendTelemetryEvent(\n\t\tevent: ITelemetryGenericEventExt,\n\t\terror?: unknown,\n\t\tlogLevel?: typeof LogLevel.verbose | typeof LogLevel.info,\n\t): void;\n\n\t/**\n\t * Send an error telemetry event.\n\t * @param event - Event to send.\n\t * @param error - Optional error object to log.\n\t * @deprecated This method is being removed without a replacement.\n\t * @see {@link https://github.com/microsoft/FluidFramework/issues/26910 | Issue #26910} for details.\n\t */\n\tsendErrorEvent(event: ITelemetryErrorEventExt, error?: unknown): void;\n\n\t/**\n\t * Send a performance telemetry event.\n\t * @param event - Event to send\n\t * @param error - Optional error object to log.\n\t * @param logLevel - Optional level of the log. If undefined, the logLevel should be treated as {@link @fluidframework/core-interfaces#LogLevel.essential}.\n\t * If the event's category is `error`, the logLevel will be upgraded to {@link @fluidframework/core-interfaces#LogLevel.essential}.\n\t * @deprecated This method is being removed without a replacement.\n\t * @see {@link https://github.com/microsoft/FluidFramework/issues/26910 | Issue #26910} for details.\n\t */\n\tsendPerformanceEvent(\n\t\tevent: ITelemetryPerformanceEventExt,\n\t\terror?: unknown,\n\t\tlogLevel?: typeof LogLevel.verbose | typeof LogLevel.info,\n\t): void;\n}\n\n/**\n * An extended {@link @fluidframework/core-interfaces#ITelemetryBaseLogger} which allows for more lenient event types.\n *\n * @remarks\n * This interface is meant to be used internally within the Fluid Framework,\n * and `ITelemetryBaseLogger` should be used when loggers are passed between layers.\n * @internal\n */\nexport interface TelemetryLoggerExt extends ITelemetryBaseLogger {\n\t/**\n\t * Send an information telemetry event.\n\t * @param event - Event to send.\n\t * @param error - Optional error object to log.\n\t * @param logLevel - Optional level of the log. If undefined, the logLevel will be treated as {@link @fluidframework/core-interfaces#LogLevelConst.essential | LogLevel.essential}.\n\t * If the event's category is `error`, the logLevel will be upgraded to {@link @fluidframework/core-interfaces#LogLevelConst.essential | LogLevel.essential}.\n\t */\n\tsendTelemetryEvent(\n\t\tevent: ITelemetryGenericEventExt,\n\t\terror?: unknown,\n\t\tlogLevel?: typeof LogLevel.verbose | typeof LogLevel.info,\n\t): void;\n\n\t/**\n\t * Send an error telemetry event.\n\t * @param event - Event to send.\n\t * @param error - Optional error object to log.\n\t */\n\tsendErrorEvent(event: ITelemetryErrorEventExt, error?: unknown): void;\n\n\t/**\n\t * Send a performance telemetry event.\n\t * @param event - Event to send\n\t * @param error - Optional error object to log.\n\t * @param logLevel - Optional level of the log. If undefined, the logLevel will be treated as {@link @fluidframework/core-interfaces#LogLevelConst.essential | LogLevel.essential}.\n\t * If the event's category is `error`, the logLevel will be upgraded to {@link @fluidframework/core-interfaces#LogLevelConst.essential | LogLevel.essential}.\n\t */\n\tsendPerformanceEvent(\n\t\tevent: ITelemetryPerformanceEventExt,\n\t\terror?: unknown,\n\t\tlogLevel?: typeof LogLevel.verbose | typeof LogLevel.info,\n\t): void;\n}\n"]}
|
package/lib/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAEX,kBAAkB,EAClB,MAAM,iCAAiC,CAAC;AAEzC;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC7B;;OAEG;IACH,MAAM,EAAE,MAAM,OAAO,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAwB,SAAQ,kBAAkB;IAClE;;;;;;;OAOG;IACH,kBAAkB,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAClC,MAAM,EAAE,kBAAkB,EAC1B,YAAY,CAAC,EAAE,aAAa,EAC5B,iCAAiC,CAAC,EAAE,OAAO,GACzC,uBAAuB,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAEX,kBAAkB,EAClB,MAAM,iCAAiC,CAAC;AAEzC;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC7B;;OAEG;IACH,MAAM,EAAE,MAAM,OAAO,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAwB,SAAQ,kBAAkB;IAClE;;;;;;;OAOG;IACH,kBAAkB,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAClC,MAAM,EAAE,kBAAkB,EAC1B,YAAY,CAAC,EAAE,aAAa,EAC5B,iCAAiC,CAAC,EAAE,OAAO,GACzC,uBAAuB,CAsDzB;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,CAAC,CAAA;CAAE,CAKlF"}
|
package/lib/utils.js
CHANGED
|
@@ -23,7 +23,7 @@ export function createSampledLogger(logger, eventSampler, skipLoggingWhenSamplin
|
|
|
23
23
|
const monitoringContext = loggerToMonitoringContext(logger);
|
|
24
24
|
const isSamplingDisabled = monitoringContext.config.getBoolean("Fluid.Telemetry.DisableSampling") ?? false;
|
|
25
25
|
const sampledLogger = {
|
|
26
|
-
send: (event) => {
|
|
26
|
+
send: (event, logLevel) => {
|
|
27
27
|
// The sampler uses the following logic for sending events:
|
|
28
28
|
// 1. If isSamplingDisabled is true, then this means events should be unsampled. Therefore we send the event without any checks.
|
|
29
29
|
// 2. If isSamplingDisabled is false, then event should be sampled using the event sampler, if the sampler is not defined just send all events, other use the eventSampler.sample() method.
|
|
@@ -32,31 +32,31 @@ export function createSampledLogger(logger, eventSampler, skipLoggingWhenSamplin
|
|
|
32
32
|
if (isSamplingDisabled && (skipLoggingWhenSamplingIsDisabled ?? false)) {
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
35
|
-
logger.send(event);
|
|
35
|
+
logger.send(event, logLevel);
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
|
-
sendTelemetryEvent: (event) => {
|
|
38
|
+
sendTelemetryEvent: (event, error, logLevel) => {
|
|
39
39
|
if (isSamplingDisabled || eventSampler === undefined || eventSampler.sample()) {
|
|
40
40
|
if (isSamplingDisabled && (skipLoggingWhenSamplingIsDisabled ?? false)) {
|
|
41
41
|
return;
|
|
42
42
|
}
|
|
43
|
-
logger.sendTelemetryEvent(event);
|
|
43
|
+
logger.sendTelemetryEvent(event, error, logLevel);
|
|
44
44
|
}
|
|
45
45
|
},
|
|
46
|
-
sendErrorEvent: (event) => {
|
|
46
|
+
sendErrorEvent: (event, error) => {
|
|
47
47
|
if (isSamplingDisabled || eventSampler === undefined || eventSampler.sample()) {
|
|
48
48
|
if (isSamplingDisabled && (skipLoggingWhenSamplingIsDisabled ?? false)) {
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
|
-
logger.sendErrorEvent(event);
|
|
51
|
+
logger.sendErrorEvent(event, error);
|
|
52
52
|
}
|
|
53
53
|
},
|
|
54
|
-
sendPerformanceEvent: (event) => {
|
|
54
|
+
sendPerformanceEvent: (event, error, logLevel) => {
|
|
55
55
|
if (isSamplingDisabled || eventSampler === undefined || eventSampler.sample()) {
|
|
56
56
|
if (isSamplingDisabled && (skipLoggingWhenSamplingIsDisabled ?? false)) {
|
|
57
57
|
return;
|
|
58
58
|
}
|
|
59
|
-
logger.sendPerformanceEvent(event);
|
|
59
|
+
logger.sendPerformanceEvent(event, error, logLevel);
|
|
60
60
|
}
|
|
61
61
|
},
|
|
62
62
|
isSamplingDisabled,
|
package/lib/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAmCxD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,mBAAmB,CAClC,MAA0B,EAC1B,YAA4B,EAC5B,iCAA2C;IAE3C,MAAM,iBAAiB,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;IAC5D,MAAM,kBAAkB,GACvB,iBAAiB,CAAC,MAAM,CAAC,UAAU,CAAC,iCAAiC,CAAC,IAAI,KAAK,CAAC;IAEjF,MAAM,aAAa,GAAG;QACrB,IAAI,EAAE,CAAC,KAA0B,EAAQ,EAAE;
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAmCxD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,mBAAmB,CAClC,MAA0B,EAC1B,YAA4B,EAC5B,iCAA2C;IAE3C,MAAM,iBAAiB,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;IAC5D,MAAM,kBAAkB,GACvB,iBAAiB,CAAC,MAAM,CAAC,UAAU,CAAC,iCAAiC,CAAC,IAAI,KAAK,CAAC;IAEjF,MAAM,aAAa,GAAG;QACrB,IAAI,EAAE,CAAC,KAA0B,EAAE,QAAmB,EAAQ,EAAE;YAC/D,2DAA2D;YAC3D,gIAAgI;YAChI,2LAA2L;YAC3L,0EAA0E;YAC1E,IAAI,kBAAkB,IAAI,YAAY,KAAK,SAAS,IAAI,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC/E,IAAI,kBAAkB,IAAI,CAAC,iCAAiC,IAAI,KAAK,CAAC,EAAE,CAAC;oBACxE,OAAO;gBACR,CAAC;gBACD,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YAC9B,CAAC;QACF,CAAC;QACD,kBAAkB,EAAE,CACnB,KAAgC,EAChC,KAAe,EACf,QAAyD,EAClD,EAAE;YACT,IAAI,kBAAkB,IAAI,YAAY,KAAK,SAAS,IAAI,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC/E,IAAI,kBAAkB,IAAI,CAAC,iCAAiC,IAAI,KAAK,CAAC,EAAE,CAAC;oBACxE,OAAO;gBACR,CAAC;gBACD,MAAM,CAAC,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;YACnD,CAAC;QACF,CAAC;QACD,cAAc,EAAE,CAAC,KAAgC,EAAE,KAAe,EAAQ,EAAE;YAC3E,IAAI,kBAAkB,IAAI,YAAY,KAAK,SAAS,IAAI,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC/E,IAAI,kBAAkB,IAAI,CAAC,iCAAiC,IAAI,KAAK,CAAC,EAAE,CAAC;oBACxE,OAAO;gBACR,CAAC;gBACD,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YACrC,CAAC;QACF,CAAC;QACD,oBAAoB,EAAE,CACrB,KAAgC,EAChC,KAAe,EACf,QAAyD,EAClD,EAAE;YACT,IAAI,kBAAkB,IAAI,YAAY,KAAK,SAAS,IAAI,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC/E,IAAI,kBAAkB,IAAI,CAAC,iCAAiC,IAAI,KAAK,CAAC,EAAE,CAAC;oBACxE,OAAO;gBACR,CAAC;gBACD,MAAM,CAAC,oBAAoB,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;YACrD,CAAC;QACF,CAAC;QACD,kBAAkB;KAClB,CAAC;IAEF,OAAO,aAAa,CAAC;AACtB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CAAI,aAAsB;IAChD,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;IAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AAC7B,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { ITelemetryBaseEvent, LogLevel } from \"@fluidframework/core-interfaces\";\n\nimport { loggerToMonitoringContext } from \"./config.js\";\nimport type {\n\tITelemetryGenericEventExt,\n\tTelemetryLoggerExt,\n} from \"./telemetryTypesUndeprecated.js\";\n\n/**\n * An object that contains a callback used in conjunction with the {@link createSampledLogger} utility function to provide custom logic for sampling events.\n *\n * @internal\n */\nexport interface IEventSampler {\n\t/**\n\t * @returns true if the event should be sampled or false if not\n\t */\n\tsample: () => boolean;\n}\n\n/**\n * A telemetry logger that has sampling capabilities\n *\n * @internal\n */\nexport interface ISampledTelemetryLogger extends TelemetryLoggerExt {\n\t/**\n\t * Indicates if the feature flag to disable sampling is set.\n\t *\n\t * @remarks Exposed to enable some advanced scenarios where the code using the sampled logger\n\t * could take advantage of skipping the execution of some logic when it can determine\n\t * it won't be necessary because the telemetry event that needs it wouldn't be\n\t * emitted anyway.\n\t */\n\tisSamplingDisabled: boolean;\n}\n\n/**\n * Wraps around an existing logger matching the {@link TelemetryLoggerExt} interface and provides the ability to only log a subset of events using a sampling strategy provided by an {@link IEventSampler}.\n * You can chose to not provide an event sampler which is effectively a no-op, meaning that it will be treated as if the sampler always returns true.\n *\n * @remarks\n * The sampling functionality uses the Fluid telemetry logging configuration along with the optionally provided event sampling callback to determine whether an event should\n * be logged or not.\n *\n * Configuration object parameters:\n * 'Fluid.Telemetry.DisableSampling': if this config value is set to true, all events will be unsampled and therefore logged.\n * Otherwise only a sample will be logged according to the provided event sampler callback.\n *\n * Note that the same sampler is used for all APIs of the returned logger. If you want separate events flowing through the returned logger to be sampled separately, the {@link IEventSampler} you provide should track them separately.\n *\n * @internal\n */\nexport function createSampledLogger(\n\tlogger: TelemetryLoggerExt,\n\teventSampler?: IEventSampler,\n\tskipLoggingWhenSamplingIsDisabled?: boolean,\n): ISampledTelemetryLogger {\n\tconst monitoringContext = loggerToMonitoringContext(logger);\n\tconst isSamplingDisabled =\n\t\tmonitoringContext.config.getBoolean(\"Fluid.Telemetry.DisableSampling\") ?? false;\n\n\tconst sampledLogger = {\n\t\tsend: (event: ITelemetryBaseEvent, logLevel?: LogLevel): void => {\n\t\t\t// The sampler uses the following logic for sending events:\n\t\t\t// 1. If isSamplingDisabled is true, then this means events should be unsampled. Therefore we send the event without any checks.\n\t\t\t// 2. If isSamplingDisabled is false, then event should be sampled using the event sampler, if the sampler is not defined just send all events, other use the eventSampler.sample() method.\n\t\t\t// 3. If skipLoggingWhenSamplingIsDisabled is true, then no event is sent.\n\t\t\tif (isSamplingDisabled || eventSampler === undefined || eventSampler.sample()) {\n\t\t\t\tif (isSamplingDisabled && (skipLoggingWhenSamplingIsDisabled ?? false)) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlogger.send(event, logLevel);\n\t\t\t}\n\t\t},\n\t\tsendTelemetryEvent: (\n\t\t\tevent: ITelemetryGenericEventExt,\n\t\t\terror?: unknown,\n\t\t\tlogLevel?: typeof LogLevel.verbose | typeof LogLevel.info,\n\t\t): void => {\n\t\t\tif (isSamplingDisabled || eventSampler === undefined || eventSampler.sample()) {\n\t\t\t\tif (isSamplingDisabled && (skipLoggingWhenSamplingIsDisabled ?? false)) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlogger.sendTelemetryEvent(event, error, logLevel);\n\t\t\t}\n\t\t},\n\t\tsendErrorEvent: (event: ITelemetryGenericEventExt, error?: unknown): void => {\n\t\t\tif (isSamplingDisabled || eventSampler === undefined || eventSampler.sample()) {\n\t\t\t\tif (isSamplingDisabled && (skipLoggingWhenSamplingIsDisabled ?? false)) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlogger.sendErrorEvent(event, error);\n\t\t\t}\n\t\t},\n\t\tsendPerformanceEvent: (\n\t\t\tevent: ITelemetryGenericEventExt,\n\t\t\terror?: unknown,\n\t\t\tlogLevel?: typeof LogLevel.verbose | typeof LogLevel.info,\n\t\t): void => {\n\t\t\tif (isSamplingDisabled || eventSampler === undefined || eventSampler.sample()) {\n\t\t\t\tif (isSamplingDisabled && (skipLoggingWhenSamplingIsDisabled ?? false)) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlogger.sendPerformanceEvent(event, error, logLevel);\n\t\t\t}\n\t\t},\n\t\tisSamplingDisabled,\n\t};\n\n\treturn sampledLogger;\n}\n\n/**\n * Runs the specified function and returns an object with the time it took to run as well as any output from it.\n * @remarks Useful in conjunction with {@link TelemetryEventBatcher}.\n *\n * @param codeToMeasure - The code to be executed and measured.\n * @returns The total duration of the code execution and whatever the passed-in code block returns.\n * @internal\n */\nexport function measure<T>(codeToMeasure: () => T): { duration: number; output: T } {\n\tconst start = performance.now();\n\tconst output = codeToMeasure();\n\tconst duration = performance.now() - start;\n\treturn { duration, output };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/telemetry-utils",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.101.0",
|
|
4
4
|
"description": "Collection of telemetry relates utilities for Fluid",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -69,17 +69,17 @@
|
|
|
69
69
|
"temp-directory": "nyc/.nyc_output"
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
|
-
"@fluid-internal/client-utils": "~2.
|
|
73
|
-
"@fluidframework/core-interfaces": "~2.
|
|
74
|
-
"@fluidframework/core-utils": "~2.
|
|
75
|
-
"@fluidframework/driver-definitions": "~2.
|
|
72
|
+
"@fluid-internal/client-utils": "~2.101.0",
|
|
73
|
+
"@fluidframework/core-interfaces": "~2.101.0",
|
|
74
|
+
"@fluidframework/core-utils": "~2.101.0",
|
|
75
|
+
"@fluidframework/driver-definitions": "~2.101.0",
|
|
76
76
|
"debug": "^4.3.4",
|
|
77
77
|
"uuid": "^11.1.0"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
80
|
"@arethetypeswrong/cli": "^0.18.2",
|
|
81
81
|
"@biomejs/biome": "~2.4.5",
|
|
82
|
-
"@fluid-internal/mocha-test-setup": "~2.
|
|
82
|
+
"@fluid-internal/mocha-test-setup": "~2.101.0",
|
|
83
83
|
"@fluid-tools/build-cli": "^0.65.0",
|
|
84
84
|
"@fluidframework/build-common": "^2.0.3",
|
|
85
85
|
"@fluidframework/build-tools": "^0.65.0",
|
package/src/config.ts
CHANGED
|
@@ -8,6 +8,7 @@ import type {
|
|
|
8
8
|
IConfigProviderBase,
|
|
9
9
|
ITelemetryBaseLogger,
|
|
10
10
|
} from "@fluidframework/core-interfaces";
|
|
11
|
+
import { LogLevel } from "@fluidframework/core-interfaces";
|
|
11
12
|
import { Lazy } from "@fluidframework/core-utils/internal";
|
|
12
13
|
|
|
13
14
|
import { createChildLogger, tagCodeArtifacts } from "./logger.js";
|
|
@@ -246,14 +247,17 @@ export class CachedConfigProvider implements IConfigProvider {
|
|
|
246
247
|
const parsed = stronglyTypedParse(provider?.getRawConfig(name));
|
|
247
248
|
if (parsed !== undefined) {
|
|
248
249
|
this.configCache.set(name, parsed);
|
|
249
|
-
this.logger?.send(
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
250
|
+
this.logger?.send(
|
|
251
|
+
{
|
|
252
|
+
category: "generic",
|
|
253
|
+
eventName: "ConfigRead",
|
|
254
|
+
...tagCodeArtifacts({
|
|
255
|
+
configName: name,
|
|
256
|
+
configValue: JSON.stringify(parsed),
|
|
257
|
+
}),
|
|
258
|
+
},
|
|
259
|
+
LogLevel.info,
|
|
260
|
+
);
|
|
257
261
|
return parsed;
|
|
258
262
|
}
|
|
259
263
|
}
|
package/src/logger.ts
CHANGED
|
@@ -224,18 +224,18 @@ export abstract class TelemetryLogger implements TelemetryLoggerExt {
|
|
|
224
224
|
*
|
|
225
225
|
* @param event - the event to send
|
|
226
226
|
* @param error - optional error object to log
|
|
227
|
-
* @param logLevel - optional level of the log.
|
|
228
|
-
*
|
|
227
|
+
* @param logLevel - optional level of the log. If the event's category is `error`,
|
|
228
|
+
* the logLevel will be upgraded to {@link @fluidframework/core-interfaces#LogLevelConst.essential | LogLevel.essential}.
|
|
229
229
|
*/
|
|
230
230
|
public sendTelemetryEvent(
|
|
231
231
|
event: ITelemetryGenericEventExt,
|
|
232
232
|
error?: unknown,
|
|
233
|
-
logLevel
|
|
233
|
+
logLevel?: typeof LogLevel.verbose | typeof LogLevel.info,
|
|
234
234
|
): void {
|
|
235
235
|
this.sendTelemetryEventCore(
|
|
236
236
|
{ ...event, category: event.category ?? "generic" },
|
|
237
237
|
error,
|
|
238
|
-
event.category === "error" ? LogLevel.
|
|
238
|
+
event.category === "error" ? LogLevel.essential : (logLevel ?? LogLevel.essential),
|
|
239
239
|
);
|
|
240
240
|
}
|
|
241
241
|
|
|
@@ -244,12 +244,12 @@ export abstract class TelemetryLogger implements TelemetryLoggerExt {
|
|
|
244
244
|
*
|
|
245
245
|
* @param event - the event to send
|
|
246
246
|
* @param error - optional error object to log
|
|
247
|
-
* @param logLevel -
|
|
247
|
+
* @param logLevel - level of the log.
|
|
248
248
|
*/
|
|
249
|
-
|
|
249
|
+
private sendTelemetryEventCore(
|
|
250
250
|
event: ITelemetryGenericEventExt & { category: TelemetryEventCategory },
|
|
251
|
-
error
|
|
252
|
-
logLevel
|
|
251
|
+
error: unknown,
|
|
252
|
+
logLevel: LogLevel,
|
|
253
253
|
): void {
|
|
254
254
|
const newEvent = convertToBaseEvent(event);
|
|
255
255
|
if (error !== undefined) {
|
|
@@ -280,7 +280,7 @@ export abstract class TelemetryLogger implements TelemetryLoggerExt {
|
|
|
280
280
|
category: "error",
|
|
281
281
|
},
|
|
282
282
|
error,
|
|
283
|
-
LogLevel.
|
|
283
|
+
LogLevel.essential,
|
|
284
284
|
);
|
|
285
285
|
}
|
|
286
286
|
|
|
@@ -289,13 +289,13 @@ export abstract class TelemetryLogger implements TelemetryLoggerExt {
|
|
|
289
289
|
*
|
|
290
290
|
* @param event - Event to send
|
|
291
291
|
* @param error - optional error object to log
|
|
292
|
-
* @param logLevel - optional level of the log.
|
|
293
|
-
*
|
|
292
|
+
* @param logLevel - optional level of the log. If the event's category is `error`,
|
|
293
|
+
* the logLevel will be upgraded to {@link @fluidframework/core-interfaces#LogLevelConst.essential | LogLevel.essential}.
|
|
294
294
|
*/
|
|
295
295
|
public sendPerformanceEvent(
|
|
296
296
|
event: ITelemetryPerformanceEventExt,
|
|
297
297
|
error?: unknown,
|
|
298
|
-
logLevel
|
|
298
|
+
logLevel?: typeof LogLevel.verbose | typeof LogLevel.info,
|
|
299
299
|
): void {
|
|
300
300
|
const perfEvent = {
|
|
301
301
|
...event,
|
|
@@ -305,7 +305,7 @@ export abstract class TelemetryLogger implements TelemetryLoggerExt {
|
|
|
305
305
|
this.sendTelemetryEventCore(
|
|
306
306
|
perfEvent,
|
|
307
307
|
error,
|
|
308
|
-
perfEvent.category === "error" ? LogLevel.
|
|
308
|
+
perfEvent.category === "error" ? LogLevel.essential : (logLevel ?? LogLevel.essential),
|
|
309
309
|
);
|
|
310
310
|
}
|
|
311
311
|
|
|
@@ -518,8 +518,8 @@ export class ChildLogger extends TelemetryLogger {
|
|
|
518
518
|
}
|
|
519
519
|
|
|
520
520
|
private shouldFilterOutEvent(event: ITelemetryBaseEvent, logLevel?: LogLevel): boolean {
|
|
521
|
-
const eventLogLevel = logLevel ?? LogLevel.
|
|
522
|
-
const configLogLevel = this.baseLogger.minLogLevel ?? LogLevel.
|
|
521
|
+
const eventLogLevel = logLevel ?? LogLevel.essential;
|
|
522
|
+
const configLogLevel = this.baseLogger.minLogLevel ?? LogLevel.info;
|
|
523
523
|
// Filter out in case event log level is below what is wanted in config.
|
|
524
524
|
return eventLogLevel < configLogLevel;
|
|
525
525
|
}
|
|
@@ -533,7 +533,7 @@ export class ChildLogger extends TelemetryLogger {
|
|
|
533
533
|
if (this.shouldFilterOutEvent(event, logLevel)) {
|
|
534
534
|
return;
|
|
535
535
|
}
|
|
536
|
-
this.baseLogger.send(this.prepareEvent(event), logLevel);
|
|
536
|
+
this.baseLogger.send(this.prepareEvent(event), logLevel ?? LogLevel.essential);
|
|
537
537
|
}
|
|
538
538
|
}
|
|
539
539
|
|
|
@@ -618,7 +618,7 @@ export class MultiSinkLogger extends TelemetryLogger {
|
|
|
618
618
|
|
|
619
619
|
super(namespace, realProperties);
|
|
620
620
|
this.loggers = loggers;
|
|
621
|
-
this._minLogLevelOfAllLoggers = LogLevel.
|
|
621
|
+
this._minLogLevelOfAllLoggers = LogLevel.info;
|
|
622
622
|
this.calculateMinLogLevel();
|
|
623
623
|
}
|
|
624
624
|
|
|
@@ -630,7 +630,7 @@ export class MultiSinkLogger extends TelemetryLogger {
|
|
|
630
630
|
if (this.loggers.length > 0) {
|
|
631
631
|
const logLevels: LogLevel[] = [];
|
|
632
632
|
for (const logger of this.loggers) {
|
|
633
|
-
logLevels.push(logger.minLogLevel ?? LogLevel.
|
|
633
|
+
logLevels.push(logger.minLogLevel ?? LogLevel.info);
|
|
634
634
|
}
|
|
635
635
|
this._minLogLevelOfAllLoggers = Math.min(...logLevels) as LogLevel;
|
|
636
636
|
}
|
|
@@ -653,10 +653,10 @@ export class MultiSinkLogger extends TelemetryLogger {
|
|
|
653
653
|
*
|
|
654
654
|
* @param event - the event to send to all the registered logger
|
|
655
655
|
*/
|
|
656
|
-
public send(event: ITelemetryBaseEvent): void {
|
|
656
|
+
public send(event: ITelemetryBaseEvent, logLevel?: LogLevel): void {
|
|
657
657
|
const newEvent = this.prepareEvent(event);
|
|
658
658
|
for (const logger of this.loggers) {
|
|
659
|
-
logger.send(newEvent);
|
|
659
|
+
logger.send(newEvent, logLevel ?? LogLevel.essential);
|
|
660
660
|
}
|
|
661
661
|
}
|
|
662
662
|
}
|
|
@@ -692,6 +692,8 @@ export class PerformanceEvent {
|
|
|
692
692
|
* @param recordHeapSize - whether or not to also record memory performance
|
|
693
693
|
* @param emitLogs - should this instance emit logs. If set to false, logs will not be emitted to the logger,
|
|
694
694
|
* but measurements will still be performed and any specified markers will be generated.
|
|
695
|
+
* @param logLevel - optional {@link LogLevel} for events emitted by this performance event.
|
|
696
|
+
* If unspecified, {@link @fluidframework/core-interfaces#LogLevelConst.essential | LogLevel.essential} will be used.
|
|
695
697
|
* @returns An instance of {@link PerformanceEvent}
|
|
696
698
|
*/
|
|
697
699
|
public static start(
|
|
@@ -699,8 +701,15 @@ export class PerformanceEvent {
|
|
|
699
701
|
event: ITelemetryGenericEventExt,
|
|
700
702
|
markers?: IPerformanceEventMarkers,
|
|
701
703
|
emitLogs: boolean = true,
|
|
704
|
+
logLevel?: typeof LogLevel.verbose | typeof LogLevel.info,
|
|
702
705
|
): PerformanceEvent {
|
|
703
|
-
return new PerformanceEvent(
|
|
706
|
+
return new PerformanceEvent(
|
|
707
|
+
extractTelemetryLoggerExt(logger),
|
|
708
|
+
event,
|
|
709
|
+
markers,
|
|
710
|
+
emitLogs,
|
|
711
|
+
logLevel,
|
|
712
|
+
);
|
|
704
713
|
}
|
|
705
714
|
|
|
706
715
|
/**
|
|
@@ -711,6 +720,8 @@ export class PerformanceEvent {
|
|
|
711
720
|
* @param markers - See {@link IPerformanceEventMarkers}
|
|
712
721
|
* @param sampleThreshold - events with the same name and category will be sent to the logger
|
|
713
722
|
* only when we hit this many executions of the task. If unspecified, all events will be sent.
|
|
723
|
+
* @param logLevel - optional {@link LogLevel} for events emitted by this performance event.
|
|
724
|
+
* If unspecified, {@link @fluidframework/core-interfaces#LogLevelConst.essential | LogLevel.essential} will be used.
|
|
714
725
|
* @returns The results of the executed task
|
|
715
726
|
*
|
|
716
727
|
* @remarks Note that if the "same" event (category + eventName) would be emitted by different
|
|
@@ -724,12 +735,14 @@ export class PerformanceEvent {
|
|
|
724
735
|
callback: (event: PerformanceEvent) => T,
|
|
725
736
|
markers?: IPerformanceEventMarkers,
|
|
726
737
|
sampleThreshold: number = 1,
|
|
738
|
+
logLevel?: typeof LogLevel.verbose | typeof LogLevel.info,
|
|
727
739
|
): T {
|
|
728
740
|
const perfEvent = PerformanceEvent.start(
|
|
729
741
|
logger,
|
|
730
742
|
event,
|
|
731
743
|
markers,
|
|
732
744
|
PerformanceEvent.shouldReport(event, sampleThreshold),
|
|
745
|
+
logLevel,
|
|
733
746
|
);
|
|
734
747
|
try {
|
|
735
748
|
const ret = callback(perfEvent);
|
|
@@ -750,6 +763,8 @@ export class PerformanceEvent {
|
|
|
750
763
|
* @param recordHeapSize - whether or not to also record memory performance
|
|
751
764
|
* @param sampleThreshold - events with the same name and category will be sent to the logger
|
|
752
765
|
* only when we hit this many executions of the task. If unspecified, all events will be sent.
|
|
766
|
+
* @param logLevel - optional {@link LogLevel} for events emitted by this performance event.
|
|
767
|
+
* If unspecified, {@link @fluidframework/core-interfaces#LogLevelConst.essential | LogLevel.essential} will be used.
|
|
753
768
|
* @returns The results of the executed task
|
|
754
769
|
*
|
|
755
770
|
* @remarks Note that if the "same" event (category + eventName) would be emitted by different
|
|
@@ -763,12 +778,14 @@ export class PerformanceEvent {
|
|
|
763
778
|
callback: (event: PerformanceEvent) => Promise<T>,
|
|
764
779
|
markers?: IPerformanceEventMarkers,
|
|
765
780
|
sampleThreshold: number = 1,
|
|
781
|
+
logLevel?: typeof LogLevel.verbose | typeof LogLevel.info,
|
|
766
782
|
): Promise<T> {
|
|
767
783
|
const perfEvent = PerformanceEvent.start(
|
|
768
784
|
logger,
|
|
769
785
|
event,
|
|
770
786
|
markers,
|
|
771
787
|
PerformanceEvent.shouldReport(event, sampleThreshold),
|
|
788
|
+
logLevel,
|
|
772
789
|
);
|
|
773
790
|
try {
|
|
774
791
|
const ret = await callback(perfEvent);
|
|
@@ -788,11 +805,12 @@ export class PerformanceEvent {
|
|
|
788
805
|
private readonly startTime = performanceNow();
|
|
789
806
|
private startMark?: string;
|
|
790
807
|
|
|
791
|
-
|
|
808
|
+
private constructor(
|
|
792
809
|
private readonly logger: TelemetryLoggerExt,
|
|
793
810
|
event: ITelemetryGenericEventExt,
|
|
794
811
|
private readonly markers: IPerformanceEventMarkers = { end: true, cancel: "generic" },
|
|
795
812
|
private readonly emitLogs: boolean = true,
|
|
813
|
+
private readonly logLevel: typeof LogLevel.verbose | typeof LogLevel.info | undefined,
|
|
796
814
|
) {
|
|
797
815
|
this.event = { ...event };
|
|
798
816
|
if (this.markers.start) {
|
|
@@ -877,7 +895,7 @@ export class PerformanceEvent {
|
|
|
877
895
|
event.duration = this.duration;
|
|
878
896
|
}
|
|
879
897
|
|
|
880
|
-
this.logger.sendPerformanceEvent(event, error);
|
|
898
|
+
this.logger.sendPerformanceEvent(event, error, this.logLevel);
|
|
881
899
|
}
|
|
882
900
|
|
|
883
901
|
private static readonly eventHits = new Map<string, number>();
|
package/src/mockLogger.ts
CHANGED
|
@@ -41,7 +41,7 @@ export class MockLogger implements ITelemetryBaseLogger {
|
|
|
41
41
|
public readonly minLogLevel: LogLevel;
|
|
42
42
|
|
|
43
43
|
public constructor(minLogLevel?: LogLevel) {
|
|
44
|
-
this.minLogLevel = minLogLevel ?? LogLevel.
|
|
44
|
+
this.minLogLevel = minLogLevel ?? LogLevel.info;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
/**
|
|
@@ -59,7 +59,7 @@ export class MockLogger implements ITelemetryBaseLogger {
|
|
|
59
59
|
* {@inheritDoc @fluidframework/core-interfaces#ITelemetryBaseLogger.send}
|
|
60
60
|
*/
|
|
61
61
|
public send(event: ITelemetryBaseEvent, logLevel?: LogLevel): void {
|
|
62
|
-
if ((logLevel ?? LogLevel.
|
|
62
|
+
if ((logLevel ?? LogLevel.essential) >= this.minLogLevel) {
|
|
63
63
|
this._events.push(event);
|
|
64
64
|
}
|
|
65
65
|
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import { performanceNow } from "@fluid-internal/client-utils";
|
|
7
7
|
import type { IDisposable, ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
|
|
8
|
+
import { LogLevel } from "@fluidframework/core-interfaces";
|
|
8
9
|
import { assert } from "@fluidframework/core-utils/internal";
|
|
9
10
|
|
|
10
11
|
import { roundToDecimalPlaces } from "./mathTools.js";
|
|
@@ -124,6 +125,9 @@ export type MeasureReturnType<TMeasureReturn, TCustomMetrics> = TCustomMetrics e
|
|
|
124
125
|
* of the specified code block.
|
|
125
126
|
* See the documentation of the `includeAggregateMetrics` parameter for additional details that can be included.
|
|
126
127
|
*
|
|
128
|
+
* Telemetry events emitted by this class (both at the sample threshold and on dispose) are sent with
|
|
129
|
+
* {@link @fluidframework/core-interfaces#LogLevelConst.info | LogLevel.info}.
|
|
130
|
+
*
|
|
127
131
|
* @typeParam TMeasurementReturn - The return type (in a vacuum) of the code block that will be measured, ignoring
|
|
128
132
|
* any custom metric data that might be required by this class. E.g., the code might just return a boolean.
|
|
129
133
|
* @typeParam TCustomMetrics - A type that contains the custom properties that will be used by an instance of this class
|
|
@@ -293,7 +297,11 @@ export class SampledTelemetryHelper<
|
|
|
293
297
|
...processedCustomData,
|
|
294
298
|
};
|
|
295
299
|
|
|
296
|
-
this.logger.sendPerformanceEvent(
|
|
300
|
+
this.logger.sendPerformanceEvent(
|
|
301
|
+
telemetryEvent,
|
|
302
|
+
undefined, // error
|
|
303
|
+
LogLevel.info,
|
|
304
|
+
);
|
|
297
305
|
this.measurementsMap.delete(bucket);
|
|
298
306
|
}
|
|
299
307
|
}
|
package/src/telemetryTypes.ts
CHANGED
|
@@ -136,14 +136,15 @@ export interface ITelemetryLoggerExt extends ITelemetryBaseLogger {
|
|
|
136
136
|
* Send an information telemetry event.
|
|
137
137
|
* @param event - Event to send.
|
|
138
138
|
* @param error - Optional error object to log.
|
|
139
|
-
* @param logLevel - Optional level of the log.
|
|
139
|
+
* @param logLevel - Optional level of the log. If undefined, the logLevel should be treated as {@link @fluidframework/core-interfaces#LogLevel.essential}.
|
|
140
|
+
* If the event's category is `error`, the logLevel will be upgraded to {@link @fluidframework/core-interfaces#LogLevel.essential}.
|
|
140
141
|
* @deprecated This method is being removed without a replacement.
|
|
141
142
|
* @see {@link https://github.com/microsoft/FluidFramework/issues/26910 | Issue #26910} for details.
|
|
142
143
|
*/
|
|
143
144
|
sendTelemetryEvent(
|
|
144
145
|
event: ITelemetryGenericEventExt,
|
|
145
146
|
error?: unknown,
|
|
146
|
-
logLevel?: typeof LogLevel.verbose | typeof LogLevel.
|
|
147
|
+
logLevel?: typeof LogLevel.verbose | typeof LogLevel.info,
|
|
147
148
|
): void;
|
|
148
149
|
|
|
149
150
|
/**
|
|
@@ -159,14 +160,15 @@ export interface ITelemetryLoggerExt extends ITelemetryBaseLogger {
|
|
|
159
160
|
* Send a performance telemetry event.
|
|
160
161
|
* @param event - Event to send
|
|
161
162
|
* @param error - Optional error object to log.
|
|
162
|
-
* @param logLevel - Optional level of the log.
|
|
163
|
+
* @param logLevel - Optional level of the log. If undefined, the logLevel should be treated as {@link @fluidframework/core-interfaces#LogLevel.essential}.
|
|
164
|
+
* If the event's category is `error`, the logLevel will be upgraded to {@link @fluidframework/core-interfaces#LogLevel.essential}.
|
|
163
165
|
* @deprecated This method is being removed without a replacement.
|
|
164
166
|
* @see {@link https://github.com/microsoft/FluidFramework/issues/26910 | Issue #26910} for details.
|
|
165
167
|
*/
|
|
166
168
|
sendPerformanceEvent(
|
|
167
169
|
event: ITelemetryPerformanceEventExt,
|
|
168
170
|
error?: unknown,
|
|
169
|
-
logLevel?: typeof LogLevel.verbose | typeof LogLevel.
|
|
171
|
+
logLevel?: typeof LogLevel.verbose | typeof LogLevel.info,
|
|
170
172
|
): void;
|
|
171
173
|
}
|
|
172
174
|
|
|
@@ -183,12 +185,13 @@ export interface TelemetryLoggerExt extends ITelemetryBaseLogger {
|
|
|
183
185
|
* Send an information telemetry event.
|
|
184
186
|
* @param event - Event to send.
|
|
185
187
|
* @param error - Optional error object to log.
|
|
186
|
-
* @param logLevel - Optional level of the log.
|
|
188
|
+
* @param logLevel - Optional level of the log. If undefined, the logLevel will be treated as {@link @fluidframework/core-interfaces#LogLevelConst.essential | LogLevel.essential}.
|
|
189
|
+
* If the event's category is `error`, the logLevel will be upgraded to {@link @fluidframework/core-interfaces#LogLevelConst.essential | LogLevel.essential}.
|
|
187
190
|
*/
|
|
188
191
|
sendTelemetryEvent(
|
|
189
192
|
event: ITelemetryGenericEventExt,
|
|
190
193
|
error?: unknown,
|
|
191
|
-
logLevel?: typeof LogLevel.verbose | typeof LogLevel.
|
|
194
|
+
logLevel?: typeof LogLevel.verbose | typeof LogLevel.info,
|
|
192
195
|
): void;
|
|
193
196
|
|
|
194
197
|
/**
|
|
@@ -202,11 +205,12 @@ export interface TelemetryLoggerExt extends ITelemetryBaseLogger {
|
|
|
202
205
|
* Send a performance telemetry event.
|
|
203
206
|
* @param event - Event to send
|
|
204
207
|
* @param error - Optional error object to log.
|
|
205
|
-
* @param logLevel - Optional level of the log.
|
|
208
|
+
* @param logLevel - Optional level of the log. If undefined, the logLevel will be treated as {@link @fluidframework/core-interfaces#LogLevelConst.essential | LogLevel.essential}.
|
|
209
|
+
* If the event's category is `error`, the logLevel will be upgraded to {@link @fluidframework/core-interfaces#LogLevelConst.essential | LogLevel.essential}.
|
|
206
210
|
*/
|
|
207
211
|
sendPerformanceEvent(
|
|
208
212
|
event: ITelemetryPerformanceEventExt,
|
|
209
213
|
error?: unknown,
|
|
210
|
-
logLevel?: typeof LogLevel.verbose | typeof LogLevel.
|
|
214
|
+
logLevel?: typeof LogLevel.verbose | typeof LogLevel.info,
|
|
211
215
|
): void;
|
|
212
216
|
}
|
package/src/utils.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type { ITelemetryBaseEvent } from "@fluidframework/core-interfaces";
|
|
6
|
+
import type { ITelemetryBaseEvent, LogLevel } from "@fluidframework/core-interfaces";
|
|
7
7
|
|
|
8
8
|
import { loggerToMonitoringContext } from "./config.js";
|
|
9
9
|
import type {
|
|
@@ -66,7 +66,7 @@ export function createSampledLogger(
|
|
|
66
66
|
monitoringContext.config.getBoolean("Fluid.Telemetry.DisableSampling") ?? false;
|
|
67
67
|
|
|
68
68
|
const sampledLogger = {
|
|
69
|
-
send: (event: ITelemetryBaseEvent): void => {
|
|
69
|
+
send: (event: ITelemetryBaseEvent, logLevel?: LogLevel): void => {
|
|
70
70
|
// The sampler uses the following logic for sending events:
|
|
71
71
|
// 1. If isSamplingDisabled is true, then this means events should be unsampled. Therefore we send the event without any checks.
|
|
72
72
|
// 2. If isSamplingDisabled is false, then event should be sampled using the event sampler, if the sampler is not defined just send all events, other use the eventSampler.sample() method.
|
|
@@ -75,31 +75,39 @@ export function createSampledLogger(
|
|
|
75
75
|
if (isSamplingDisabled && (skipLoggingWhenSamplingIsDisabled ?? false)) {
|
|
76
76
|
return;
|
|
77
77
|
}
|
|
78
|
-
logger.send(event);
|
|
78
|
+
logger.send(event, logLevel);
|
|
79
79
|
}
|
|
80
80
|
},
|
|
81
|
-
sendTelemetryEvent: (
|
|
81
|
+
sendTelemetryEvent: (
|
|
82
|
+
event: ITelemetryGenericEventExt,
|
|
83
|
+
error?: unknown,
|
|
84
|
+
logLevel?: typeof LogLevel.verbose | typeof LogLevel.info,
|
|
85
|
+
): void => {
|
|
82
86
|
if (isSamplingDisabled || eventSampler === undefined || eventSampler.sample()) {
|
|
83
87
|
if (isSamplingDisabled && (skipLoggingWhenSamplingIsDisabled ?? false)) {
|
|
84
88
|
return;
|
|
85
89
|
}
|
|
86
|
-
logger.sendTelemetryEvent(event);
|
|
90
|
+
logger.sendTelemetryEvent(event, error, logLevel);
|
|
87
91
|
}
|
|
88
92
|
},
|
|
89
|
-
sendErrorEvent: (event: ITelemetryGenericEventExt): void => {
|
|
93
|
+
sendErrorEvent: (event: ITelemetryGenericEventExt, error?: unknown): void => {
|
|
90
94
|
if (isSamplingDisabled || eventSampler === undefined || eventSampler.sample()) {
|
|
91
95
|
if (isSamplingDisabled && (skipLoggingWhenSamplingIsDisabled ?? false)) {
|
|
92
96
|
return;
|
|
93
97
|
}
|
|
94
|
-
logger.sendErrorEvent(event);
|
|
98
|
+
logger.sendErrorEvent(event, error);
|
|
95
99
|
}
|
|
96
100
|
},
|
|
97
|
-
sendPerformanceEvent: (
|
|
101
|
+
sendPerformanceEvent: (
|
|
102
|
+
event: ITelemetryGenericEventExt,
|
|
103
|
+
error?: unknown,
|
|
104
|
+
logLevel?: typeof LogLevel.verbose | typeof LogLevel.info,
|
|
105
|
+
): void => {
|
|
98
106
|
if (isSamplingDisabled || eventSampler === undefined || eventSampler.sample()) {
|
|
99
107
|
if (isSamplingDisabled && (skipLoggingWhenSamplingIsDisabled ?? false)) {
|
|
100
108
|
return;
|
|
101
109
|
}
|
|
102
|
-
logger.sendPerformanceEvent(event);
|
|
110
|
+
logger.sendPerformanceEvent(event, error, logLevel);
|
|
103
111
|
}
|
|
104
112
|
},
|
|
105
113
|
isSamplingDisabled,
|