@fluidframework/telemetry-utils 2.0.0-dev.5.2.0.169897 → 2.0.0-dev.6.4.0.191258

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 (122) hide show
  1. package/.eslintrc.js +2 -1
  2. package/CHANGELOG.md +126 -0
  3. package/README.md +4 -3
  4. package/dist/config.d.ts +4 -2
  5. package/dist/config.d.ts.map +1 -1
  6. package/dist/config.js +36 -38
  7. package/dist/config.js.map +1 -1
  8. package/dist/error.d.ts +92 -0
  9. package/dist/error.d.ts.map +1 -0
  10. package/dist/error.js +133 -0
  11. package/dist/error.js.map +1 -0
  12. package/dist/errorLogging.d.ts +44 -19
  13. package/dist/errorLogging.d.ts.map +1 -1
  14. package/dist/errorLogging.js +70 -31
  15. package/dist/errorLogging.js.map +1 -1
  16. package/dist/eventEmitterWithErrorHandling.d.ts +3 -3
  17. package/dist/eventEmitterWithErrorHandling.d.ts.map +1 -1
  18. package/dist/eventEmitterWithErrorHandling.js +10 -3
  19. package/dist/eventEmitterWithErrorHandling.js.map +1 -1
  20. package/dist/events.d.ts +1 -1
  21. package/dist/events.d.ts.map +1 -1
  22. package/dist/events.js.map +1 -1
  23. package/dist/fluidErrorBase.d.ts +49 -16
  24. package/dist/fluidErrorBase.d.ts.map +1 -1
  25. package/dist/fluidErrorBase.js +21 -14
  26. package/dist/fluidErrorBase.js.map +1 -1
  27. package/dist/index.d.ts +5 -5
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +16 -8
  30. package/dist/index.js.map +1 -1
  31. package/dist/logger.d.ts +98 -60
  32. package/dist/logger.d.ts.map +1 -1
  33. package/dist/logger.js +193 -124
  34. package/dist/logger.js.map +1 -1
  35. package/dist/mockLogger.d.ts +17 -8
  36. package/dist/mockLogger.d.ts.map +1 -1
  37. package/dist/mockLogger.js +49 -28
  38. package/dist/mockLogger.js.map +1 -1
  39. package/dist/sampledTelemetryHelper.d.ts +9 -8
  40. package/dist/sampledTelemetryHelper.d.ts.map +1 -1
  41. package/dist/sampledTelemetryHelper.js +21 -16
  42. package/dist/sampledTelemetryHelper.js.map +1 -1
  43. package/dist/telemetryTypes.d.ts +20 -6
  44. package/dist/telemetryTypes.d.ts.map +1 -1
  45. package/dist/telemetryTypes.js.map +1 -1
  46. package/dist/thresholdCounter.d.ts.map +1 -1
  47. package/dist/thresholdCounter.js.map +1 -1
  48. package/dist/utils.d.ts +3 -3
  49. package/dist/utils.d.ts.map +1 -1
  50. package/dist/utils.js +2 -2
  51. package/dist/utils.js.map +1 -1
  52. package/lib/config.d.ts +4 -2
  53. package/lib/config.d.ts.map +1 -1
  54. package/lib/config.js +34 -37
  55. package/lib/config.js.map +1 -1
  56. package/lib/error.d.ts +92 -0
  57. package/lib/error.d.ts.map +1 -0
  58. package/lib/error.js +125 -0
  59. package/lib/error.js.map +1 -0
  60. package/lib/errorLogging.d.ts +44 -19
  61. package/lib/errorLogging.d.ts.map +1 -1
  62. package/lib/errorLogging.js +69 -31
  63. package/lib/errorLogging.js.map +1 -1
  64. package/lib/eventEmitterWithErrorHandling.d.ts +3 -3
  65. package/lib/eventEmitterWithErrorHandling.d.ts.map +1 -1
  66. package/lib/eventEmitterWithErrorHandling.js +9 -2
  67. package/lib/eventEmitterWithErrorHandling.js.map +1 -1
  68. package/lib/events.d.ts +1 -1
  69. package/lib/events.d.ts.map +1 -1
  70. package/lib/events.js.map +1 -1
  71. package/lib/fluidErrorBase.d.ts +49 -16
  72. package/lib/fluidErrorBase.d.ts.map +1 -1
  73. package/lib/fluidErrorBase.js +21 -14
  74. package/lib/fluidErrorBase.js.map +1 -1
  75. package/lib/index.d.ts +5 -5
  76. package/lib/index.d.ts.map +1 -1
  77. package/lib/index.js +4 -4
  78. package/lib/index.js.map +1 -1
  79. package/lib/logger.d.ts +98 -60
  80. package/lib/logger.d.ts.map +1 -1
  81. package/lib/logger.js +184 -119
  82. package/lib/logger.js.map +1 -1
  83. package/lib/mockLogger.d.ts +17 -8
  84. package/lib/mockLogger.d.ts.map +1 -1
  85. package/lib/mockLogger.js +50 -29
  86. package/lib/mockLogger.js.map +1 -1
  87. package/lib/sampledTelemetryHelper.d.ts +9 -8
  88. package/lib/sampledTelemetryHelper.d.ts.map +1 -1
  89. package/lib/sampledTelemetryHelper.js +19 -14
  90. package/lib/sampledTelemetryHelper.js.map +1 -1
  91. package/lib/telemetryTypes.d.ts +20 -6
  92. package/lib/telemetryTypes.d.ts.map +1 -1
  93. package/lib/telemetryTypes.js.map +1 -1
  94. package/lib/thresholdCounter.d.ts.map +1 -1
  95. package/lib/thresholdCounter.js.map +1 -1
  96. package/lib/utils.d.ts +3 -3
  97. package/lib/utils.d.ts.map +1 -1
  98. package/lib/utils.js +2 -2
  99. package/lib/utils.js.map +1 -1
  100. package/package.json +21 -44
  101. package/src/config.ts +25 -15
  102. package/src/error.ts +202 -0
  103. package/src/errorLogging.ts +102 -57
  104. package/src/eventEmitterWithErrorHandling.ts +5 -3
  105. package/src/events.ts +3 -3
  106. package/src/fluidErrorBase.ts +63 -27
  107. package/src/index.ts +17 -6
  108. package/src/logger.ts +291 -121
  109. package/src/mockLogger.ts +65 -24
  110. package/src/sampledTelemetryHelper.ts +20 -16
  111. package/src/telemetryTypes.ts +29 -6
  112. package/src/thresholdCounter.ts +2 -2
  113. package/src/utils.ts +3 -3
  114. package/dist/debugLogger.d.ts +0 -39
  115. package/dist/debugLogger.d.ts.map +0 -1
  116. package/dist/debugLogger.js +0 -112
  117. package/dist/debugLogger.js.map +0 -1
  118. package/lib/debugLogger.d.ts +0 -39
  119. package/lib/debugLogger.d.ts.map +0 -1
  120. package/lib/debugLogger.js +0 -108
  121. package/lib/debugLogger.js.map +0 -1
  122. package/src/debugLogger.ts +0 -143
package/lib/logger.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.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 {\n\tITelemetryBaseEvent,\n\tITelemetryBaseLogger,\n\tITelemetryErrorEvent,\n\tITelemetryGenericEvent,\n\tITelemetryPerformanceEvent,\n\tITelemetryProperties,\n\tTelemetryEventPropertyType,\n\tITaggedTelemetryPropertyType,\n\tTelemetryEventCategory,\n} from \"@fluidframework/common-definitions\";\nimport { IsomorphicPerformance, performance } from \"@fluidframework/common-utils\";\nimport { CachedConfigProvider, loggerIsMonitoringContext, mixinMonitoringContext } from \"./config\";\nimport {\n\tisILoggingError,\n\textractLogSafeErrorProperties,\n\tgenerateStack,\n\tisTaggedTelemetryPropertyValue,\n} from \"./errorLogging\";\nimport {\n\tITaggedTelemetryPropertyTypeExt,\n\tITelemetryEventExt,\n\tITelemetryGenericEventExt,\n\tITelemetryLoggerExt,\n\tITelemetryPerformanceEventExt,\n\tTelemetryEventPropertyTypeExt,\n} from \"./telemetryTypes\";\n\nexport interface Memory {\n\tusedJSHeapSize: number;\n}\n\nexport interface PerformanceWithMemory extends IsomorphicPerformance {\n\treadonly memory: Memory;\n}\n/**\n * Broad classifications to be applied to individual properties as they're prepared to be logged to telemetry.\n * Please do not modify existing entries for backwards compatibility.\n */\nexport enum TelemetryDataTag {\n\t/** Data containing terms or IDs from code packages that may have been dynamically loaded */\n\tCodeArtifact = \"CodeArtifact\",\n\t/** Personal data of a variety of classifications that pertains to the user */\n\tUserData = \"UserData\",\n}\n\nexport type TelemetryEventPropertyTypes = TelemetryEventPropertyType | ITaggedTelemetryPropertyType;\n\nexport interface ITelemetryLoggerPropertyBag {\n\t[index: string]: TelemetryEventPropertyTypes | (() => TelemetryEventPropertyTypes);\n}\nexport interface ITelemetryLoggerPropertyBags {\n\tall?: ITelemetryLoggerPropertyBag;\n\terror?: ITelemetryLoggerPropertyBag;\n}\n\n/**\n * TelemetryLogger class contains various helper telemetry methods,\n * encoding in one place schemas for various types of Fluid telemetry events.\n * Creates sub-logger that appends properties to all events\n */\nexport abstract class TelemetryLogger implements ITelemetryLoggerExt {\n\tpublic static readonly eventNamespaceSeparator = \":\";\n\n\tpublic static formatTick(tick: number): number {\n\t\treturn Math.floor(tick);\n\t}\n\n\t/**\n\t * Attempts to parse number from string.\n\t * If fails,returns original string.\n\t * Used to make telemetry data typed (and support math operations, like comparison),\n\t * in places where we do expect numbers (like contentsize/duration property in http header)\n\t */\n\tpublic static numberFromString(str: string | null | undefined): string | number | undefined {\n\t\tif (str === undefined || str === null) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst num = Number(str);\n\t\treturn Number.isNaN(num) ? str : num;\n\t}\n\n\tpublic static sanitizePkgName(name: string) {\n\t\treturn name.replace(\"@\", \"\").replace(\"/\", \"-\");\n\t}\n\n\t/**\n\t * Take an unknown error object and add the appropriate info from it to the event. Message and stack will be copied\n\t * over from the error object, along with other telemetry properties if it's an ILoggingError.\n\t * @param event - Event being logged\n\t * @param error - Error to extract info from\n\t * @param fetchStack - Whether to fetch the current callstack if error.stack is undefined\n\t */\n\tpublic static prepareErrorObject(event: ITelemetryBaseEvent, error: any, fetchStack: boolean) {\n\t\tconst { message, errorType, stack } = extractLogSafeErrorProperties(\n\t\t\terror,\n\t\t\ttrue /* sanitizeStack */,\n\t\t);\n\t\t// First, copy over error message, stack, and errorType directly (overwrite if present on event)\n\t\tevent.stack = stack;\n\t\tevent.error = message; // Note that the error message goes on the 'error' field\n\t\tevent.errorType = errorType;\n\n\t\tif (isILoggingError(error)) {\n\t\t\t// Add any other telemetry properties from the LoggingError\n\t\t\tconst telemetryProp = error.getTelemetryProperties();\n\t\t\tfor (const key of Object.keys(telemetryProp)) {\n\t\t\t\tif (event[key] !== undefined) {\n\t\t\t\t\t// Don't overwrite existing properties on the event\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tevent[key] = telemetryProp[key];\n\t\t\t}\n\t\t}\n\n\t\t// Collect stack if we were not able to extract it from error\n\t\tif (event.stack === undefined && fetchStack) {\n\t\t\tevent.stack = generateStack();\n\t\t}\n\t}\n\n\tpublic constructor(\n\t\tprotected readonly namespace?: string,\n\t\tprotected readonly properties?: ITelemetryLoggerPropertyBags,\n\t) {}\n\n\t/**\n\t * Send an event with the logger\n\t *\n\t * @param event - the event to send\n\t */\n\tpublic abstract send(event: ITelemetryBaseEvent): void;\n\n\t/**\n\t * Send a telemetry event with the logger\n\t *\n\t * @param event - the event to send\n\t * @param error - optional error object to log\n\t */\n\tpublic sendTelemetryEvent(event: ITelemetryGenericEventExt, error?: any) {\n\t\tthis.sendTelemetryEventCore({ ...event, category: event.category ?? \"generic\" }, error);\n\t}\n\n\t/**\n\t * Send a telemetry event with the logger\n\t *\n\t * @param event - the event to send\n\t * @param error - optional error object to log\n\t */\n\tprotected sendTelemetryEventCore(\n\t\tevent: ITelemetryGenericEventExt & { category: TelemetryEventCategory },\n\t\terror?: any,\n\t) {\n\t\tconst newEvent = convertToBaseEvent(event);\n\t\tif (error !== undefined) {\n\t\t\tTelemetryLogger.prepareErrorObject(newEvent, error, false);\n\t\t}\n\n\t\t// Will include Nan & Infinity, but probably we do not care\n\t\tif (typeof newEvent.duration === \"number\") {\n\t\t\tnewEvent.duration = TelemetryLogger.formatTick(newEvent.duration);\n\t\t}\n\n\t\tthis.send(newEvent);\n\t}\n\n\t/**\n\t * Send an error telemetry event with the logger\n\t *\n\t * @param event - the event to send\n\t * @param error - optional error object to log\n\t */\n\tpublic sendErrorEvent(event: ITelemetryErrorEvent, error?: any) {\n\t\tthis.sendTelemetryEventCore(\n\t\t\t{\n\t\t\t\t// ensure the error field has some value,\n\t\t\t\t// this can and will be overridden by event, or error\n\t\t\t\terror: event.eventName,\n\t\t\t\t...event,\n\t\t\t\tcategory: \"error\",\n\t\t\t},\n\t\t\terror,\n\t\t);\n\t}\n\n\t/**\n\t * Send a performance telemetry event with the logger\n\t *\n\t * @param event - Event to send\n\t * @param error - optional error object to log\n\t */\n\tpublic sendPerformanceEvent(event: ITelemetryPerformanceEventExt, error?: any): void {\n\t\tconst perfEvent = {\n\t\t\t...event,\n\t\t\tcategory: event.category ?? \"performance\",\n\t\t};\n\n\t\tthis.sendTelemetryEventCore(perfEvent, error);\n\t}\n\n\tprotected prepareEvent(event: ITelemetryBaseEvent): ITelemetryBaseEvent {\n\t\tconst includeErrorProps = event.category === \"error\" || event.error !== undefined;\n\t\tconst newEvent: ITelemetryBaseEvent = {\n\t\t\t...event,\n\t\t};\n\t\tif (this.namespace !== undefined) {\n\t\t\tnewEvent.eventName = `${this.namespace}${TelemetryLogger.eventNamespaceSeparator}${newEvent.eventName}`;\n\t\t}\n\t\tif (this.properties) {\n\t\t\tconst properties: (undefined | ITelemetryLoggerPropertyBag)[] = [];\n\t\t\tproperties.push(this.properties.all);\n\t\t\tif (includeErrorProps) {\n\t\t\t\tproperties.push(this.properties.error);\n\t\t\t}\n\t\t\tfor (const props of properties) {\n\t\t\t\tif (props !== undefined) {\n\t\t\t\t\tfor (const key of Object.keys(props)) {\n\t\t\t\t\t\tif (event[key] !== undefined) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst getterOrValue = props[key];\n\t\t\t\t\t\t// If this throws, hopefully it is handled elsewhere\n\t\t\t\t\t\tconst value =\n\t\t\t\t\t\t\ttypeof getterOrValue === \"function\" ? getterOrValue() : getterOrValue;\n\t\t\t\t\t\tif (value !== undefined) {\n\t\t\t\t\t\t\tnewEvent[key] = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn newEvent;\n\t}\n}\n\n/**\n * @deprecated 0.56, remove TaggedLoggerAdapter once its usage is removed from\n * container-runtime. Issue: #8191\n * TaggedLoggerAdapter class can add tag handling to your logger.\n */\nexport class TaggedLoggerAdapter implements ITelemetryBaseLogger {\n\tpublic constructor(private readonly logger: ITelemetryBaseLogger) {}\n\n\tpublic send(eventWithTagsMaybe: ITelemetryBaseEvent) {\n\t\tconst newEvent: ITelemetryBaseEvent = {\n\t\t\tcategory: eventWithTagsMaybe.category,\n\t\t\teventName: eventWithTagsMaybe.eventName,\n\t\t};\n\t\tfor (const key of Object.keys(eventWithTagsMaybe)) {\n\t\t\tconst taggableProp = eventWithTagsMaybe[key];\n\t\t\tconst { value, tag } =\n\t\t\t\ttypeof taggableProp === \"object\"\n\t\t\t\t\t? taggableProp\n\t\t\t\t\t: { value: taggableProp, tag: undefined };\n\t\t\tswitch (tag) {\n\t\t\t\tcase undefined:\n\t\t\t\t\t// No tag means we can log plainly\n\t\t\t\t\tnewEvent[key] = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"PackageData\": // For back-compat\n\t\t\t\tcase TelemetryDataTag.CodeArtifact:\n\t\t\t\t\t// For Microsoft applications, CodeArtifact is safe for now\n\t\t\t\t\t// (we don't load 3P code in 1P apps)\n\t\t\t\t\tnewEvent[key] = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TelemetryDataTag.UserData:\n\t\t\t\t\t// Strip out anything tagged explicitly as UserData.\n\t\t\t\t\t// Alternate strategy would be to hash these props\n\t\t\t\t\tnewEvent[key] = \"REDACTED (UserData)\";\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t// If we encounter a tag we don't recognize\n\t\t\t\t\t// then we must assume we should scrub.\n\t\t\t\t\tnewEvent[key] = \"REDACTED (unknown tag)\";\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tthis.logger.send(newEvent);\n\t}\n}\n\n/**\n * ChildLogger class contains various helper telemetry methods,\n * encoding in one place schemas for various types of Fluid telemetry events.\n * Creates sub-logger that appends properties to all events\n */\nexport class ChildLogger extends TelemetryLogger {\n\t/**\n\t * Create child logger\n\t * @param baseLogger - Base logger to use to output events. If undefined, proper child logger\n\t * is created, but it does not send telemetry events anywhere.\n\t * @param namespace - Telemetry event name prefix to add to all events\n\t * @param properties - Base properties to add to all events\n\t */\n\tpublic static create(\n\t\tbaseLogger?: ITelemetryBaseLogger,\n\t\tnamespace?: string,\n\t\tproperties?: ITelemetryLoggerPropertyBags,\n\t): TelemetryLogger {\n\t\t// if we are creating a child of a child, rather than nest, which will increase\n\t\t// the callstack overhead, just generate a new logger that includes everything from the previous\n\t\tif (baseLogger instanceof ChildLogger) {\n\t\t\tconst combinedProperties: ITelemetryLoggerPropertyBags = {};\n\t\t\tfor (const extendedProps of [baseLogger.properties, properties]) {\n\t\t\t\tif (extendedProps !== undefined) {\n\t\t\t\t\tif (extendedProps.all !== undefined) {\n\t\t\t\t\t\tcombinedProperties.all = {\n\t\t\t\t\t\t\t...combinedProperties.all,\n\t\t\t\t\t\t\t...extendedProps.all,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tif (extendedProps.error !== undefined) {\n\t\t\t\t\t\tcombinedProperties.error = {\n\t\t\t\t\t\t\t...combinedProperties.error,\n\t\t\t\t\t\t\t...extendedProps.error,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst combinedNamespace =\n\t\t\t\tbaseLogger.namespace === undefined\n\t\t\t\t\t? namespace\n\t\t\t\t\t: namespace === undefined\n\t\t\t\t\t? baseLogger.namespace\n\t\t\t\t\t: `${baseLogger.namespace}${TelemetryLogger.eventNamespaceSeparator}${namespace}`;\n\n\t\t\treturn new ChildLogger(baseLogger.baseLogger, combinedNamespace, combinedProperties);\n\t\t}\n\n\t\treturn new ChildLogger(\n\t\t\tbaseLogger ? baseLogger : new BaseTelemetryNullLogger(),\n\t\t\tnamespace,\n\t\t\tproperties,\n\t\t);\n\t}\n\n\tprivate constructor(\n\t\tprotected readonly baseLogger: ITelemetryBaseLogger,\n\t\tnamespace: string | undefined,\n\t\tproperties: ITelemetryLoggerPropertyBags | undefined,\n\t) {\n\t\tsuper(namespace, properties);\n\n\t\t// propagate the monitoring context\n\t\tif (loggerIsMonitoringContext(baseLogger)) {\n\t\t\tmixinMonitoringContext(this, new CachedConfigProvider(this, baseLogger.config));\n\t\t}\n\t}\n\n\t/**\n\t * Send an event with the logger\n\t *\n\t * @param event - the event to send\n\t */\n\tpublic send(event: ITelemetryBaseEvent): void {\n\t\tthis.baseLogger.send(this.prepareEvent(event));\n\t}\n}\n\n/**\n * Multi-sink logger\n * Takes multiple ITelemetryBaseLogger objects (sinks) and logs all events into each sink\n */\nexport class MultiSinkLogger extends TelemetryLogger {\n\tprotected loggers: ITelemetryBaseLogger[] = [];\n\n\t/**\n\t * Create multiple sink logger (i.e. logger that sends events to multiple sinks)\n\t * @param namespace - Telemetry event name prefix to add to all events\n\t * @param properties - Base properties to add to all events\n\t */\n\tconstructor(namespace?: string, properties?: ITelemetryLoggerPropertyBags) {\n\t\tsuper(namespace, properties);\n\t}\n\n\t/**\n\t * Add logger to send all events to\n\t * @param logger - Logger to add\n\t */\n\tpublic addLogger(logger?: ITelemetryBaseLogger) {\n\t\tif (logger !== undefined && logger !== null) {\n\t\t\tthis.loggers.push(logger);\n\t\t}\n\t}\n\n\t/**\n\t * Send an event to the loggers\n\t *\n\t * @param event - the event to send to all the registered logger\n\t */\n\tpublic send(event: ITelemetryBaseEvent): void {\n\t\tconst newEvent = this.prepareEvent(event);\n\t\tthis.loggers.forEach((logger: ITelemetryBaseLogger) => {\n\t\t\tlogger.send(newEvent);\n\t\t});\n\t}\n}\n\n/**\n * Describes what events PerformanceEvent should log\n * By default, all events are logged, but client can override this behavior\n * For example, there is rarely a need to record start event, as we really after\n * success / failure tracking, including duration (on success).\n */\nexport interface IPerformanceEventMarkers {\n\tstart?: true;\n\tend?: true;\n\tcancel?: \"generic\" | \"error\"; // tells wether to issue \"generic\" or \"error\" category cancel event\n}\n\n/**\n * Helper class to log performance events\n */\nexport class PerformanceEvent {\n\tpublic static start(\n\t\tlogger: ITelemetryLoggerExt,\n\t\tevent: ITelemetryGenericEvent,\n\t\tmarkers?: IPerformanceEventMarkers,\n\t\trecordHeapSize: boolean = false,\n\t) {\n\t\treturn new PerformanceEvent(logger, event, markers, recordHeapSize);\n\t}\n\n\tpublic static timedExec<T>(\n\t\tlogger: ITelemetryLoggerExt,\n\t\tevent: ITelemetryGenericEvent,\n\t\tcallback: (event: PerformanceEvent) => T,\n\t\tmarkers?: IPerformanceEventMarkers,\n\t) {\n\t\tconst perfEvent = PerformanceEvent.start(logger, event, markers);\n\t\ttry {\n\t\t\tconst ret = callback(perfEvent);\n\t\t\tperfEvent.autoEnd();\n\t\t\treturn ret;\n\t\t} catch (error) {\n\t\t\tperfEvent.cancel(undefined, error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tpublic static async timedExecAsync<T>(\n\t\tlogger: ITelemetryLoggerExt,\n\t\tevent: ITelemetryGenericEvent,\n\t\tcallback: (event: PerformanceEvent) => Promise<T>,\n\t\tmarkers?: IPerformanceEventMarkers,\n\t\trecordHeapSize?: boolean,\n\t) {\n\t\tconst perfEvent = PerformanceEvent.start(logger, event, markers, recordHeapSize);\n\t\ttry {\n\t\t\tconst ret = await callback(perfEvent);\n\t\t\tperfEvent.autoEnd();\n\t\t\treturn ret;\n\t\t} catch (error) {\n\t\t\tperfEvent.cancel(undefined, error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tpublic get duration() {\n\t\treturn performance.now() - this.startTime;\n\t}\n\n\tprivate event?: ITelemetryGenericEvent;\n\tprivate readonly startTime = performance.now();\n\tprivate startMark?: string;\n\tprivate startMemoryCollection: number | undefined = 0;\n\n\tprotected constructor(\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t\tevent: ITelemetryGenericEvent,\n\t\tprivate readonly markers: IPerformanceEventMarkers = { end: true, cancel: \"generic\" },\n\t\tprivate readonly recordHeapSize: boolean = false,\n\t) {\n\t\tthis.event = { ...event };\n\t\tif (this.markers.start) {\n\t\t\tthis.reportEvent(\"start\");\n\t\t}\n\n\t\tif (typeof window === \"object\" && window != null && window.performance?.mark) {\n\t\t\tthis.startMark = `${event.eventName}-start`;\n\t\t\twindow.performance.mark(this.startMark);\n\t\t}\n\t}\n\n\tpublic reportProgress(props?: ITelemetryProperties, eventNameSuffix: string = \"update\"): void {\n\t\tthis.reportEvent(eventNameSuffix, props);\n\t}\n\n\tprivate autoEnd() {\n\t\t// Event might have been cancelled or ended in the callback\n\t\tif (this.event && this.markers.end) {\n\t\t\tthis.reportEvent(\"end\");\n\t\t}\n\t\tthis.performanceEndMark();\n\t\tthis.event = undefined;\n\t}\n\n\tpublic end(props?: ITelemetryProperties): void {\n\t\tthis.reportEvent(\"end\", props);\n\t\tthis.performanceEndMark();\n\t\tthis.event = undefined;\n\t}\n\n\tprivate performanceEndMark() {\n\t\tif (this.startMark && this.event) {\n\t\t\tconst endMark = `${this.event.eventName}-end`;\n\t\t\twindow.performance.mark(endMark);\n\t\t\twindow.performance.measure(`${this.event.eventName}`, this.startMark, endMark);\n\t\t\tthis.startMark = undefined;\n\t\t}\n\t}\n\n\tpublic cancel(props?: ITelemetryProperties, error?: any): void {\n\t\tif (this.markers.cancel !== undefined) {\n\t\t\tthis.reportEvent(\"cancel\", { category: this.markers.cancel, ...props }, error);\n\t\t}\n\t\tthis.event = undefined;\n\t}\n\n\t/**\n\t * Report the event, if it hasn't already been reported.\n\t */\n\tpublic reportEvent(eventNameSuffix: string, props?: ITelemetryProperties, error?: any) {\n\t\t// There are strange sequences involving multiple Promise chains\n\t\t// where the event can be cancelled and then later a callback is invoked\n\t\t// and the caller attempts to end directly, e.g. issue #3936. Just return.\n\t\tif (!this.event) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst event: ITelemetryPerformanceEvent = { ...this.event, ...props };\n\t\tevent.eventName = `${event.eventName}_${eventNameSuffix}`;\n\t\tif (eventNameSuffix !== \"start\") {\n\t\t\tevent.duration = this.duration;\n\t\t\tif (this.startMemoryCollection) {\n\t\t\t\tconst currentMemory = (performance as PerformanceWithMemory)?.memory\n\t\t\t\t\t?.usedJSHeapSize;\n\t\t\t\tconst differenceInKBytes = Math.floor(\n\t\t\t\t\t(currentMemory - this.startMemoryCollection) / 1024,\n\t\t\t\t);\n\t\t\t\tif (differenceInKBytes > 0) {\n\t\t\t\t\tevent.usedJSHeapSize = differenceInKBytes;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (this.recordHeapSize) {\n\t\t\tthis.startMemoryCollection = (\n\t\t\t\tperformance as PerformanceWithMemory\n\t\t\t)?.memory?.usedJSHeapSize;\n\t\t}\n\n\t\tthis.logger.sendPerformanceEvent(event, error);\n\t}\n}\n\n/**\n * Logger that is useful for UT\n * It can be used in places where logger instance is required, but events should be not send over.\n */\nexport class TelemetryUTLogger implements ITelemetryLoggerExt {\n\tpublic send(event: ITelemetryBaseEvent): void {}\n\tpublic sendTelemetryEvent(event: ITelemetryGenericEvent, error?: any) {}\n\tpublic sendErrorEvent(event: ITelemetryErrorEvent, error?: any) {\n\t\tthis.reportError(\"errorEvent in UT logger!\", event, error);\n\t}\n\tpublic sendPerformanceEvent(event: ITelemetryPerformanceEvent, error?: any): void {}\n\tpublic logGenericError(eventName: string, error: any) {\n\t\tthis.reportError(`genericError in UT logger!`, { eventName }, error);\n\t}\n\tpublic logException(event: ITelemetryErrorEvent, exception: any): void {\n\t\tthis.reportError(\"exception in UT logger!\", event, exception);\n\t}\n\tpublic debugAssert(condition: boolean, event?: ITelemetryErrorEvent): void {\n\t\tthis.reportError(\"debugAssert in UT logger!\");\n\t}\n\tpublic shipAssert(condition: boolean, event?: ITelemetryErrorEvent): void {\n\t\tthis.reportError(\"shipAssert in UT logger!\");\n\t}\n\n\tprivate reportError(message: string, event?: ITelemetryErrorEvent, err?: any) {\n\t\tconst error = new Error(message);\n\t\t(error as any).error = error;\n\t\t(error as any).event = event;\n\t\t// report to console as exception can be eaten\n\t\tconsole.error(message);\n\t\tconsole.error(error);\n\t\tthrow error;\n\t}\n}\n\n/**\n * Null logger\n * It can be used in places where logger instance is required, but events should be not send over.\n */\nexport class BaseTelemetryNullLogger implements ITelemetryBaseLogger {\n\t/**\n\t * Send an event with the logger\n\t *\n\t * @param event - the event to send\n\t */\n\tpublic send(event: ITelemetryBaseEvent): void {\n\t\treturn;\n\t}\n}\n\n/**\n * Null logger\n * It can be used in places where logger instance is required, but events should be not send over.\n */\nexport class TelemetryNullLogger implements ITelemetryLoggerExt {\n\tpublic send(event: ITelemetryBaseEvent): void {}\n\tpublic sendTelemetryEvent(event: ITelemetryGenericEvent, error?: any): void {}\n\tpublic sendErrorEvent(event: ITelemetryErrorEvent, error?: any): void {}\n\tpublic sendPerformanceEvent(event: ITelemetryPerformanceEvent, error?: any): void {}\n}\n\n/**\n * Takes in an event object, and converts all of its values to a basePropertyType.\n * In the case of an invalid property type, the value will be converted to an error string.\n * @param event - Event with fields you want to stringify.\n */\nfunction convertToBaseEvent({\n\tcategory,\n\teventName,\n\t...props\n}: ITelemetryEventExt): ITelemetryBaseEvent {\n\tconst newEvent: ITelemetryBaseEvent = { category, eventName };\n\tfor (const key of Object.keys(props)) {\n\t\tnewEvent[key] = convertToBasePropertyType(props[key]);\n\t}\n\treturn newEvent;\n}\n\n/**\n * Takes in value, and does one of 4 things.\n * if value is of primitive type - returns the original value.\n * If the value is an array of primitives - returns a stringified version of the array.\n * If the value is an object of type ITaggedTelemetryPropertyType - returns the object\n * with its values recursively converted to base property Type.\n * If none of these cases are reached - returns an error string\n * @param x - value passed in to convert to a base property type\n */\nexport function convertToBasePropertyType(\n\tx: TelemetryEventPropertyTypeExt | ITaggedTelemetryPropertyTypeExt,\n): TelemetryEventPropertyType | ITaggedTelemetryPropertyType {\n\treturn isTaggedTelemetryPropertyValue(x)\n\t\t? {\n\t\t\t\tvalue: convertToBasePropertyTypeUntagged(x.value),\n\t\t\t\ttag: x.tag,\n\t\t }\n\t\t: convertToBasePropertyTypeUntagged(x);\n}\n\nfunction convertToBasePropertyTypeUntagged(\n\tx: TelemetryEventPropertyTypeExt,\n): TelemetryEventPropertyType {\n\tswitch (typeof x) {\n\t\tcase \"string\":\n\t\tcase \"number\":\n\t\tcase \"boolean\":\n\t\tcase \"undefined\":\n\t\t\treturn x;\n\t\tcase \"object\":\n\t\t\t// We assume this is an array or flat object based on the input types\n\t\t\treturn JSON.stringify(x);\n\t\tdefault:\n\t\t\t// should never reach this case based on the input types\n\t\t\tconsole.error(\n\t\t\t\t`convertToBasePropertyTypeUntagged: INVALID PROPERTY (typed as ${typeof x})`,\n\t\t\t);\n\t\t\treturn `INVALID PROPERTY (typed as ${typeof x})`;\n\t}\n}\n"]}
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.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 {\n\tITelemetryBaseEvent,\n\tITelemetryBaseLogger,\n\tITelemetryErrorEvent,\n\tITelemetryGenericEvent,\n\tITelemetryPerformanceEvent,\n\tITelemetryProperties,\n\tTelemetryBaseEventPropertyType as TelemetryEventPropertyType,\n\tLogLevel,\n\tTagged,\n\tITelemetryBaseProperties,\n\tTelemetryBaseEventPropertyType,\n} from \"@fluidframework/core-interfaces\";\nimport { IsomorphicPerformance, performance } from \"@fluid-internal/client-utils\";\nimport { CachedConfigProvider, loggerIsMonitoringContext, mixinMonitoringContext } from \"./config\";\nimport {\n\tisILoggingError,\n\textractLogSafeErrorProperties,\n\tgenerateStack,\n\tisTaggedTelemetryPropertyValue,\n} from \"./errorLogging\";\nimport {\n\tITelemetryEventExt,\n\tITelemetryGenericEventExt,\n\tITelemetryLoggerExt,\n\tITelemetryPerformanceEventExt,\n\tTelemetryEventPropertyTypeExt,\n\tTelemetryEventCategory,\n} from \"./telemetryTypes\";\n\nexport interface Memory {\n\tusedJSHeapSize: number;\n}\n\nexport interface PerformanceWithMemory extends IsomorphicPerformance {\n\treadonly memory: Memory;\n}\n/**\n * Broad classifications to be applied to individual properties as they're prepared to be logged to telemetry.\n * Please do not modify existing entries for backwards compatibility.\n */\nexport enum TelemetryDataTag {\n\t/**\n\t * Data containing terms or IDs from code packages that may have been dynamically loaded\n\t */\n\tCodeArtifact = \"CodeArtifact\",\n\t/**\n\t * Personal data of a variety of classifications that pertains to the user\n\t */\n\tUserData = \"UserData\",\n}\n\nexport type TelemetryEventPropertyTypes = ITelemetryBaseProperties[string];\n\nexport interface ITelemetryLoggerPropertyBag {\n\t[index: string]: TelemetryEventPropertyTypes | (() => TelemetryEventPropertyTypes);\n}\nexport interface ITelemetryLoggerPropertyBags {\n\tall?: ITelemetryLoggerPropertyBag;\n\terror?: ITelemetryLoggerPropertyBag;\n}\n\n/**\n * Attempts to parse number from string.\n * If fails,returns original string.\n * Used to make telemetry data typed (and support math operations, like comparison),\n * in places where we do expect numbers (like contentsize/duration property in http header)\n */\n// eslint-disable-next-line @rushstack/no-new-null\nexport function numberFromString(str: string | null | undefined): string | number | undefined {\n\tif (str === undefined || str === null) {\n\t\treturn undefined;\n\t}\n\tconst num = Number(str);\n\treturn Number.isNaN(num) ? str : num;\n}\n\nexport function formatTick(tick: number): number {\n\treturn Math.floor(tick);\n}\n\nexport const eventNamespaceSeparator = \":\" as const;\n\n/**\n * TelemetryLogger class contains various helper telemetry methods,\n * encoding in one place schemas for various types of Fluid telemetry events.\n * Creates sub-logger that appends properties to all events\n */\nexport abstract class TelemetryLogger implements ITelemetryLoggerExt {\n\tpublic static readonly eventNamespaceSeparator = eventNamespaceSeparator;\n\n\tpublic static sanitizePkgName(name: string): string {\n\t\treturn name.replace(\"@\", \"\").replace(\"/\", \"-\");\n\t}\n\n\t/**\n\t * Take an unknown error object and add the appropriate info from it to the event. Message and stack will be copied\n\t * over from the error object, along with other telemetry properties if it's an ILoggingError.\n\t * @param event - Event being logged\n\t * @param error - Error to extract info from\n\t * @param fetchStack - Whether to fetch the current callstack if error.stack is undefined\n\t */\n\tpublic static prepareErrorObject(\n\t\tevent: ITelemetryBaseEvent,\n\t\terror: unknown,\n\t\tfetchStack: boolean,\n\t): void {\n\t\tconst { message, errorType, stack } = extractLogSafeErrorProperties(\n\t\t\terror,\n\t\t\ttrue /* sanitizeStack */,\n\t\t);\n\t\t// First, copy over error message, stack, and errorType directly (overwrite if present on event)\n\t\tevent.stack = stack;\n\t\tevent.error = message; // Note that the error message goes on the 'error' field\n\t\tevent.errorType = errorType;\n\n\t\tif (isILoggingError(error)) {\n\t\t\t// Add any other telemetry properties from the LoggingError\n\t\t\tconst telemetryProp = error.getTelemetryProperties();\n\t\t\tfor (const key of Object.keys(telemetryProp)) {\n\t\t\t\tif (event[key] !== undefined) {\n\t\t\t\t\t// Don't overwrite existing properties on the event\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tevent[key] = telemetryProp[key];\n\t\t\t}\n\t\t}\n\n\t\t// Collect stack if we were not able to extract it from error\n\t\tif (event.stack === undefined && fetchStack) {\n\t\t\tevent.stack = generateStack();\n\t\t}\n\t}\n\n\tpublic constructor(\n\t\tprotected readonly namespace?: string,\n\t\tprotected readonly properties?: ITelemetryLoggerPropertyBags,\n\t) {}\n\n\t/**\n\t * Send an event with the logger\n\t *\n\t * @param event - the event to send\n\t */\n\tpublic abstract send(event: ITelemetryBaseEvent, logLevel?: LogLevel): void;\n\n\t/**\n\t * Send a telemetry event with the logger\n\t *\n\t * @param event - the event to send\n\t * @param error - optional error object to log\n\t * @param logLevel - optional level of the log. It category of event is set as error,\n\t * then the logLevel will be upgraded to be an error.\n\t */\n\tpublic sendTelemetryEvent(\n\t\tevent: ITelemetryGenericEventExt,\n\t\terror?: unknown,\n\t\tlogLevel: typeof LogLevel.verbose | typeof LogLevel.default = LogLevel.default,\n\t): void {\n\t\tthis.sendTelemetryEventCore(\n\t\t\t{ ...event, category: event.category ?? \"generic\" },\n\t\t\terror,\n\t\t\tevent.category === \"error\" ? LogLevel.error : logLevel,\n\t\t);\n\t}\n\n\t/**\n\t * Send a telemetry event with the logger\n\t *\n\t * @param event - the event to send\n\t * @param error - optional error object to log\n\t * @param logLevel - optional level of the log.\n\t */\n\tprotected sendTelemetryEventCore(\n\t\tevent: ITelemetryGenericEventExt & { category: TelemetryEventCategory },\n\t\terror?: unknown,\n\t\tlogLevel?: LogLevel,\n\t): void {\n\t\tconst newEvent = convertToBaseEvent(event);\n\t\tif (error !== undefined) {\n\t\t\tTelemetryLogger.prepareErrorObject(newEvent, error, false);\n\t\t}\n\n\t\t// Will include Nan & Infinity, but probably we do not care\n\t\tif (typeof newEvent.duration === \"number\") {\n\t\t\tnewEvent.duration = formatTick(newEvent.duration);\n\t\t}\n\n\t\tthis.send(newEvent, logLevel);\n\t}\n\n\t/**\n\t * Send an error telemetry event with the logger\n\t *\n\t * @param event - the event to send\n\t * @param error - optional error object to log\n\t */\n\tpublic sendErrorEvent(event: ITelemetryErrorEvent, error?: unknown): void {\n\t\tthis.sendTelemetryEventCore(\n\t\t\t{\n\t\t\t\t// ensure the error field has some value,\n\t\t\t\t// this can and will be overridden by event, or error\n\t\t\t\terror: event.eventName,\n\t\t\t\t...event,\n\t\t\t\tcategory: \"error\",\n\t\t\t},\n\t\t\terror,\n\t\t\tLogLevel.error,\n\t\t);\n\t}\n\n\t/**\n\t * Send a performance telemetry event with the logger\n\t *\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. It category of event is set as error,\n\t * then the logLevel will be upgraded to be an error.\n\t */\n\tpublic sendPerformanceEvent(\n\t\tevent: ITelemetryPerformanceEventExt,\n\t\terror?: unknown,\n\t\tlogLevel: typeof LogLevel.verbose | typeof LogLevel.default = LogLevel.default,\n\t): void {\n\t\tconst perfEvent = {\n\t\t\t...event,\n\t\t\tcategory: event.category ?? \"performance\",\n\t\t};\n\n\t\tthis.sendTelemetryEventCore(\n\t\t\tperfEvent,\n\t\t\terror,\n\t\t\tperfEvent.category === \"error\" ? LogLevel.error : logLevel,\n\t\t);\n\t}\n\n\tprotected prepareEvent(event: ITelemetryBaseEvent): ITelemetryBaseEvent {\n\t\tconst includeErrorProps = event.category === \"error\" || event.error !== undefined;\n\t\tconst newEvent: ITelemetryBaseEvent = {\n\t\t\t...event,\n\t\t};\n\t\tif (this.namespace !== undefined) {\n\t\t\tnewEvent.eventName = `${this.namespace}${TelemetryLogger.eventNamespaceSeparator}${newEvent.eventName}`;\n\t\t}\n\t\treturn this.extendProperties(newEvent, includeErrorProps);\n\t}\n\n\tprivate extendProperties<T extends ITelemetryLoggerPropertyBag = ITelemetryLoggerPropertyBag>(\n\t\ttoExtend: T,\n\t\tincludeErrorProps: boolean,\n\t): T {\n\t\tconst eventLike: ITelemetryLoggerPropertyBag = toExtend;\n\t\tif (this.properties) {\n\t\t\tconst properties: (undefined | ITelemetryLoggerPropertyBag)[] = [];\n\t\t\tproperties.push(this.properties.all);\n\t\t\tif (includeErrorProps) {\n\t\t\t\tproperties.push(this.properties.error);\n\t\t\t}\n\t\t\tfor (const props of properties) {\n\t\t\t\tif (props !== undefined) {\n\t\t\t\t\tfor (const key of Object.keys(props)) {\n\t\t\t\t\t\tif (eventLike[key] !== undefined) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst getterOrValue = props[key];\n\t\t\t\t\t\t// If this throws, hopefully it is handled elsewhere\n\t\t\t\t\t\tconst value =\n\t\t\t\t\t\t\ttypeof getterOrValue === \"function\" ? getterOrValue() : getterOrValue;\n\t\t\t\t\t\tif (value !== undefined) {\n\t\t\t\t\t\t\teventLike[key] = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn toExtend;\n\t}\n}\n\n/**\n * @deprecated 0.56, remove TaggedLoggerAdapter once its usage is removed from\n * container-runtime. Issue: #8191\n * TaggedLoggerAdapter class can add tag handling to your logger.\n */\nexport class TaggedLoggerAdapter implements ITelemetryBaseLogger {\n\tpublic constructor(private readonly logger: ITelemetryBaseLogger) {}\n\n\t/**\n\t * {@inheritDoc @fluidframework/core-interfaces#ITelemetryBaseLogger.send}\n\t */\n\tpublic send(eventWithTagsMaybe: ITelemetryBaseEvent): void {\n\t\tconst newEvent: ITelemetryBaseEvent = {\n\t\t\tcategory: eventWithTagsMaybe.category,\n\t\t\teventName: eventWithTagsMaybe.eventName,\n\t\t};\n\t\tfor (const key of Object.keys(eventWithTagsMaybe)) {\n\t\t\tconst taggableProp = eventWithTagsMaybe[key];\n\t\t\tconst { value, tag } =\n\t\t\t\ttypeof taggableProp === \"object\"\n\t\t\t\t\t? taggableProp\n\t\t\t\t\t: { value: taggableProp, tag: undefined };\n\t\t\tswitch (tag) {\n\t\t\t\tcase undefined:\n\t\t\t\t\t// No tag means we can log plainly\n\t\t\t\t\tnewEvent[key] = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"PackageData\": // For back-compat\n\t\t\t\tcase TelemetryDataTag.CodeArtifact:\n\t\t\t\t\t// For Microsoft applications, CodeArtifact is safe for now\n\t\t\t\t\t// (we don't load 3P code in 1P apps)\n\t\t\t\t\tnewEvent[key] = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TelemetryDataTag.UserData:\n\t\t\t\t\t// Strip out anything tagged explicitly as UserData.\n\t\t\t\t\t// Alternate strategy would be to hash these props\n\t\t\t\t\tnewEvent[key] = \"REDACTED (UserData)\";\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t// If we encounter a tag we don't recognize\n\t\t\t\t\t// then we must assume we should scrub.\n\t\t\t\t\tnewEvent[key] = \"REDACTED (unknown tag)\";\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tthis.logger.send(newEvent);\n\t}\n}\n\n/**\n * Create a child logger based on the provided props object\n * @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.\n *\n * @remarks\n * Passing in no props object (i.e. undefined) will return a logger that is effectively a no-op.\n */\nexport function createChildLogger(props?: {\n\tlogger?: ITelemetryBaseLogger;\n\tnamespace?: string;\n\tproperties?: ITelemetryLoggerPropertyBags;\n}): ITelemetryLoggerExt {\n\treturn ChildLogger.create(props?.logger, props?.namespace, props?.properties);\n}\n\n/**\n * ChildLogger class contains various helper telemetry methods,\n * encoding in one place schemas for various types of Fluid telemetry events.\n * Creates sub-logger that appends properties to all events\n */\nexport class ChildLogger extends TelemetryLogger {\n\t/**\n\t * Create child logger\n\t * @param baseLogger - Base logger to use to output events. If undefined, proper child logger\n\t * is created, but it does not send telemetry events anywhere.\n\t * @param namespace - Telemetry event name prefix to add to all events\n\t * @param properties - Base properties to add to all events\n\t */\n\tpublic static create(\n\t\tbaseLogger?: ITelemetryBaseLogger,\n\t\tnamespace?: string,\n\t\tproperties?: ITelemetryLoggerPropertyBags,\n\t): TelemetryLogger {\n\t\t// if we are creating a child of a child, rather than nest, which will increase\n\t\t// the callstack overhead, just generate a new logger that includes everything from the previous\n\t\tif (baseLogger instanceof ChildLogger) {\n\t\t\tconst combinedProperties: ITelemetryLoggerPropertyBags = {};\n\t\t\tfor (const extendedProps of [baseLogger.properties, properties]) {\n\t\t\t\tif (extendedProps !== undefined) {\n\t\t\t\t\tif (extendedProps.all !== undefined) {\n\t\t\t\t\t\tcombinedProperties.all = {\n\t\t\t\t\t\t\t...combinedProperties.all,\n\t\t\t\t\t\t\t...extendedProps.all,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tif (extendedProps.error !== undefined) {\n\t\t\t\t\t\tcombinedProperties.error = {\n\t\t\t\t\t\t\t...combinedProperties.error,\n\t\t\t\t\t\t\t...extendedProps.error,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst combinedNamespace =\n\t\t\t\tbaseLogger.namespace === undefined\n\t\t\t\t\t? namespace\n\t\t\t\t\t: namespace === undefined\n\t\t\t\t\t? baseLogger.namespace\n\t\t\t\t\t: `${baseLogger.namespace}${TelemetryLogger.eventNamespaceSeparator}${namespace}`;\n\n\t\t\tconst child = new ChildLogger(\n\t\t\t\tbaseLogger.baseLogger,\n\t\t\t\tcombinedNamespace,\n\t\t\t\tcombinedProperties,\n\t\t\t);\n\n\t\t\tif (!loggerIsMonitoringContext(child) && loggerIsMonitoringContext(baseLogger)) {\n\t\t\t\tmixinMonitoringContext(child, baseLogger.config);\n\t\t\t}\n\t\t\treturn child;\n\t\t}\n\n\t\treturn new ChildLogger(\n\t\t\tbaseLogger ? baseLogger : { send(): void {} },\n\t\t\tnamespace,\n\t\t\tproperties,\n\t\t);\n\t}\n\n\tprivate constructor(\n\t\tprotected readonly baseLogger: ITelemetryBaseLogger,\n\t\tnamespace: string | undefined,\n\t\tproperties: ITelemetryLoggerPropertyBags | undefined,\n\t) {\n\t\tsuper(namespace, properties);\n\n\t\t// propagate the monitoring context\n\t\tif (loggerIsMonitoringContext(baseLogger)) {\n\t\t\tmixinMonitoringContext(this, new CachedConfigProvider(this, baseLogger.config));\n\t\t}\n\t}\n\n\tpublic get minLogLevel(): LogLevel | undefined {\n\t\treturn this.baseLogger.minLogLevel;\n\t}\n\n\tprivate shouldFilterOutEvent(event: ITelemetryBaseEvent, logLevel?: LogLevel): boolean {\n\t\tconst eventLogLevel = logLevel ?? LogLevel.default;\n\t\tconst configLogLevel = this.baseLogger.minLogLevel ?? LogLevel.default;\n\t\t// Filter out in case event log level is below what is wanted in config.\n\t\treturn eventLogLevel < configLogLevel;\n\t}\n\n\t/**\n\t * Send an event with the logger\n\t *\n\t * @param event - the event to send\n\t */\n\tpublic send(event: ITelemetryBaseEvent, logLevel?: LogLevel): void {\n\t\tif (this.shouldFilterOutEvent(event, logLevel)) {\n\t\t\treturn;\n\t\t}\n\t\tthis.baseLogger.send(this.prepareEvent(event), logLevel);\n\t}\n}\n\n/**\n * Create a logger which logs to multiple other loggers based on the provided props object\n * @param props - loggers are the base loggers that will logged to after it's processing, namespace will be prefixed to all event names, properties are default properties that will be applied events.\n * tryInheritProperties will attempted to copy those loggers properties to this loggers if they are of a known type e.g. one from this package\n */\nexport function createMultiSinkLogger(props: {\n\tnamespace?: string;\n\tproperties?: ITelemetryLoggerPropertyBags;\n\tloggers?: (ITelemetryBaseLogger | undefined)[];\n\ttryInheritProperties?: true;\n}): ITelemetryLoggerExt {\n\treturn new MultiSinkLogger(\n\t\tprops.namespace,\n\t\tprops.properties,\n\t\tprops.loggers?.filter((l): l is ITelemetryBaseLogger => l !== undefined),\n\t\tprops.tryInheritProperties,\n\t);\n}\n\n/**\n * Multi-sink logger\n * Takes multiple ITelemetryBaseLogger objects (sinks) and logs all events into each sink\n */\nexport class MultiSinkLogger extends TelemetryLogger {\n\tprotected loggers: ITelemetryBaseLogger[];\n\t// This is minimum of minLlogLevel of all loggers.\n\tprivate _minLogLevelOfAllLoggers: LogLevel;\n\n\t/**\n\t * Create multiple sink logger (i.e. logger that sends events to multiple sinks)\n\t * @param namespace - Telemetry event name prefix to add to all events\n\t * @param properties - Base properties to add to all events\n\t * @param loggers - The list of loggers to use as sinks\n\t * @param tryInheritProperties - Will attempted to copy those loggers properties to this loggers if they are of a known type e.g. one from this package\n\t */\n\tconstructor(\n\t\tnamespace?: string,\n\t\tproperties?: ITelemetryLoggerPropertyBags,\n\t\tloggers: ITelemetryBaseLogger[] = [],\n\t\ttryInheritProperties?: true,\n\t) {\n\t\tlet realProperties = properties !== undefined ? { ...properties } : undefined;\n\t\tif (tryInheritProperties === true) {\n\t\t\tconst merge = (realProperties ??= {});\n\t\t\tloggers\n\t\t\t\t.filter((l): l is this => l instanceof TelemetryLogger)\n\t\t\t\t.map((l) => l.properties ?? {})\n\t\t\t\t// eslint-disable-next-line unicorn/no-array-for-each\n\t\t\t\t.forEach((cv) => {\n\t\t\t\t\t// eslint-disable-next-line unicorn/no-array-for-each\n\t\t\t\t\tObject.keys(cv).forEach((k) => {\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\t\t\t\tmerge[k] = { ...cv[k], ...merge?.[k] };\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t}\n\n\t\tsuper(namespace, realProperties);\n\t\tthis.loggers = loggers;\n\t\tthis._minLogLevelOfAllLoggers = LogLevel.default;\n\t\tthis.calculateMinLogLevel();\n\t}\n\n\tpublic get minLogLevel(): LogLevel {\n\t\treturn this._minLogLevelOfAllLoggers;\n\t}\n\n\tprivate calculateMinLogLevel(): void {\n\t\tif (this.loggers.length > 0) {\n\t\t\tconst logLevels: LogLevel[] = [];\n\t\t\tfor (const logger of this.loggers) {\n\t\t\t\tlogLevels.push(logger.minLogLevel ?? LogLevel.default);\n\t\t\t}\n\t\t\tthis._minLogLevelOfAllLoggers = Math.min(...logLevels) as LogLevel;\n\t\t}\n\t}\n\n\t/**\n\t * Add logger to send all events to\n\t * @param logger - Logger to add\n\t */\n\tpublic addLogger(logger?: ITelemetryBaseLogger): void {\n\t\tif (logger !== undefined && logger !== null) {\n\t\t\tthis.loggers.push(logger);\n\t\t\t// Update in case the logLevel of added logger is less than the current.\n\t\t\tthis.calculateMinLogLevel();\n\t\t}\n\t}\n\n\t/**\n\t * Send an event to the loggers\n\t *\n\t * @param event - the event to send to all the registered logger\n\t */\n\tpublic send(event: ITelemetryBaseEvent): void {\n\t\tconst newEvent = this.prepareEvent(event);\n\t\tfor (const logger of this.loggers) {\n\t\t\tlogger.send(newEvent);\n\t\t}\n\t}\n}\n\n/**\n * Describes what events PerformanceEvent should log\n * By default, all events are logged, but client can override this behavior\n * For example, there is rarely a need to record start event, as we really after\n * success / failure tracking, including duration (on success).\n */\nexport interface IPerformanceEventMarkers {\n\tstart?: true;\n\tend?: true;\n\tcancel?: \"generic\" | \"error\"; // tells wether to issue \"generic\" or \"error\" category cancel event\n}\n\n/**\n * Helper class to log performance events\n */\nexport class PerformanceEvent {\n\tpublic static start(\n\t\tlogger: ITelemetryLoggerExt,\n\t\tevent: ITelemetryGenericEvent,\n\t\tmarkers?: IPerformanceEventMarkers,\n\t\trecordHeapSize: boolean = false,\n\t): PerformanceEvent {\n\t\treturn new PerformanceEvent(logger, event, markers, recordHeapSize);\n\t}\n\n\tpublic static timedExec<T>(\n\t\tlogger: ITelemetryLoggerExt,\n\t\tevent: ITelemetryGenericEvent,\n\t\tcallback: (event: PerformanceEvent) => T,\n\t\tmarkers?: IPerformanceEventMarkers,\n\t): T {\n\t\tconst perfEvent = PerformanceEvent.start(logger, event, markers);\n\t\ttry {\n\t\t\tconst ret = callback(perfEvent);\n\t\t\tperfEvent.autoEnd();\n\t\t\treturn ret;\n\t\t} catch (error) {\n\t\t\tperfEvent.cancel(undefined, error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tpublic static async timedExecAsync<T>(\n\t\tlogger: ITelemetryLoggerExt,\n\t\tevent: ITelemetryGenericEvent,\n\t\tcallback: (event: PerformanceEvent) => Promise<T>,\n\t\tmarkers?: IPerformanceEventMarkers,\n\t\trecordHeapSize?: boolean,\n\t): Promise<T> {\n\t\tconst perfEvent = PerformanceEvent.start(logger, event, markers, recordHeapSize);\n\t\ttry {\n\t\t\tconst ret = await callback(perfEvent);\n\t\t\tperfEvent.autoEnd();\n\t\t\treturn ret;\n\t\t} catch (error) {\n\t\t\tperfEvent.cancel(undefined, error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tpublic get duration(): number {\n\t\treturn performance.now() - this.startTime;\n\t}\n\n\tprivate event?: ITelemetryGenericEvent;\n\tprivate readonly startTime = performance.now();\n\tprivate startMark?: string;\n\tprivate startMemoryCollection: number | undefined = 0;\n\n\tprotected constructor(\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t\tevent: ITelemetryGenericEvent,\n\t\tprivate readonly markers: IPerformanceEventMarkers = { end: true, cancel: \"generic\" },\n\t\tprivate readonly recordHeapSize: boolean = false,\n\t) {\n\t\tthis.event = { ...event };\n\t\tif (this.markers.start) {\n\t\t\tthis.reportEvent(\"start\");\n\t\t}\n\n\t\t// eslint-disable-next-line unicorn/no-null\n\t\tif (typeof window === \"object\" && window != null && window.performance?.mark) {\n\t\t\tthis.startMark = `${event.eventName}-start`;\n\t\t\twindow.performance.mark(this.startMark);\n\t\t}\n\t}\n\n\tpublic reportProgress(props?: ITelemetryProperties, eventNameSuffix: string = \"update\"): void {\n\t\tthis.reportEvent(eventNameSuffix, props);\n\t}\n\n\tprivate autoEnd(): void {\n\t\t// Event might have been cancelled or ended in the callback\n\t\tif (this.event && this.markers.end) {\n\t\t\tthis.reportEvent(\"end\");\n\t\t}\n\t\tthis.performanceEndMark();\n\t\tthis.event = undefined;\n\t}\n\n\tpublic end(props?: ITelemetryProperties): void {\n\t\tthis.reportEvent(\"end\", props);\n\t\tthis.performanceEndMark();\n\t\tthis.event = undefined;\n\t}\n\n\tprivate performanceEndMark(): void {\n\t\tif (this.startMark && this.event) {\n\t\t\tconst endMark = `${this.event.eventName}-end`;\n\t\t\twindow.performance.mark(endMark);\n\t\t\twindow.performance.measure(`${this.event.eventName}`, this.startMark, endMark);\n\t\t\tthis.startMark = undefined;\n\t\t}\n\t}\n\n\tpublic cancel(props?: ITelemetryProperties, error?: unknown): void {\n\t\tif (this.markers.cancel !== undefined) {\n\t\t\tthis.reportEvent(\"cancel\", { category: this.markers.cancel, ...props }, error);\n\t\t}\n\t\tthis.event = undefined;\n\t}\n\n\t/**\n\t * Report the event, if it hasn't already been reported.\n\t */\n\tpublic reportEvent(\n\t\teventNameSuffix: string,\n\t\tprops?: ITelemetryProperties,\n\t\terror?: unknown,\n\t): void {\n\t\t// There are strange sequences involving multiple Promise chains\n\t\t// where the event can be cancelled and then later a callback is invoked\n\t\t// and the caller attempts to end directly, e.g. issue #3936. Just return.\n\t\tif (!this.event) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst event: ITelemetryPerformanceEvent = { ...this.event, ...props };\n\t\tevent.eventName = `${event.eventName}_${eventNameSuffix}`;\n\t\tif (eventNameSuffix !== \"start\") {\n\t\t\tevent.duration = this.duration;\n\t\t\tif (this.startMemoryCollection) {\n\t\t\t\tconst currentMemory = (performance as PerformanceWithMemory)?.memory\n\t\t\t\t\t?.usedJSHeapSize;\n\t\t\t\tconst differenceInKBytes = Math.floor(\n\t\t\t\t\t(currentMemory - this.startMemoryCollection) / 1024,\n\t\t\t\t);\n\t\t\t\tif (differenceInKBytes > 0) {\n\t\t\t\t\tevent.usedJSHeapSize = differenceInKBytes;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (this.recordHeapSize) {\n\t\t\tthis.startMemoryCollection = (\n\t\t\t\tperformance as PerformanceWithMemory\n\t\t\t)?.memory?.usedJSHeapSize;\n\t\t}\n\n\t\tthis.logger.sendPerformanceEvent(event, error);\n\t}\n}\n\n/**\n * Null logger that no-ops for all telemetry events passed to it.\n * @deprecated - This will be removed in a future release.\n * For internal use within the FluidFramework codebase, use {@link createChildLogger} with no arguments instead.\n * For external consumers we recommend writing a trivial implementation of {@link @fluidframework/core-interfaces#ITelemetryBaseLogger}\n * where the send() method does nothing and using that.\n */\nexport class TelemetryNullLogger implements ITelemetryLoggerExt {\n\tpublic send(event: ITelemetryBaseEvent): void {}\n\tpublic sendTelemetryEvent(event: ITelemetryGenericEvent, error?: unknown): void {}\n\tpublic sendErrorEvent(event: ITelemetryErrorEvent, error?: unknown): void {}\n\tpublic sendPerformanceEvent(event: ITelemetryPerformanceEvent, error?: unknown): void {}\n}\n\n/**\n * Takes in an event object, and converts all of its values to a basePropertyType.\n * In the case of an invalid property type, the value will be converted to an error string.\n * @param event - Event with fields you want to stringify.\n */\nfunction convertToBaseEvent({\n\tcategory,\n\teventName,\n\t...props\n}: ITelemetryEventExt): ITelemetryBaseEvent {\n\tconst newEvent: ITelemetryBaseEvent = { category, eventName };\n\tfor (const key of Object.keys(props)) {\n\t\tnewEvent[key] = convertToBasePropertyType(props[key]);\n\t}\n\treturn newEvent;\n}\n\n/**\n * Takes in value, and does one of 4 things.\n * if value is of primitive type - returns the original value.\n * If the value is a flat array or object - returns a stringified version of the array/object.\n * If the value is an object of type Tagged<TelemetryEventPropertyType> - returns the object\n * with its values recursively converted to base property Type.\n * If none of these cases are reached - returns an error string\n * @param x - value passed in to convert to a base property type\n */\nexport function convertToBasePropertyType(\n\tx: TelemetryEventPropertyTypeExt | Tagged<TelemetryEventPropertyTypeExt>,\n): TelemetryEventPropertyType | Tagged<TelemetryEventPropertyType> {\n\treturn isTaggedTelemetryPropertyValue(x)\n\t\t? {\n\t\t\t\tvalue: convertToBasePropertyTypeUntagged(x.value),\n\t\t\t\ttag: x.tag,\n\t\t }\n\t\t: convertToBasePropertyTypeUntagged(x);\n}\n\nfunction convertToBasePropertyTypeUntagged(\n\tx: TelemetryEventPropertyTypeExt,\n): TelemetryEventPropertyType {\n\tswitch (typeof x) {\n\t\tcase \"string\":\n\t\tcase \"number\":\n\t\tcase \"boolean\":\n\t\tcase \"undefined\":\n\t\t\treturn x;\n\t\tcase \"object\":\n\t\t\t// We assume this is an array or flat object based on the input types\n\t\t\treturn JSON.stringify(x);\n\t\tdefault:\n\t\t\t// should never reach this case based on the input types\n\t\t\tconsole.error(\n\t\t\t\t`convertToBasePropertyTypeUntagged: INVALID PROPERTY (typed as ${typeof x})`,\n\t\t\t);\n\t\t\treturn `INVALID PROPERTY (typed as ${typeof x})`;\n\t}\n}\n\nexport const tagData = <\n\tT extends TelemetryDataTag,\n\tV extends Record<\n\t\tstring,\n\t\tTelemetryBaseEventPropertyType | (() => TelemetryBaseEventPropertyType)\n\t>,\n>(\n\ttag: T,\n\tvalues: V,\n): {\n\t[P in keyof V]:\n\t\t| (V[P] extends () => TelemetryBaseEventPropertyType\n\t\t\t\t? () => {\n\t\t\t\t\t\tvalue: ReturnType<V[P]>;\n\t\t\t\t\t\ttag: T;\n\t\t\t\t }\n\t\t\t\t: {\n\t\t\t\t\t\tvalue: Exclude<V[P], undefined>;\n\t\t\t\t\t\ttag: T;\n\t\t\t\t })\n\t\t| (V[P] extends undefined ? undefined : never);\n} =>\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\tObject.entries(values)\n\t\t.filter((e) => e[1] !== undefined)\n\t\t// eslint-disable-next-line unicorn/no-array-reduce, unicorn/prefer-object-from-entries\n\t\t.reduce((pv, cv) => {\n\t\t\tconst [key, value] = cv;\n\t\t\tif (typeof value === \"function\") {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\n\t\t\t\tpv[key] = () => {\n\t\t\t\t\treturn { tag, value: value() };\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tpv[key] = { tag, value };\n\t\t\t}\n\t\t\treturn pv;\n\t\t}, {}) as ReturnType<typeof tagData>;\n\n/**\n * Helper function to tag telemetry properties as CodeArtifacts. It supports properties of type\n * TelemetryBaseEventPropertyType as well as getters that return TelemetryBaseEventPropertyType.\n */\nexport const tagCodeArtifacts = <\n\tT extends Record<\n\t\tstring,\n\t\tTelemetryBaseEventPropertyType | (() => TelemetryBaseEventPropertyType)\n\t>,\n>(\n\tvalues: T,\n): {\n\t[P in keyof T]:\n\t\t| (T[P] extends () => TelemetryBaseEventPropertyType\n\t\t\t\t? () => {\n\t\t\t\t\t\tvalue: ReturnType<T[P]>;\n\t\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact;\n\t\t\t\t }\n\t\t\t\t: {\n\t\t\t\t\t\tvalue: Exclude<T[P], undefined>;\n\t\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact;\n\t\t\t\t })\n\t\t| (T[P] extends undefined ? undefined : never);\n} => tagData<TelemetryDataTag.CodeArtifact, T>(TelemetryDataTag.CodeArtifact, values);\n"]}
@@ -2,17 +2,18 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { ITelemetryBaseEvent } from "@fluidframework/common-definitions";
6
- import { TelemetryLogger } from "./logger";
5
+ import { ITelemetryBaseEvent, ITelemetryBaseLogger, LogLevel } from "@fluidframework/core-interfaces";
7
6
  import { ITelemetryLoggerExt } from "./telemetryTypes";
8
7
  /**
9
8
  * The MockLogger records events sent to it, and then can walk back over those events
10
9
  * searching for a set of expected events to match against the logged events.
11
10
  */
12
- export declare class MockLogger extends TelemetryLogger implements ITelemetryLoggerExt {
11
+ export declare class MockLogger implements ITelemetryBaseLogger {
12
+ readonly minLogLevel?: LogLevel | undefined;
13
13
  events: ITelemetryBaseEvent[];
14
- constructor();
14
+ constructor(minLogLevel?: LogLevel | undefined);
15
15
  clear(): void;
16
+ toTelemetryLogger(): ITelemetryLoggerExt;
16
17
  send(event: ITelemetryBaseEvent): void;
17
18
  /**
18
19
  * Search events logged since the last time matchEvents was called, looking for the given expected
@@ -23,7 +24,9 @@ export declare class MockLogger extends TelemetryLogger implements ITelemetryLog
23
24
  * Note: category is omitted from the type because it's usually uninteresting and tedious to type.
24
25
  */
25
26
  matchEvents(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], inlineDetailsProp?: boolean): boolean;
26
- /** Asserts that matchEvents is true, and prints the actual/expected output if not */
27
+ /**
28
+ * Asserts that matchEvents is true, and prints the actual/expected output if not.
29
+ */
27
30
  assertMatch(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string, inlineDetailsProp?: boolean): void;
28
31
  /**
29
32
  * Search events logged since the last time matchEvents was called, looking for any of the given
@@ -35,7 +38,9 @@ export declare class MockLogger extends TelemetryLogger implements ITelemetryLog
35
38
  * @returns if any of the expected events is found.
36
39
  */
37
40
  matchAnyEvent(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], inlineDetailsProp?: boolean): boolean;
38
- /** Asserts that matchAnyEvent is true, and prints the actual/expected output if not */
41
+ /**
42
+ * Asserts that matchAnyEvent is true, and prints the actual/expected output if not.
43
+ */
39
44
  assertMatchAny(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string, inlineDetailsProp?: boolean): void;
40
45
  /**
41
46
  * Search events logged since the last time matchEvents was called, looking only for the given expected
@@ -46,9 +51,13 @@ export declare class MockLogger extends TelemetryLogger implements ITelemetryLog
46
51
  * Note: category is omitted from the type because it's usually uninteresting and tedious to type.
47
52
  */
48
53
  matchEventStrict(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], inlineDetailsProp?: boolean): boolean;
49
- /** Asserts that matchEvents is true, and prints the actual/expected output if not */
54
+ /**
55
+ * Asserts that matchEvents is true, and prints the actual/expected output if not
56
+ */
50
57
  assertMatchStrict(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string, inlineDetailsProp?: boolean): void;
51
- /** Asserts that matchAnyEvent is false for the given events, and prints the actual/expected output if not */
58
+ /**
59
+ * Asserts that matchAnyEvent is false for the given events, and prints the actual/expected output if not
60
+ */
52
61
  assertMatchNone(disallowedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string, inlineDetailsProp?: boolean): void;
53
62
  private getMatchedEventsCount;
54
63
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"mockLogger.d.ts","sourceRoot":"","sources":["../src/mockLogger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAEzE,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD;;;GAGG;AACH,qBAAa,UAAW,SAAQ,eAAgB,YAAW,mBAAmB;IAC7E,MAAM,EAAE,mBAAmB,EAAE,CAAM;;IAMnC,KAAK;IAIL,IAAI,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;IAItC;;;;;;;OAOG;IACH,WAAW,CACV,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,iBAAiB,GAAE,OAAe,GAChC,OAAO;IAUV,qFAAqF;IACrF,WAAW,CACV,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe;IAanC;;;;;;;;OAQG;IACH,aAAa,CACZ,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,iBAAiB,GAAE,OAAe,GAChC,OAAO;IAQV,uFAAuF;IACvF,cAAc,CACb,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe;IAanC;;;;;;;OAOG;IACH,gBAAgB,CACf,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,iBAAiB,GAAE,OAAe,GAChC,OAAO;IAOV,qFAAqF;IACrF,iBAAiB,CAChB,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe;IAanC,6GAA6G;IAC7G,eAAe,CACd,gBAAgB,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACzD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe;IAanC,OAAO,CAAC,qBAAqB;IAsB7B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;CAqB1B"}
1
+ {"version":3,"file":"mockLogger.d.ts","sourceRoot":"","sources":["../src/mockLogger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,mBAAmB,EACnB,oBAAoB,EACpB,QAAQ,EACR,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,mBAAmB,EAA2B,MAAM,kBAAkB,CAAC;AAGhF;;;GAGG;AACH,qBAAa,UAAW,YAAW,oBAAoB;aAG1B,WAAW,CAAC;IAFxC,MAAM,EAAE,mBAAmB,EAAE,CAAM;gBAEP,WAAW,CAAC,sBAAU;IAElD,KAAK,IAAI,IAAI;IAIb,iBAAiB,IAAI,mBAAmB;IAIxC,IAAI,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;IAItC;;;;;;;OAOG;IACH,WAAW,CACV,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,iBAAiB,GAAE,OAAe,GAChC,OAAO;IAUV;;OAEG;IACH,WAAW,CACV,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe,GAChC,IAAI;IAYP;;;;;;;;OAQG;IACH,aAAa,CACZ,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,iBAAiB,GAAE,OAAe,GAChC,OAAO;IAQV;;OAEG;IACH,cAAc,CACb,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe,GAChC,IAAI;IAYP;;;;;;;OAOG;IACH,gBAAgB,CACf,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,iBAAiB,GAAE,OAAe,GAChC,OAAO;IAOV;;OAEG;IACH,iBAAiB,CAChB,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe,GAChC,IAAI;IAYP;;OAEG;IACH,eAAe,CACd,gBAAgB,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACzD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe,GAChC,IAAI;IAYP,OAAO,CAAC,qBAAqB;IAsB7B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;CAsB1B"}
package/lib/mockLogger.js CHANGED
@@ -2,31 +2,23 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- var __rest = (this && this.__rest) || function (s, e) {
6
- var t = {};
7
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
8
- t[p] = s[p];
9
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
10
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
11
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
12
- t[p[i]] = s[p[i]];
13
- }
14
- return t;
15
- };
16
- import { assert } from "@fluidframework/common-utils";
17
- import { TelemetryLogger } from "./logger";
5
+ import { assert } from "@fluidframework/core-utils";
6
+ import { createChildLogger } from "./logger";
18
7
  /**
19
8
  * The MockLogger records events sent to it, and then can walk back over those events
20
9
  * searching for a set of expected events to match against the logged events.
21
10
  */
22
- export class MockLogger extends TelemetryLogger {
23
- constructor() {
24
- super();
11
+ export class MockLogger {
12
+ constructor(minLogLevel) {
13
+ this.minLogLevel = minLogLevel;
25
14
  this.events = [];
26
15
  }
27
16
  clear() {
28
17
  this.events = [];
29
18
  }
19
+ toTelemetryLogger() {
20
+ return createChildLogger({ logger: this });
21
+ }
30
22
  send(event) {
31
23
  this.events.push(event);
32
24
  }
@@ -44,7 +36,9 @@ export class MockLogger extends TelemetryLogger {
44
36
  const unmatchedExpectedEventCount = expectedEvents.length - matchedExpectedEventCount;
45
37
  return unmatchedExpectedEventCount === 0;
46
38
  }
47
- /** Asserts that matchEvents is true, and prints the actual/expected output if not */
39
+ /**
40
+ * Asserts that matchEvents is true, and prints the actual/expected output if not.
41
+ */
48
42
  assertMatch(expectedEvents, message, inlineDetailsProp = false) {
49
43
  const actualEvents = this.events;
50
44
  if (!this.matchEvents(expectedEvents, inlineDetailsProp)) {
@@ -69,7 +63,9 @@ ${JSON.stringify(actualEvents)}`);
69
63
  const matchedExpectedEventCount = this.getMatchedEventsCount(expectedEvents, inlineDetailsProp);
70
64
  return matchedExpectedEventCount > 0;
71
65
  }
72
- /** Asserts that matchAnyEvent is true, and prints the actual/expected output if not */
66
+ /**
67
+ * Asserts that matchAnyEvent is true, and prints the actual/expected output if not.
68
+ */
73
69
  assertMatchAny(expectedEvents, message, inlineDetailsProp = false) {
74
70
  const actualEvents = this.events;
75
71
  if (!this.matchAnyEvent(expectedEvents, inlineDetailsProp)) {
@@ -93,7 +89,9 @@ ${JSON.stringify(actualEvents)}`);
93
89
  return (expectedEvents.length === this.events.length &&
94
90
  this.matchEvents(expectedEvents, inlineDetailsProp));
95
91
  }
96
- /** Asserts that matchEvents is true, and prints the actual/expected output if not */
92
+ /**
93
+ * Asserts that matchEvents is true, and prints the actual/expected output if not
94
+ */
97
95
  assertMatchStrict(expectedEvents, message, inlineDetailsProp = false) {
98
96
  const actualEvents = this.events;
99
97
  if (!this.matchEventStrict(expectedEvents, inlineDetailsProp)) {
@@ -105,7 +103,9 @@ actual:
105
103
  ${JSON.stringify(actualEvents)}`);
106
104
  }
107
105
  }
108
- /** Asserts that matchAnyEvent is false for the given events, and prints the actual/expected output if not */
106
+ /**
107
+ * Asserts that matchAnyEvent is false for the given events, and prints the actual/expected output if not
108
+ */
109
109
  assertMatchNone(disallowedEvents, message, inlineDetailsProp = false) {
110
110
  const actualEvents = this.events;
111
111
  if (this.matchAnyEvent(disallowedEvents, inlineDetailsProp)) {
@@ -119,13 +119,13 @@ ${JSON.stringify(actualEvents)}`);
119
119
  }
120
120
  getMatchedEventsCount(expectedEvents, inlineDetailsProp) {
121
121
  let iExpectedEvent = 0;
122
- this.events.forEach((event) => {
122
+ for (const event of this.events) {
123
123
  if (iExpectedEvent < expectedEvents.length &&
124
124
  MockLogger.eventsMatch(event, expectedEvents[iExpectedEvent], inlineDetailsProp)) {
125
125
  // We found the next expected event; increment
126
126
  ++iExpectedEvent;
127
127
  }
128
- });
128
+ }
129
129
  // Remove the events so far; next call will just compare subsequent events from here
130
130
  this.events = [];
131
131
  // Return the count of matched events.
@@ -135,18 +135,39 @@ ${JSON.stringify(actualEvents)}`);
135
135
  * Ensure the expected event is a strict subset of the actual event
136
136
  */
137
137
  static eventsMatch(actual, expected, inlineDetailsProp) {
138
- const { details } = actual, actualForMatching = __rest(actual, ["details"]);
139
- let detailsExpanded = { details };
138
+ const { details, ...actualForMatching } = actual;
140
139
  // "details" is used in a lot of telemetry logs to group a bunch of properties together and stringify them.
141
140
  // Some of the properties in the expected event may be inside "details". So, if inlineDetailsProp is true,
142
141
  // extract the properties from "details" in the actual event and inline them in the actual event.
143
142
  if (inlineDetailsProp && details !== undefined) {
144
- assert(typeof details === "string", 0x6c9 /* Details should a JSON stringified string if inlineDetailsProp is true */);
145
- detailsExpanded = JSON.parse(details);
143
+ assert(typeof details === "string",
144
+ // eslint-disable-next-line unicorn/numeric-separators-style
145
+ 0x6c9 /* Details should a JSON stringified string if inlineDetailsProp is true */);
146
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
147
+ const detailsExpanded = JSON.parse(details);
148
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
149
+ return matchObjects({ ...actualForMatching, ...detailsExpanded }, expected);
150
+ }
151
+ return matchObjects(actual, expected);
152
+ }
153
+ }
154
+ function matchObjects(actual, expected) {
155
+ for (const [expectedKey, expectedValue] of Object.entries(expected)) {
156
+ const actualValue = actual[expectedKey];
157
+ if (!Array.isArray(expectedValue) &&
158
+ expectedValue !== null &&
159
+ typeof expectedValue === "object") {
160
+ if (Array.isArray(actualValue) ||
161
+ actualValue === null ||
162
+ typeof actualValue !== "object" ||
163
+ !matchObjects(actualValue, expectedValue)) {
164
+ return false;
165
+ }
166
+ }
167
+ else if (JSON.stringify(actualValue) !== JSON.stringify(expectedValue)) {
168
+ return false;
146
169
  }
147
- const actualExpanded = Object.assign(Object.assign({}, actualForMatching), detailsExpanded);
148
- const masked = Object.assign(Object.assign({}, actualExpanded), expected);
149
- return JSON.stringify(masked) === JSON.stringify(actualExpanded);
150
170
  }
171
+ return true;
151
172
  }
152
173
  //# sourceMappingURL=mockLogger.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mockLogger.js","sourceRoot":"","sources":["../src/mockLogger.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 { ITelemetryBaseEvent } from \"@fluidframework/common-definitions\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { TelemetryLogger } from \"./logger\";\nimport { ITelemetryLoggerExt } from \"./telemetryTypes\";\n\n/**\n * The MockLogger records events sent to it, and then can walk back over those events\n * searching for a set of expected events to match against the logged events.\n */\nexport class MockLogger extends TelemetryLogger implements ITelemetryLoggerExt {\n\tevents: ITelemetryBaseEvent[] = [];\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tclear() {\n\t\tthis.events = [];\n\t}\n\n\tsend(event: ITelemetryBaseEvent): void {\n\t\tthis.events.push(event);\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking for the given expected\n\t * events in order.\n\t * @param expectedEvents - events in order that are expected to appear in the recorded log.\n\t * @param inlineDetailsProp - true if the \"details\" property in the actual event should be extracted and inlined.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t */\n\tmatchEvents(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t): boolean {\n\t\tconst matchedExpectedEventCount = this.getMatchedEventsCount(\n\t\t\texpectedEvents,\n\t\t\tinlineDetailsProp,\n\t\t);\n\t\t// How many expected events were left over? Hopefully none.\n\t\tconst unmatchedExpectedEventCount = expectedEvents.length - matchedExpectedEventCount;\n\t\treturn unmatchedExpectedEventCount === 0;\n\t}\n\n\t/** Asserts that matchEvents is true, and prints the actual/expected output if not */\n\tassertMatch(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t) {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchEvents(expectedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking for any of the given\n\t * expected events.\n\t * @param expectedEvents - events that are expected to appear in the recorded log.\n\t * @param inlineDetailsProp - true if the \"details\" property in the actual event should be extracted and inlined.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t * @returns if any of the expected events is found.\n\t */\n\tmatchAnyEvent(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t): boolean {\n\t\tconst matchedExpectedEventCount = this.getMatchedEventsCount(\n\t\t\texpectedEvents,\n\t\t\tinlineDetailsProp,\n\t\t);\n\t\treturn matchedExpectedEventCount > 0;\n\t}\n\n\t/** Asserts that matchAnyEvent is true, and prints the actual/expected output if not */\n\tassertMatchAny(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t) {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchAnyEvent(expectedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking only for the given expected\n\t * events in order.\n\t * @param expectedEvents - events in order that are expected to be the only events in the recorded log.\n\t * @param inlineDetailsProp - true if the \"details\" property in the actual event should be extracted and inlined.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t */\n\tmatchEventStrict(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t): boolean {\n\t\treturn (\n\t\t\texpectedEvents.length === this.events.length &&\n\t\t\tthis.matchEvents(expectedEvents, inlineDetailsProp)\n\t\t);\n\t}\n\n\t/** Asserts that matchEvents is true, and prints the actual/expected output if not */\n\tassertMatchStrict(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t) {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchEventStrict(expectedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/** Asserts that matchAnyEvent is false for the given events, and prints the actual/expected output if not */\n\tassertMatchNone(\n\t\tdisallowedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t) {\n\t\tconst actualEvents = this.events;\n\t\tif (this.matchAnyEvent(disallowedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\ndisallowed events:\n${JSON.stringify(disallowedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\tprivate getMatchedEventsCount(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean,\n\t): number {\n\t\tlet iExpectedEvent = 0;\n\t\tthis.events.forEach((event) => {\n\t\t\tif (\n\t\t\t\tiExpectedEvent < expectedEvents.length &&\n\t\t\t\tMockLogger.eventsMatch(event, expectedEvents[iExpectedEvent], inlineDetailsProp)\n\t\t\t) {\n\t\t\t\t// We found the next expected event; increment\n\t\t\t\t++iExpectedEvent;\n\t\t\t}\n\t\t});\n\n\t\t// Remove the events so far; next call will just compare subsequent events from here\n\t\tthis.events = [];\n\n\t\t// Return the count of matched events.\n\t\treturn iExpectedEvent;\n\t}\n\n\t/**\n\t * Ensure the expected event is a strict subset of the actual event\n\t */\n\tprivate static eventsMatch(\n\t\tactual: ITelemetryBaseEvent,\n\t\texpected: Omit<ITelemetryBaseEvent, \"category\">,\n\t\tinlineDetailsProp: boolean,\n\t): boolean {\n\t\tconst { details, ...actualForMatching } = actual;\n\t\tlet detailsExpanded = { details };\n\t\t// \"details\" is used in a lot of telemetry logs to group a bunch of properties together and stringify them.\n\t\t// Some of the properties in the expected event may be inside \"details\". So, if inlineDetailsProp is true,\n\t\t// extract the properties from \"details\" in the actual event and inline them in the actual event.\n\t\tif (inlineDetailsProp && details !== undefined) {\n\t\t\tassert(\n\t\t\t\ttypeof details === \"string\",\n\t\t\t\t0x6c9 /* Details should a JSON stringified string if inlineDetailsProp is true */,\n\t\t\t);\n\t\t\tdetailsExpanded = JSON.parse(details);\n\t\t}\n\t\tconst actualExpanded: ITelemetryBaseEvent = { ...actualForMatching, ...detailsExpanded };\n\t\tconst masked = { ...actualExpanded, ...expected };\n\t\treturn JSON.stringify(masked) === JSON.stringify(actualExpanded);\n\t}\n}\n"]}
1
+ {"version":3,"file":"mockLogger.js","sourceRoot":"","sources":["../src/mockLogger.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 {\n\tITelemetryBaseEvent,\n\tITelemetryBaseLogger,\n\tLogLevel,\n} from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/core-utils\";\nimport { ITelemetryLoggerExt, ITelemetryPropertiesExt } from \"./telemetryTypes\";\nimport { createChildLogger } from \"./logger\";\n\n/**\n * The MockLogger records events sent to it, and then can walk back over those events\n * searching for a set of expected events to match against the logged events.\n */\nexport class MockLogger implements ITelemetryBaseLogger {\n\tevents: ITelemetryBaseEvent[] = [];\n\n\tconstructor(public readonly minLogLevel?: LogLevel) {}\n\n\tclear(): void {\n\t\tthis.events = [];\n\t}\n\n\ttoTelemetryLogger(): ITelemetryLoggerExt {\n\t\treturn createChildLogger({ logger: this });\n\t}\n\n\tsend(event: ITelemetryBaseEvent): void {\n\t\tthis.events.push(event);\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking for the given expected\n\t * events in order.\n\t * @param expectedEvents - events in order that are expected to appear in the recorded log.\n\t * @param inlineDetailsProp - true if the \"details\" property in the actual event should be extracted and inlined.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t */\n\tmatchEvents(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t): boolean {\n\t\tconst matchedExpectedEventCount = this.getMatchedEventsCount(\n\t\t\texpectedEvents,\n\t\t\tinlineDetailsProp,\n\t\t);\n\t\t// How many expected events were left over? Hopefully none.\n\t\tconst unmatchedExpectedEventCount = expectedEvents.length - matchedExpectedEventCount;\n\t\treturn unmatchedExpectedEventCount === 0;\n\t}\n\n\t/**\n\t * Asserts that matchEvents is true, and prints the actual/expected output if not.\n\t */\n\tassertMatch(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t): void {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchEvents(expectedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking for any of the given\n\t * expected events.\n\t * @param expectedEvents - events that are expected to appear in the recorded log.\n\t * @param inlineDetailsProp - true if the \"details\" property in the actual event should be extracted and inlined.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t * @returns if any of the expected events is found.\n\t */\n\tmatchAnyEvent(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t): boolean {\n\t\tconst matchedExpectedEventCount = this.getMatchedEventsCount(\n\t\t\texpectedEvents,\n\t\t\tinlineDetailsProp,\n\t\t);\n\t\treturn matchedExpectedEventCount > 0;\n\t}\n\n\t/**\n\t * Asserts that matchAnyEvent is true, and prints the actual/expected output if not.\n\t */\n\tassertMatchAny(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t): void {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchAnyEvent(expectedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking only for the given expected\n\t * events in order.\n\t * @param expectedEvents - events in order that are expected to be the only events in the recorded log.\n\t * @param inlineDetailsProp - true if the \"details\" property in the actual event should be extracted and inlined.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t */\n\tmatchEventStrict(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t): boolean {\n\t\treturn (\n\t\t\texpectedEvents.length === this.events.length &&\n\t\t\tthis.matchEvents(expectedEvents, inlineDetailsProp)\n\t\t);\n\t}\n\n\t/**\n\t * Asserts that matchEvents is true, and prints the actual/expected output if not\n\t */\n\tassertMatchStrict(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t): void {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchEventStrict(expectedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/**\n\t * Asserts that matchAnyEvent is false for the given events, and prints the actual/expected output if not\n\t */\n\tassertMatchNone(\n\t\tdisallowedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t): void {\n\t\tconst actualEvents = this.events;\n\t\tif (this.matchAnyEvent(disallowedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\ndisallowed events:\n${JSON.stringify(disallowedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\tprivate getMatchedEventsCount(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean,\n\t): number {\n\t\tlet iExpectedEvent = 0;\n\t\tfor (const event of this.events) {\n\t\t\tif (\n\t\t\t\tiExpectedEvent < expectedEvents.length &&\n\t\t\t\tMockLogger.eventsMatch(event, expectedEvents[iExpectedEvent], inlineDetailsProp)\n\t\t\t) {\n\t\t\t\t// We found the next expected event; increment\n\t\t\t\t++iExpectedEvent;\n\t\t\t}\n\t\t}\n\n\t\t// Remove the events so far; next call will just compare subsequent events from here\n\t\tthis.events = [];\n\n\t\t// Return the count of matched events.\n\t\treturn iExpectedEvent;\n\t}\n\n\t/**\n\t * Ensure the expected event is a strict subset of the actual event\n\t */\n\tprivate static eventsMatch(\n\t\tactual: ITelemetryBaseEvent,\n\t\texpected: Omit<ITelemetryBaseEvent, \"category\">,\n\t\tinlineDetailsProp: boolean,\n\t): boolean {\n\t\tconst { details, ...actualForMatching } = actual;\n\t\t// \"details\" is used in a lot of telemetry logs to group a bunch of properties together and stringify them.\n\t\t// Some of the properties in the expected event may be inside \"details\". So, if inlineDetailsProp is true,\n\t\t// extract the properties from \"details\" in the actual event and inline them in the actual event.\n\t\tif (inlineDetailsProp && details !== undefined) {\n\t\t\tassert(\n\t\t\t\ttypeof details === \"string\",\n\t\t\t\t// eslint-disable-next-line unicorn/numeric-separators-style\n\t\t\t\t0x6c9 /* Details should a JSON stringified string if inlineDetailsProp is true */,\n\t\t\t);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\tconst detailsExpanded = JSON.parse(details);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\treturn matchObjects({ ...actualForMatching, ...detailsExpanded }, expected);\n\t\t}\n\t\treturn matchObjects(actual, expected);\n\t}\n}\n\nfunction matchObjects(actual: ITelemetryPropertiesExt, expected: ITelemetryPropertiesExt): boolean {\n\tfor (const [expectedKey, expectedValue] of Object.entries(expected)) {\n\t\tconst actualValue = actual[expectedKey];\n\t\tif (\n\t\t\t!Array.isArray(expectedValue) &&\n\t\t\texpectedValue !== null &&\n\t\t\ttypeof expectedValue === \"object\"\n\t\t) {\n\t\t\tif (\n\t\t\t\tArray.isArray(actualValue) ||\n\t\t\t\tactualValue === null ||\n\t\t\t\ttypeof actualValue !== \"object\" ||\n\t\t\t\t!matchObjects(\n\t\t\t\t\tactualValue as ITelemetryPropertiesExt,\n\t\t\t\t\texpectedValue as ITelemetryPropertiesExt,\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else if (JSON.stringify(actualValue) !== JSON.stringify(expectedValue)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n"]}
@@ -2,11 +2,11 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { IDisposable, ITelemetryGenericEvent, ITelemetryProperties } from "@fluidframework/common-definitions";
5
+ import { ITelemetryGenericEvent, ITelemetryProperties, IDisposable } from "@fluidframework/core-interfaces";
6
6
  import { ITelemetryLoggerExt } from "./telemetryTypes";
7
7
  /**
8
8
  * Helper class that executes a specified code block and writes an
9
- * {@link @fluidframework/common-definitions#ITelemetryPerformanceEvent} to a specified logger every time a specified
9
+ * {@link @fluidframework/core-interfaces#ITelemetryPerformanceEvent} to a specified logger every time a specified
10
10
  * number of executions is reached (or when the class is disposed). The `duration` field in the telemetry event is
11
11
  * the duration of the latest execution (sample) of the specified function. See the documentation of the
12
12
  * `includeAggregateMetrics` parameter for additional details that can be included.
@@ -39,12 +39,13 @@ export declare class SampledTelemetryHelper implements IDisposable {
39
39
  */
40
40
  constructor(eventBase: ITelemetryGenericEvent, logger: ITelemetryLoggerExt, sampleThreshold: number, includeAggregateMetrics?: boolean, perBucketProperties?: Map<string, ITelemetryProperties>);
41
41
  /**
42
- * @param codeToMeasure -
43
- * The code to be executed and measured.
44
- * @param bucket -
45
- * A key to track executions of the code block separately. Each different value of this parameter has a separate
46
- * set of executions and metrics tracked by the class. If no such distinction needs to be made, do not provide a
47
- * value.
42
+ * Executes the specified code and keeps track of execution time statistics.
43
+ * If it's been called enough times (the sampleThreshold for the class) then it generates a log message with the necessary information.
44
+ *
45
+ * @param codeToMeasure - The code to be executed and measured.
46
+ * @param bucket - A key to track executions of the code block separately.
47
+ * Each different value of this parameter has a separate set of executions and metrics tracked by the class.
48
+ * If no such distinction needs to be made, do not provide a value.
48
49
  * @returns Whatever the passed-in code block returns.
49
50
  */
50
51
  measure<T>(codeToMeasure: () => T, bucket?: string): T;
@@ -1 +1 @@
1
- {"version":3,"file":"sampledTelemetryHelper.d.ts","sourceRoot":"","sources":["../src/sampledTelemetryHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,WAAW,EACX,sBAAsB,EAEtB,oBAAoB,EACpB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAiCvD;;;;;;GAMG;AACH,qBAAa,sBAAuB,YAAW,WAAW;IAwBxD,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,uBAAuB;IACxC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IA3BrC,QAAQ,EAAE,OAAO,CAAS;IAE1B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAmC;IAEnE;;;;;;;;;;;;;;;;;OAiBG;gBAEe,SAAS,EAAE,sBAAsB,EACjC,MAAM,EAAE,mBAAmB,EAC3B,eAAe,EAAE,MAAM,EACvB,uBAAuB,GAAE,OAAe,EACxC,mBAAmB,oCAA0C;IAG/E;;;;;;;;OAQG;IACI,OAAO,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,MAAM,GAAE,MAAW,GAAG,CAAC;IA0BjE,OAAO,CAAC,WAAW;IAoBZ,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,IAAI;CAG/C"}
1
+ {"version":3,"file":"sampledTelemetryHelper.d.ts","sourceRoot":"","sources":["../src/sampledTelemetryHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,sBAAsB,EAEtB,oBAAoB,EACpB,WAAW,EACX,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAoCvD;;;;;;GAMG;AACH,qBAAa,sBAAuB,YAAW,WAAW;IAwBxD,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,uBAAuB;IACxC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IA3BrC,QAAQ,EAAE,OAAO,CAAS;IAE1B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAmC;IAEnE;;;;;;;;;;;;;;;;;OAiBG;gBAEe,SAAS,EAAE,sBAAsB,EACjC,MAAM,EAAE,mBAAmB,EAC3B,eAAe,EAAE,MAAM,EACvB,uBAAuB,GAAE,OAAe,EACxC,mBAAmB,oCAA0C;IAG/E;;;;;;;;;OASG;IACI,OAAO,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,MAAM,GAAE,MAAW,GAAG,CAAC;IA0BjE,OAAO,CAAC,WAAW;IAoBZ,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,IAAI;CAG/C"}
@@ -2,10 +2,10 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { performance } from "@fluidframework/common-utils";
5
+ import { performance } from "@fluid-internal/client-utils";
6
6
  /**
7
7
  * Helper class that executes a specified code block and writes an
8
- * {@link @fluidframework/common-definitions#ITelemetryPerformanceEvent} to a specified logger every time a specified
8
+ * {@link @fluidframework/core-interfaces#ITelemetryPerformanceEvent} to a specified logger every time a specified
9
9
  * number of executions is reached (or when the class is disposed). The `duration` field in the telemetry event is
10
10
  * the duration of the latest execution (sample) of the specified function. See the documentation of the
11
11
  * `includeAggregateMetrics` parameter for additional details that can be included.
@@ -39,16 +39,16 @@ export class SampledTelemetryHelper {
39
39
  this.measurementsMap = new Map();
40
40
  }
41
41
  /**
42
- * @param codeToMeasure -
43
- * The code to be executed and measured.
44
- * @param bucket -
45
- * A key to track executions of the code block separately. Each different value of this parameter has a separate
46
- * set of executions and metrics tracked by the class. If no such distinction needs to be made, do not provide a
47
- * value.
42
+ * Executes the specified code and keeps track of execution time statistics.
43
+ * If it's been called enough times (the sampleThreshold for the class) then it generates a log message with the necessary information.
44
+ *
45
+ * @param codeToMeasure - The code to be executed and measured.
46
+ * @param bucket - A key to track executions of the code block separately.
47
+ * Each different value of this parameter has a separate set of executions and metrics tracked by the class.
48
+ * If no such distinction needs to be made, do not provide a value.
48
49
  * @returns Whatever the passed-in code block returns.
49
50
  */
50
51
  measure(codeToMeasure, bucket = "") {
51
- var _a, _b, _c;
52
52
  const start = performance.now();
53
53
  const returnValue = codeToMeasure();
54
54
  const duration = performance.now() - start;
@@ -60,9 +60,9 @@ export class SampledTelemetryHelper {
60
60
  m.count++;
61
61
  m.duration = duration;
62
62
  if (this.includeAggregateMetrics) {
63
- m.totalDuration = ((_a = m.totalDuration) !== null && _a !== void 0 ? _a : 0) + duration;
64
- m.minDuration = Math.min((_b = m.minDuration) !== null && _b !== void 0 ? _b : duration, duration);
65
- m.maxDuration = Math.max((_c = m.maxDuration) !== null && _c !== void 0 ? _c : 0, duration);
63
+ m.totalDuration = (m.totalDuration ?? 0) + duration;
64
+ m.minDuration = Math.min(m.minDuration ?? duration, duration);
65
+ m.maxDuration = Math.max(m.maxDuration ?? 0, duration);
66
66
  }
67
67
  if (m.count >= this.sampleThreshold) {
68
68
  this.flushBucket(bucket);
@@ -76,13 +76,18 @@ export class SampledTelemetryHelper {
76
76
  }
77
77
  if (measurements.count !== 0) {
78
78
  const bucketProperties = this.perBucketProperties.get(bucket);
79
- const telemetryEvent = Object.assign(Object.assign(Object.assign({}, this.eventBase), bucketProperties), measurements);
79
+ const telemetryEvent = {
80
+ ...this.eventBase,
81
+ ...bucketProperties,
82
+ ...measurements,
83
+ };
80
84
  this.logger.sendPerformanceEvent(telemetryEvent);
81
85
  this.measurementsMap.delete(bucket);
82
86
  }
83
87
  }
84
88
  dispose(error) {
85
- this.measurementsMap.forEach((_, k) => this.flushBucket(k));
89
+ for (const [k] of this.measurementsMap.entries())
90
+ this.flushBucket(k);
86
91
  }
87
92
  }
88
93
  //# sourceMappingURL=sampledTelemetryHelper.js.map