@fluidframework/telemetry-utils 2.20.0 → 2.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc.cjs CHANGED
@@ -8,7 +8,4 @@ module.exports = {
8
8
  parserOptions: {
9
9
  project: ["./tsconfig.json", "./src/test/tsconfig.json"],
10
10
  },
11
- rules: {
12
- "@fluid-internal/fluid/no-unchecked-record-access": "warn",
13
- },
14
11
  };
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @fluidframework/telemetry-utils
2
2
 
3
+ ## 2.22.0
4
+
5
+ Dependency updates only.
6
+
7
+ ## 2.21.0
8
+
9
+ Dependency updates only.
10
+
3
11
  ## 2.20.0
4
12
 
5
13
  ### Minor Changes
package/README.md CHANGED
@@ -58,6 +58,7 @@ When making such a request please include if the configuration already works (an
58
58
  ### Supported Runtimes
59
59
 
60
60
  - NodeJs ^20.10.0 except that we will drop support for it [when NodeJs 20 loses its upstream support on 2026-04-30](https://github.com/nodejs/release#release-schedule), and will support a newer LTS version of NodeJS (22) at least 1 year before 20 is end-of-life. This same policy applies to NodeJS 22 when it is end of life (2027-04-30).
61
+ - Running Fluid in a Node.js environment with the `--no-experimental-fetch` flag is not supported.
61
62
  - Modern browsers supporting the es2022 standard library: in response to asks we can add explicit support for using babel to polyfill to target specific standards or runtimes (meaning we can avoid/remove use of things that don't polyfill robustly, but otherwise target modern standards).
62
63
 
63
64
  ### Supported Tools
@@ -94,11 +94,11 @@ function normalizeError(error, annotations = {}) {
94
94
  const maybeHasRetry = error;
95
95
  let retryProps;
96
96
  if ("canRetry" in error) {
97
- retryProps ?? (retryProps = {});
97
+ retryProps ??= {};
98
98
  retryProps.canRetry = maybeHasRetry.canRetry;
99
99
  }
100
100
  if ("retryAfterSeconds" in error) {
101
- retryProps ?? (retryProps = {});
101
+ retryProps ??= {};
102
102
  retryProps.retryAfterSeconds = maybeHasRetry.retryAfterSeconds;
103
103
  }
104
104
  if (retryProps !== undefined) {
@@ -1 +1 @@
1
- {"version":3,"file":"errorLogging.js","sourceRoot":"","sources":["../src/errorLogging.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 type { ITelemetryBaseProperties, Tagged } from \"@fluidframework/core-interfaces\";\nimport type { ILoggingError } from \"@fluidframework/core-interfaces/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { type IFluidErrorBase, hasErrorInstanceId, isFluidError } from \"./fluidErrorBase.js\";\nimport { convertToBasePropertyType } from \"./logger.js\";\nimport type {\n\tITelemetryLoggerExt,\n\tITelemetryPropertiesExt,\n\tTelemetryEventPropertyTypeExt,\n} from \"./telemetryTypes.js\";\n\n/**\n * Determines if the provided value is an object but neither null nor an array.\n */\nconst isRegularObject = (value: unknown): boolean => {\n\treturn value !== null && !Array.isArray(value) && typeof value === \"object\";\n};\n\n/**\n * Inspect the given error for common \"safe\" props and return them.\n *\n * @internal\n */\nexport function extractLogSafeErrorProperties(\n\terror: unknown,\n\tsanitizeStack: boolean,\n): {\n\tmessage: string;\n\terrorType?: string | undefined;\n\tstack?: string | undefined;\n} {\n\tconst removeMessageFromStack = (stack: string, errorName?: string): string => {\n\t\tif (!sanitizeStack) {\n\t\t\treturn stack;\n\t\t}\n\t\tconst stackFrames = stack.split(\"\\n\");\n\t\tstackFrames.shift(); // Remove \"[ErrorName]: [ErrorMessage]\"\n\t\tif (errorName !== undefined) {\n\t\t\tstackFrames.unshift(errorName); // Add \"[ErrorName]\"\n\t\t}\n\t\treturn stackFrames.join(\"\\n\");\n\t};\n\n\tconst message =\n\t\ttypeof (error as Partial<Error>)?.message === \"string\"\n\t\t\t? (error as Error).message\n\t\t\t: String(error);\n\n\tconst safeProps: { message: string; errorType?: string; stack?: string } = {\n\t\tmessage,\n\t};\n\n\tif (isRegularObject(error)) {\n\t\tconst { errorType, stack, name } = error as Partial<IFluidErrorBase>;\n\n\t\tif (typeof errorType === \"string\") {\n\t\t\tsafeProps.errorType = errorType;\n\t\t}\n\n\t\tif (typeof stack === \"string\") {\n\t\t\tconst errorName = typeof name === \"string\" ? name : undefined;\n\t\t\tsafeProps.stack = removeMessageFromStack(stack, errorName);\n\t\t}\n\t}\n\n\treturn safeProps;\n}\n\n/**\n * Type-guard for {@link @fluidframework/core-interfaces#ILoggingError}.\n *\n * @internal\n */\nexport const isILoggingError = (x: unknown): x is ILoggingError =>\n\ttypeof (x as Partial<ILoggingError>)?.getTelemetryProperties === \"function\";\n\n/**\n * Copy props from source onto target, but do not overwrite an existing prop that matches\n */\nfunction copyProps(\n\ttarget: ITelemetryPropertiesExt | LoggingError,\n\tsource: ITelemetryPropertiesExt,\n): void {\n\tfor (const [key, value] of Object.entries(source)) {\n\t\tif (target[key] === undefined) {\n\t\t\ttarget[key] = value;\n\t\t}\n\t}\n}\n\n/**\n * Metadata to annotate an error object when annotating or normalizing it\n *\n * @internal\n */\nexport interface IFluidErrorAnnotations {\n\t/**\n\t * Telemetry props to log with the error\n\t */\n\tprops?: ITelemetryBaseProperties;\n}\n\n/**\n * Normalize the given error yielding a valid Fluid Error\n * @returns A valid Fluid Error with any provided annotations applied\n * @param error - The error to normalize\n * @param annotations - Annotations to apply to the normalized error\n *\n * @internal\n */\nexport function normalizeError(\n\terror: unknown,\n\tannotations: IFluidErrorAnnotations = {},\n): IFluidErrorBase {\n\tif (isFluidError(error)) {\n\t\t// We can simply add the telemetry props to the error and return it\n\t\terror.addTelemetryProperties(annotations.props ?? {});\n\t\treturn error;\n\t}\n\n\t// We have to construct a new Fluid Error, copying safe properties over\n\tconst { message, stack } = extractLogSafeErrorProperties(error, false /* sanitizeStack */);\n\tconst fluidError: IFluidErrorBase = new NormalizedLoggingError({\n\t\tmessage,\n\t\tstack,\n\t});\n\n\t// We need to preserve these properties which are used in a non-typesafe way throughout driver code (see #8743)\n\t// Anywhere they are set should be on a valid Fluid Error that would have been returned above,\n\t// but we can't prove it with the types, so adding this defensive measure.\n\tif (typeof error === \"object\" && error !== null) {\n\t\tconst maybeHasRetry: Partial<Record<\"canRetry\" | \"retryAfterSeconds\", unknown>> = error;\n\t\tlet retryProps: Partial<Record<\"canRetry\" | \"retryAfterSeconds\", unknown>> | undefined;\n\t\tif (\"canRetry\" in error) {\n\t\t\tretryProps ??= {};\n\t\t\tretryProps.canRetry = maybeHasRetry.canRetry;\n\t\t}\n\t\tif (\"retryAfterSeconds\" in error) {\n\t\t\tretryProps ??= {};\n\t\t\tretryProps.retryAfterSeconds = maybeHasRetry.retryAfterSeconds;\n\t\t}\n\t\tif (retryProps !== undefined) {\n\t\t\tObject.assign(fluidError, retryProps);\n\t\t}\n\t}\n\n\tif (typeof error !== \"object\") {\n\t\t// This is only interesting for non-objects\n\t\tfluidError.addTelemetryProperties({ typeofError: typeof error });\n\t}\n\n\tconst errorTelemetryProps = LoggingError.typeCheck(error)\n\t\t? error.getTelemetryProperties()\n\t\t: {\n\t\t\t\tuntrustedOrigin: 1, // This will let us filter errors that did not originate from our own codebase\n\t\t\t\t// FUTURE: Once 2.0 becomes LTS, switch to this more explicit property name\n\t\t\t\t// Consider using a string to distinguish cases like \"dependency\" v. \"callback\"\n\t\t\t\t// errorRunningExternalCode: 1,\n\t\t\t};\n\n\tfluidError.addTelemetryProperties({\n\t\t...errorTelemetryProps,\n\t\t...annotations.props,\n\t});\n\n\treturn fluidError;\n}\n\nlet stackPopulatedOnCreation: boolean | undefined;\n\n/**\n * The purpose of this function is to provide ability to capture stack context quickly.\n * Accessing new Error().stack is slow, and the slowest part is accessing stack property itself.\n * There are scenarios where we generate error with stack, but error is handled in most cases and\n * stack property is not accessed.\n * For such cases it's better to not read stack property right away, but rather delay it until / if it's needed\n * Some browsers will populate stack right away, others require throwing Error, so we do auto-detection on the fly.\n * @param stackTraceLimit - stack trace limit for an error\n * @returns Error object that has stack populated.\n *\n * @internal\n */\nexport function generateErrorWithStack(stackTraceLimit?: number): Error {\n\tconst ErrorConfig = Error as unknown as { stackTraceLimit: number };\n\tconst originalStackTraceLimit = ErrorConfig.stackTraceLimit;\n\tif (stackTraceLimit !== undefined) {\n\t\tErrorConfig.stackTraceLimit = stackTraceLimit;\n\t}\n\tconst err = new Error(\"<<generated stack>>\");\n\n\tif (stackPopulatedOnCreation === undefined) {\n\t\tstackPopulatedOnCreation = err.stack !== undefined;\n\t}\n\n\tif (stackPopulatedOnCreation) {\n\t\tErrorConfig.stackTraceLimit = originalStackTraceLimit;\n\t\treturn err;\n\t}\n\n\ttry {\n\t\tthrow err;\n\t} catch (error) {\n\t\tErrorConfig.stackTraceLimit = originalStackTraceLimit;\n\t\treturn error as Error;\n\t}\n}\n\n/**\n * Generate a stack at this callsite as if an error were thrown from here.\n * @param stackTraceLimit - stack trace limit for an error\n * @returns the callstack (does not throw)\n *\n * @internal\n */\nexport function generateStack(stackTraceLimit?: number): string | undefined {\n\treturn generateErrorWithStack(stackTraceLimit).stack;\n}\n\n/**\n * Create a new error using newErrorFn, wrapping and caused by the given unknown error.\n * Copies the inner error's stack, errorInstanceId and telemetry props over to the new error if present\n * @param innerError - An error from untrusted/unknown origins\n * @param newErrorFn - callback that will create a new error given the original error's message\n * @returns A new error object \"wrapping\" the given error\n *\n * @internal\n */\nexport function wrapError<T extends LoggingError>(\n\tinnerError: unknown,\n\tnewErrorFn: (message: string) => T,\n): T {\n\tconst { message, stack } = extractLogSafeErrorProperties(\n\t\tinnerError,\n\t\tfalse /* sanitizeStack */,\n\t);\n\n\tconst newError = newErrorFn(message);\n\n\tif (stack !== undefined) {\n\t\toverwriteStack(newError, stack);\n\t}\n\n\t// Mark external errors with untrustedOrigin flag\n\tif (isExternalError(innerError)) {\n\t\tnewError.addTelemetryProperties({\n\t\t\tuntrustedOrigin: 1,\n\t\t\t// FUTURE: Once 2.0 becomes LTS, switch to this more explicit property name\n\t\t\t// Consider using a string to distinguish cases like \"dependency\" v. \"callback\"\n\t\t\t// errorRunningExternalCode: 1,\n\t\t});\n\t}\n\n\t// Reuse errorInstanceId\n\tif (hasErrorInstanceId(innerError)) {\n\t\tnewError.overwriteErrorInstanceId(innerError.errorInstanceId);\n\n\t\t// For \"back-compat\" in the logs\n\t\tnewError.addTelemetryProperties({ innerErrorInstanceId: innerError.errorInstanceId });\n\t}\n\n\t// Lastly, copy over all other telemetry properties. Note these will not overwrite existing properties\n\t// This will include the untrustedOrigin/errorRunningExternalCode info if the inner error itself was created from an external error\n\tif (isILoggingError(innerError)) {\n\t\tnewError.addTelemetryProperties(innerError.getTelemetryProperties());\n\t}\n\n\treturn newError;\n}\n\n/**\n * The same as wrapError, but also logs the innerError, including the wrapping error's instance ID.\n *\n * @typeParam T - The kind of wrapper error to create.\n *\n * @internal\n */\nexport function wrapErrorAndLog<T extends LoggingError>(\n\tinnerError: unknown,\n\tnewErrorFn: (message: string) => T,\n\tlogger: ITelemetryLoggerExt,\n): T {\n\tconst newError = wrapError(innerError, newErrorFn);\n\n\t// This will match innerError.errorInstanceId if present (see wrapError)\n\tconst errorInstanceId = newError.errorInstanceId;\n\n\t// For \"back-compat\" in the logs\n\tconst wrappedByErrorInstanceId = errorInstanceId;\n\n\tlogger.sendTelemetryEvent(\n\t\t{\n\t\t\teventName: \"WrapError\",\n\t\t\terrorInstanceId,\n\t\t\twrappedByErrorInstanceId,\n\t\t},\n\t\tinnerError,\n\t);\n\n\treturn newError;\n}\n\n/**\n * Attempts to overwrite the error's stack\n *\n * There have been reports of certain JS environments where overwriting stack will throw.\n * If that happens, this adds the given stack as the telemetry property \"stack2\"\n *\n * @internal\n */\nexport function overwriteStack(error: IFluidErrorBase | LoggingError, stack: string): void {\n\ttry {\n\t\tObject.assign(error, { stack });\n\t} catch {\n\t\terror.addTelemetryProperties({ stack2: stack });\n\t}\n}\n\n/**\n * True for any error object that is an (optionally normalized) external error\n * False for any error we created and raised within the FF codebase via LoggingError base class,\n * or wrapped in a well-known error type\n *\n * @internal\n */\nexport function isExternalError(error: unknown): boolean {\n\t// LoggingErrors are an internal FF error type. However, an external error can be converted\n\t// into a LoggingError if it is normalized. In this case we must use the untrustedOrigin/errorRunningExternalCode flag to\n\t// determine whether the original error was in fact external.\n\tif (LoggingError.typeCheck(error)) {\n\t\tif ((error as NormalizedLoggingError).errorType === NORMALIZED_ERROR_TYPE) {\n\t\t\tconst props = error.getTelemetryProperties();\n\t\t\t// NOTE: errorRunningExternalCode is not currently used - once this \"read\" code reaches LTS,\n\t\t\t// we can switch to writing this more explicit property\n\t\t\treturn props.untrustedOrigin === 1 || Boolean(props.errorRunningExternalCode);\n\t\t}\n\t\treturn false;\n\t}\n\treturn true;\n}\n\n/**\n * Type guard to identify if a particular telemetry property appears to be a\n * {@link @fluidframework/core-interfaces#Tagged} telemetry property.\n *\n * @internal\n */\nexport function isTaggedTelemetryPropertyValue(\n\tx: Tagged<TelemetryEventPropertyTypeExt> | TelemetryEventPropertyTypeExt,\n): x is Tagged<TelemetryEventPropertyTypeExt> {\n\treturn typeof (x as Partial<Tagged<unknown>>)?.tag === \"string\";\n}\n\n// TODO: Use `unknown` instead (API breaking change)\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * Borrowed from\n * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value#examples}\n * Avoids runtime errors with circular references.\n * Not ideal, as will cut values that are not necessarily circular references.\n * Could be improved by implementing Node's util.inspect() for browser (minus all the coloring code)\n *\n * @internal\n */\nexport const getCircularReplacer = (): ((key: string, value: unknown) => any) => {\n\tconst seen = new WeakSet();\n\treturn (key: string, value: unknown): any => {\n\t\tif (typeof value === \"object\" && value !== null) {\n\t\t\tif (seen.has(value)) {\n\t\t\t\treturn \"<removed/circular>\";\n\t\t\t}\n\t\t\tseen.add(value);\n\t\t}\n\t\treturn value;\n\t};\n};\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\n/**\n * Base class for \"trusted\" errors we create, whose properties can generally be logged to telemetry safely.\n * All properties set on the object, or passed in (via the constructor or addTelemetryProperties),\n * will be logged in accordance with their tag, if present.\n *\n * PLEASE take care to avoid setting sensitive data on this object without proper tagging!\n *\n * @internal\n */\nexport class LoggingError\n\textends Error\n\timplements ILoggingError, Omit<IFluidErrorBase, \"errorType\">\n{\n\tprivate _errorInstanceId = uuid();\n\tpublic get errorInstanceId(): string {\n\t\treturn this._errorInstanceId;\n\t}\n\tpublic overwriteErrorInstanceId(id: string): void {\n\t\tthis._errorInstanceId = id;\n\t}\n\n\t/**\n\t * Create a new LoggingError\n\t * @param message - Error message to use for Error base class\n\t * @param props - telemetry props to include on the error for when it's logged\n\t * @param omitPropsFromLogging - properties by name to omit from telemetry props\n\t */\n\tpublic constructor(\n\t\tmessage: string,\n\t\tprops?: ITelemetryBaseProperties,\n\t\tprivate readonly omitPropsFromLogging: Set<string> = new Set(),\n\t) {\n\t\tsuper(message);\n\n\t\t// Don't log this list itself, or the private _errorInstanceId\n\t\tomitPropsFromLogging.add(\"omitPropsFromLogging\");\n\t\tomitPropsFromLogging.add(\"_errorInstanceId\");\n\n\t\tif (props) {\n\t\t\tthis.addTelemetryProperties(props);\n\t\t}\n\t}\n\n\t/**\n\t * Determines if a given object is an instance of a LoggingError\n\t * @param object - any object\n\t * @returns true if the object is an instance of a LoggingError, false if not.\n\t */\n\tpublic static typeCheck(object: unknown): object is LoggingError {\n\t\tif (typeof object === \"object\" && object !== null) {\n\t\t\treturn (\n\t\t\t\ttypeof (object as LoggingError).addTelemetryProperties === \"function\" &&\n\t\t\t\ttypeof (object as LoggingError).getTelemetryProperties === \"function\" &&\n\t\t\t\ttypeof (object as LoggingError).errorInstanceId === \"string\"\n\t\t\t);\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Add additional properties to be logged\n\t */\n\tpublic addTelemetryProperties(props: ITelemetryPropertiesExt): void {\n\t\tcopyProps(this, props);\n\t}\n\n\t/**\n\t * Get all properties fit to be logged to telemetry for this error\n\t */\n\tpublic getTelemetryProperties(): ITelemetryBaseProperties {\n\t\t// Only pick properties fit for telemetry out of all of this object's enumerable properties.\n\t\tconst telemetryProps: ITelemetryBaseProperties = {};\n\t\tfor (const key of Object.keys(this)) {\n\t\t\tif (this.omitPropsFromLogging.has(key)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst val = this[key] as\n\t\t\t\t| TelemetryEventPropertyTypeExt\n\t\t\t\t| Tagged<TelemetryEventPropertyTypeExt>;\n\n\t\t\t// Ensure only valid props get logged, since props of logging error could be in any shape\n\t\t\ttelemetryProps[key] = convertToBasePropertyType(val);\n\t\t}\n\t\t// Ensure a few extra props always exist\n\t\treturn {\n\t\t\t...telemetryProps,\n\t\t\tstack: this.stack,\n\t\t\tmessage: this.message,\n\t\t\terrorInstanceId: this._errorInstanceId,\n\t\t};\n\t}\n}\n\n/**\n * The Error class used when normalizing an external error\n *\n * @internal\n */\nexport const NORMALIZED_ERROR_TYPE = \"genericError\";\n\n/**\n * Subclass of LoggingError returned by normalizeError\n *\n * @internal\n */\nclass NormalizedLoggingError extends LoggingError {\n\t// errorType \"genericError\" is used as a default value throughout the code.\n\t// Note that this matches ContainerErrorTypes/DriverErrorTypes' genericError\n\tpublic readonly errorType = NORMALIZED_ERROR_TYPE;\n\n\tpublic constructor(errorProps: Pick<IFluidErrorBase, \"message\" | \"stack\">) {\n\t\tsuper(errorProps.message);\n\n\t\tif (errorProps.stack !== undefined) {\n\t\t\toverwriteStack(this, errorProps.stack);\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"errorLogging.js","sourceRoot":"","sources":["../src/errorLogging.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 type { ITelemetryBaseProperties, Tagged } from \"@fluidframework/core-interfaces\";\nimport type { ILoggingError } from \"@fluidframework/core-interfaces/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { type IFluidErrorBase, hasErrorInstanceId, isFluidError } from \"./fluidErrorBase.js\";\nimport { convertToBasePropertyType } from \"./logger.js\";\nimport type {\n\tITelemetryLoggerExt,\n\tITelemetryPropertiesExt,\n\tTelemetryEventPropertyTypeExt,\n} from \"./telemetryTypes.js\";\n\n/**\n * Determines if the provided value is an object but neither null nor an array.\n */\nconst isRegularObject = (value: unknown): boolean => {\n\treturn value !== null && !Array.isArray(value) && typeof value === \"object\";\n};\n\n/**\n * Inspect the given error for common \"safe\" props and return them.\n *\n * @internal\n */\nexport function extractLogSafeErrorProperties(\n\terror: unknown,\n\tsanitizeStack: boolean,\n): {\n\tmessage: string;\n\terrorType?: string | undefined;\n\tstack?: string | undefined;\n} {\n\tconst removeMessageFromStack = (stack: string, errorName?: string): string => {\n\t\tif (!sanitizeStack) {\n\t\t\treturn stack;\n\t\t}\n\t\tconst stackFrames = stack.split(\"\\n\");\n\t\tstackFrames.shift(); // Remove \"[ErrorName]: [ErrorMessage]\"\n\t\tif (errorName !== undefined) {\n\t\t\tstackFrames.unshift(errorName); // Add \"[ErrorName]\"\n\t\t}\n\t\treturn stackFrames.join(\"\\n\");\n\t};\n\n\tconst message =\n\t\ttypeof (error as Partial<Error>)?.message === \"string\"\n\t\t\t? (error as Error).message\n\t\t\t: String(error);\n\n\tconst safeProps: { message: string; errorType?: string; stack?: string } = {\n\t\tmessage,\n\t};\n\n\tif (isRegularObject(error)) {\n\t\tconst { errorType, stack, name } = error as Partial<IFluidErrorBase>;\n\n\t\tif (typeof errorType === \"string\") {\n\t\t\tsafeProps.errorType = errorType;\n\t\t}\n\n\t\tif (typeof stack === \"string\") {\n\t\t\tconst errorName = typeof name === \"string\" ? name : undefined;\n\t\t\tsafeProps.stack = removeMessageFromStack(stack, errorName);\n\t\t}\n\t}\n\n\treturn safeProps;\n}\n\n/**\n * Type-guard for {@link @fluidframework/core-interfaces#ILoggingError}.\n *\n * @internal\n */\nexport const isILoggingError = (x: unknown): x is ILoggingError =>\n\ttypeof (x as Partial<ILoggingError>)?.getTelemetryProperties === \"function\";\n\n/**\n * Copy props from source onto target, but do not overwrite an existing prop that matches\n */\nfunction copyProps(\n\ttarget: ITelemetryPropertiesExt | LoggingError,\n\tsource: ITelemetryPropertiesExt,\n): void {\n\tfor (const [key, value] of Object.entries(source)) {\n\t\tif (target[key] === undefined) {\n\t\t\ttarget[key] = value;\n\t\t}\n\t}\n}\n\n/**\n * Metadata to annotate an error object when annotating or normalizing it\n *\n * @internal\n */\nexport interface IFluidErrorAnnotations {\n\t/**\n\t * Telemetry props to log with the error\n\t */\n\tprops?: ITelemetryBaseProperties;\n}\n\n/**\n * Normalize the given error yielding a valid Fluid Error\n * @returns A valid Fluid Error with any provided annotations applied\n * @param error - The error to normalize\n * @param annotations - Annotations to apply to the normalized error\n *\n * @internal\n */\nexport function normalizeError(\n\terror: unknown,\n\tannotations: IFluidErrorAnnotations = {},\n): IFluidErrorBase {\n\tif (isFluidError(error)) {\n\t\t// We can simply add the telemetry props to the error and return it\n\t\terror.addTelemetryProperties(annotations.props ?? {});\n\t\treturn error;\n\t}\n\n\t// We have to construct a new Fluid Error, copying safe properties over\n\tconst { message, stack } = extractLogSafeErrorProperties(error, false /* sanitizeStack */);\n\tconst fluidError: IFluidErrorBase = new NormalizedLoggingError({\n\t\tmessage,\n\t\tstack,\n\t});\n\n\t// We need to preserve these properties which are used in a non-typesafe way throughout driver code (see #8743)\n\t// Anywhere they are set should be on a valid Fluid Error that would have been returned above,\n\t// but we can't prove it with the types, so adding this defensive measure.\n\tif (typeof error === \"object\" && error !== null) {\n\t\tconst maybeHasRetry: Partial<Record<\"canRetry\" | \"retryAfterSeconds\", unknown>> = error;\n\t\tlet retryProps: Partial<Record<\"canRetry\" | \"retryAfterSeconds\", unknown>> | undefined;\n\t\tif (\"canRetry\" in error) {\n\t\t\tretryProps ??= {};\n\t\t\tretryProps.canRetry = maybeHasRetry.canRetry;\n\t\t}\n\t\tif (\"retryAfterSeconds\" in error) {\n\t\t\tretryProps ??= {};\n\t\t\tretryProps.retryAfterSeconds = maybeHasRetry.retryAfterSeconds;\n\t\t}\n\t\tif (retryProps !== undefined) {\n\t\t\tObject.assign(fluidError, retryProps);\n\t\t}\n\t}\n\n\tif (typeof error !== \"object\") {\n\t\t// This is only interesting for non-objects\n\t\tfluidError.addTelemetryProperties({ typeofError: typeof error });\n\t}\n\n\tconst errorTelemetryProps = LoggingError.typeCheck(error)\n\t\t? error.getTelemetryProperties()\n\t\t: {\n\t\t\t\tuntrustedOrigin: 1, // This will let us filter errors that did not originate from our own codebase\n\t\t\t\t// FUTURE: Once 2.0 becomes LTS, switch to this more explicit property name\n\t\t\t\t// Consider using a string to distinguish cases like \"dependency\" v. \"callback\"\n\t\t\t\t// errorRunningExternalCode: 1,\n\t\t\t};\n\n\tfluidError.addTelemetryProperties({\n\t\t...errorTelemetryProps,\n\t\t...annotations.props,\n\t});\n\n\treturn fluidError;\n}\n\nlet stackPopulatedOnCreation: boolean | undefined;\n\n/**\n * The purpose of this function is to provide ability to capture stack context quickly.\n * Accessing new Error().stack is slow, and the slowest part is accessing stack property itself.\n * There are scenarios where we generate error with stack, but error is handled in most cases and\n * stack property is not accessed.\n * For such cases it's better to not read stack property right away, but rather delay it until / if it's needed\n * Some browsers will populate stack right away, others require throwing Error, so we do auto-detection on the fly.\n * @param stackTraceLimit - stack trace limit for an error\n * @returns Error object that has stack populated.\n *\n * @internal\n */\nexport function generateErrorWithStack(stackTraceLimit?: number): Error {\n\tconst ErrorConfig = Error as unknown as { stackTraceLimit: number };\n\tconst originalStackTraceLimit = ErrorConfig.stackTraceLimit;\n\tif (stackTraceLimit !== undefined) {\n\t\tErrorConfig.stackTraceLimit = stackTraceLimit;\n\t}\n\tconst err = new Error(\"<<generated stack>>\");\n\n\tif (stackPopulatedOnCreation === undefined) {\n\t\tstackPopulatedOnCreation = err.stack !== undefined;\n\t}\n\n\tif (stackPopulatedOnCreation) {\n\t\tErrorConfig.stackTraceLimit = originalStackTraceLimit;\n\t\treturn err;\n\t}\n\n\ttry {\n\t\tthrow err;\n\t} catch (error) {\n\t\tErrorConfig.stackTraceLimit = originalStackTraceLimit;\n\t\treturn error as Error;\n\t}\n}\n\n/**\n * Generate a stack at this callsite as if an error were thrown from here.\n * @param stackTraceLimit - stack trace limit for an error\n * @returns the callstack (does not throw)\n *\n * @internal\n */\nexport function generateStack(stackTraceLimit?: number): string | undefined {\n\treturn generateErrorWithStack(stackTraceLimit).stack;\n}\n\n/**\n * Create a new error using newErrorFn, wrapping and caused by the given unknown error.\n * Copies the inner error's stack, errorInstanceId and telemetry props over to the new error if present\n * @param innerError - An error from untrusted/unknown origins\n * @param newErrorFn - callback that will create a new error given the original error's message\n * @returns A new error object \"wrapping\" the given error\n *\n * @internal\n */\nexport function wrapError<T extends LoggingError>(\n\tinnerError: unknown,\n\tnewErrorFn: (message: string) => T,\n): T {\n\tconst { message, stack } = extractLogSafeErrorProperties(\n\t\tinnerError,\n\t\tfalse /* sanitizeStack */,\n\t);\n\n\tconst newError = newErrorFn(message);\n\n\tif (stack !== undefined) {\n\t\toverwriteStack(newError, stack);\n\t}\n\n\t// Mark external errors with untrustedOrigin flag\n\tif (isExternalError(innerError)) {\n\t\tnewError.addTelemetryProperties({\n\t\t\tuntrustedOrigin: 1,\n\t\t\t// FUTURE: Once 2.0 becomes LTS, switch to this more explicit property name\n\t\t\t// Consider using a string to distinguish cases like \"dependency\" v. \"callback\"\n\t\t\t// errorRunningExternalCode: 1,\n\t\t});\n\t}\n\n\t// Reuse errorInstanceId\n\tif (hasErrorInstanceId(innerError)) {\n\t\tnewError.overwriteErrorInstanceId(innerError.errorInstanceId);\n\n\t\t// For \"back-compat\" in the logs\n\t\tnewError.addTelemetryProperties({ innerErrorInstanceId: innerError.errorInstanceId });\n\t}\n\n\t// Lastly, copy over all other telemetry properties. Note these will not overwrite existing properties\n\t// This will include the untrustedOrigin/errorRunningExternalCode info if the inner error itself was created from an external error\n\tif (isILoggingError(innerError)) {\n\t\tnewError.addTelemetryProperties(innerError.getTelemetryProperties());\n\t}\n\n\treturn newError;\n}\n\n/**\n * The same as wrapError, but also logs the innerError, including the wrapping error's instance ID.\n *\n * @typeParam T - The kind of wrapper error to create.\n *\n * @internal\n */\nexport function wrapErrorAndLog<T extends LoggingError>(\n\tinnerError: unknown,\n\tnewErrorFn: (message: string) => T,\n\tlogger: ITelemetryLoggerExt,\n): T {\n\tconst newError = wrapError(innerError, newErrorFn);\n\n\t// This will match innerError.errorInstanceId if present (see wrapError)\n\tconst errorInstanceId = newError.errorInstanceId;\n\n\t// For \"back-compat\" in the logs\n\tconst wrappedByErrorInstanceId = errorInstanceId;\n\n\tlogger.sendTelemetryEvent(\n\t\t{\n\t\t\teventName: \"WrapError\",\n\t\t\terrorInstanceId,\n\t\t\twrappedByErrorInstanceId,\n\t\t},\n\t\tinnerError,\n\t);\n\n\treturn newError;\n}\n\n/**\n * Attempts to overwrite the error's stack\n *\n * There have been reports of certain JS environments where overwriting stack will throw.\n * If that happens, this adds the given stack as the telemetry property \"stack2\"\n *\n * @internal\n */\nexport function overwriteStack(error: IFluidErrorBase | LoggingError, stack: string): void {\n\ttry {\n\t\tObject.assign(error, { stack });\n\t} catch {\n\t\terror.addTelemetryProperties({ stack2: stack });\n\t}\n}\n\n/**\n * True for any error object that is an (optionally normalized) external error\n * False for any error we created and raised within the FF codebase via LoggingError base class,\n * or wrapped in a well-known error type\n *\n * @internal\n */\nexport function isExternalError(error: unknown): boolean {\n\t// LoggingErrors are an internal FF error type. However, an external error can be converted\n\t// into a LoggingError if it is normalized. In this case we must use the untrustedOrigin/errorRunningExternalCode flag to\n\t// determine whether the original error was in fact external.\n\tif (LoggingError.typeCheck(error)) {\n\t\tif ((error as NormalizedLoggingError).errorType === NORMALIZED_ERROR_TYPE) {\n\t\t\tconst props = error.getTelemetryProperties();\n\t\t\t// NOTE: errorRunningExternalCode is not currently used - once this \"read\" code reaches LTS,\n\t\t\t// we can switch to writing this more explicit property\n\t\t\treturn props.untrustedOrigin === 1 || Boolean(props.errorRunningExternalCode);\n\t\t}\n\t\treturn false;\n\t}\n\treturn true;\n}\n\n/**\n * Type guard to identify if a particular telemetry property appears to be a\n * {@link @fluidframework/core-interfaces#Tagged} telemetry property.\n *\n * @internal\n */\nexport function isTaggedTelemetryPropertyValue(\n\tx: Tagged<TelemetryEventPropertyTypeExt> | TelemetryEventPropertyTypeExt,\n): x is Tagged<TelemetryEventPropertyTypeExt> {\n\treturn typeof (x as Partial<Tagged<unknown>>)?.tag === \"string\";\n}\n\n// TODO: Use `unknown` instead (API breaking change)\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * Borrowed from\n * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value#examples}\n * Avoids runtime errors with circular references.\n * Not ideal, as will cut values that are not necessarily circular references.\n * Could be improved by implementing Node's util.inspect() for browser (minus all the coloring code)\n *\n * @internal\n */\nexport const getCircularReplacer = (): ((key: string, value: unknown) => any) => {\n\tconst seen = new WeakSet();\n\treturn (key: string, value: unknown): any => {\n\t\tif (typeof value === \"object\" && value !== null) {\n\t\t\tif (seen.has(value)) {\n\t\t\t\treturn \"<removed/circular>\";\n\t\t\t}\n\t\t\tseen.add(value);\n\t\t}\n\t\treturn value;\n\t};\n};\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\n/**\n * Base class for \"trusted\" errors we create, whose properties can generally be logged to telemetry safely.\n * All properties set on the object, or passed in (via the constructor or addTelemetryProperties),\n * will be logged in accordance with their tag, if present.\n *\n * PLEASE take care to avoid setting sensitive data on this object without proper tagging!\n *\n * @internal\n */\nexport class LoggingError\n\textends Error\n\timplements ILoggingError, Omit<IFluidErrorBase, \"errorType\">\n{\n\tprivate _errorInstanceId = uuid();\n\tpublic get errorInstanceId(): string {\n\t\treturn this._errorInstanceId;\n\t}\n\tpublic overwriteErrorInstanceId(id: string): void {\n\t\tthis._errorInstanceId = id;\n\t}\n\n\t/**\n\t * Create a new LoggingError\n\t * @param message - Error message to use for Error base class\n\t * @param props - telemetry props to include on the error for when it's logged\n\t * @param omitPropsFromLogging - properties by name to omit from telemetry props\n\t */\n\tpublic constructor(\n\t\tmessage: string,\n\t\tprops?: ITelemetryBaseProperties,\n\t\tprivate readonly omitPropsFromLogging: Set<string> = new Set(),\n\t) {\n\t\tsuper(message);\n\n\t\t// Don't log this list itself, or the private _errorInstanceId\n\t\tomitPropsFromLogging.add(\"omitPropsFromLogging\");\n\t\tomitPropsFromLogging.add(\"_errorInstanceId\");\n\n\t\tif (props) {\n\t\t\tthis.addTelemetryProperties(props);\n\t\t}\n\t}\n\n\t/**\n\t * Determines if a given object is an instance of a LoggingError\n\t * @param object - any object\n\t * @returns true if the object is an instance of a LoggingError, false if not.\n\t */\n\tpublic static typeCheck(object: unknown): object is LoggingError {\n\t\tif (typeof object === \"object\" && object !== null) {\n\t\t\treturn (\n\t\t\t\ttypeof (object as LoggingError).addTelemetryProperties === \"function\" &&\n\t\t\t\ttypeof (object as LoggingError).getTelemetryProperties === \"function\" &&\n\t\t\t\ttypeof (object as LoggingError).errorInstanceId === \"string\"\n\t\t\t);\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Add additional properties to be logged\n\t */\n\tpublic addTelemetryProperties(props: ITelemetryPropertiesExt): void {\n\t\tcopyProps(this, props);\n\t}\n\n\t/**\n\t * Get all properties fit to be logged to telemetry for this error\n\t */\n\tpublic getTelemetryProperties(): ITelemetryBaseProperties {\n\t\t// Only pick properties fit for telemetry out of all of this object's enumerable properties.\n\t\tconst telemetryProps: ITelemetryBaseProperties = {};\n\t\tfor (const key of Object.keys(this)) {\n\t\t\tif (this.omitPropsFromLogging.has(key)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst val = this[key] as\n\t\t\t\t| TelemetryEventPropertyTypeExt\n\t\t\t\t| Tagged<TelemetryEventPropertyTypeExt>;\n\n\t\t\t// Ensure only valid props get logged, since props of logging error could be in any shape\n\t\t\ttelemetryProps[key] = convertToBasePropertyType(val);\n\t\t}\n\t\t// Ensure a few extra props always exist\n\t\treturn {\n\t\t\t...telemetryProps,\n\t\t\tstack: this.stack,\n\t\t\tmessage: this.message,\n\t\t\terrorInstanceId: this._errorInstanceId,\n\t\t};\n\t}\n}\n\n/**\n * The Error class used when normalizing an external error\n *\n * @internal\n */\nexport const NORMALIZED_ERROR_TYPE = \"genericError\";\n\n/**\n * Subclass of LoggingError returned by normalizeError\n *\n * @internal\n */\nclass NormalizedLoggingError extends LoggingError {\n\t// errorType \"genericError\" is used as a default value throughout the code.\n\t// Note that this matches ContainerErrorTypes/DriverErrorTypes' genericError\n\tpublic readonly errorType = NORMALIZED_ERROR_TYPE;\n\n\tpublic constructor(errorProps: Pick<IFluidErrorBase, \"message\" | \"stack\">) {\n\t\tsuper(errorProps.message);\n\n\t\tif (errorProps.stack !== undefined) {\n\t\t\toverwriteStack(this, errorProps.stack);\n\t\t}\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACN,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,QAAQ,EACR,KAAK,MAAM,EACX,KAAK,8BAA8B,EACnC,MAAM,iCAAiC,CAAC;AAazC,OAAO,KAAK,EACX,uBAAuB,EAEvB,yBAAyB,EACzB,mBAAmB,EACnB,6BAA6B,EAC7B,uBAAuB,EACvB,sBAAsB,EACtB,6BAA6B,EAC7B,MAAM,qBAAqB,CAAC;AAE7B;;;;;;GAMG;AACH,oBAAY,gBAAgB;IAC3B;;OAEG;IACH,YAAY,iBAAiB;IAC7B;;OAEG;IACH,QAAQ,aAAa;CACrB;AAED;;;GAGG;AACH,MAAM,MAAM,2BAA2B,GAAG,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAE1E;;;GAGG;AACH,MAAM,MAAM,2BAA2B,GAAG,MAAM,CAC/C,MAAM,EACN,2BAA2B,GAAG,CAAC,MAAM,2BAA2B,CAAC,CACjE,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,4BAA4B;IAC5C,GAAG,CAAC,EAAE,2BAA2B,CAAC;IAClC,KAAK,CAAC,EAAE,2BAA2B,CAAC;CACpC;AAED;;;;;;;;;GASG;AAEH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAM5F;AAID;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;GAGG;AACH,eAAO,MAAM,uBAAuB,KAAe,CAAC;AAEpD;;;;GAIG;AACH,8BAAsB,eAAgB,YAAW,mBAAmB;IAkDlE,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;IAC7B,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC;IAlD/B;;OAEG;IACH,gBAAuB,uBAAuB,MAA2B;WAE3D,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAInD;;;;;;OAMG;WACW,kBAAkB,CAC/B,KAAK,EAAE,mBAAmB,EAC1B,KAAK,EAAE,OAAO,EACd,UAAU,EAAE,OAAO,GACjB,IAAI;gBA6Ba,SAAS,CAAC,oBAAQ,EAClB,UAAU,CAAC,0CAA8B;IAG7D;;;;OAIG;aACa,IAAI,CAAC,KAAK,EAAE,mBAAmB,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI;IAE3E;;;;;;;OAOG;IACI,kBAAkB,CACxB,KAAK,EAAE,yBAAyB,EAChC,KAAK,CAAC,EAAE,OAAO,EACf,QAAQ,GAAE,OAAO,QAAQ,CAAC,OAAO,GAAG,OAAO,QAAQ,CAAC,OAA0B,GAC5E,IAAI;IAQP;;;;;;OAMG;IACH,SAAS,CAAC,sBAAsB,CAC/B,KAAK,EAAE,yBAAyB,GAAG;QAAE,QAAQ,EAAE,sBAAsB,CAAA;KAAE,EACvE,KAAK,CAAC,EAAE,OAAO,EACf,QAAQ,CAAC,EAAE,QAAQ,GACjB,IAAI;IAcP;;;;;OAKG;IACI,cAAc,CAAC,KAAK,EAAE,uBAAuB,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI;IAc5E;;;;;;;OAOG;IACI,oBAAoB,CAC1B,KAAK,EAAE,6BAA6B,EACpC,KAAK,CAAC,EAAE,OAAO,EACf,QAAQ,GAAE,OAAO,QAAQ,CAAC,OAAO,GAAG,OAAO,QAAQ,CAAC,OAA0B,GAC5E,IAAI;IAaP,SAAS,CAAC,YAAY,CAAC,KAAK,EAAE,mBAAmB,GAAG,mBAAmB;IAWvE,OAAO,CAAC,gBAAgB;CA4BxB;AAED;;;;;;GAMG;AACH,qBAAa,mBAAoB,YAAW,oBAAoB;IAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,oBAAoB;IAEhE;;OAEG;IACI,IAAI,CAAC,kBAAkB,EAAE,mBAAmB,GAAG,IAAI;CAuC1D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,CAAC,EAAE;IACzC,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,4BAA4B,CAAC;CAC1C,GAAG,mBAAmB,CAEtB;AAED;;;;GAIG;AACH,qBAAa,WAAY,SAAQ,eAAe;IAyD9C,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,oBAAoB;IAxDpD;;;;;;OAMG;WACW,MAAM,CACnB,UAAU,CAAC,EAAE,oBAAoB,EACjC,SAAS,CAAC,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,4BAA4B,GACvC,eAAe;IA4ClB,OAAO;IAaP,IAAW,WAAW,IAAI,QAAQ,GAAG,SAAS,CAE7C;IAED,OAAO,CAAC,oBAAoB;IAO5B;;;;OAIG;IACI,IAAI,CAAC,KAAK,EAAE,mBAAmB,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI;CAMlE;AAED;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACzC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,UAAU,CAAC,EAAE,4BAA4B,CAAC;IAE1C;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,oBAAoB,GAAG,SAAS,CAAC,EAAE,CAAC;IAE/C;;OAEG;IACH,oBAAoB,CAAC,EAAE,IAAI,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,yBAAyB,GAAG,mBAAmB,CAO3F;AAED;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,eAAe;IACnD,SAAS,CAAC,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAE1C,OAAO,CAAC,wBAAwB,CAAW;IAE3C;;;;;;OAMG;gBAEF,SAAS,CAAC,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,4BAA4B,EACzC,OAAO,GAAE,oBAAoB,EAAO,EACpC,oBAAoB,CAAC,EAAE,IAAI;IAwB5B,IAAW,WAAW,IAAI,QAAQ,CAEjC;IAED,OAAO,CAAC,oBAAoB;IAU5B;;;OAGG;IACI,SAAS,CAAC,MAAM,CAAC,EAAE,oBAAoB,GAAG,IAAI;IAQrD;;;;OAIG;IACI,IAAI,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;CAM7C;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,wBAAwB;IACxC,KAAK,CAAC,EAAE,IAAI,CAAC;IACb,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,MAAM,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;CAC7B;AAED;;;;GAIG;AACH,qBAAa,gBAAgB;IA0G3B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAEvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IA5G1B;;;;;;;;;OASG;WACW,KAAK,CAClB,MAAM,EAAE,mBAAmB,EAC3B,KAAK,EAAE,yBAAyB,EAChC,OAAO,CAAC,EAAE,wBAAwB,EAClC,QAAQ,GAAE,OAAc,GACtB,gBAAgB;IAInB;;;;;;;;;;;;;;OAcG;WACW,SAAS,CAAC,CAAC,EACxB,MAAM,EAAE,mBAAmB,EAC3B,KAAK,EAAE,yBAAyB,EAChC,QAAQ,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,CAAC,EACxC,OAAO,CAAC,EAAE,wBAAwB,EAClC,eAAe,GAAE,MAAU,GACzB,CAAC;IAiBJ;;;;;;;;;;;;;;;OAeG;WACiB,cAAc,CAAC,CAAC,EACnC,MAAM,EAAE,mBAAmB,EAC3B,KAAK,EAAE,yBAAyB,EAChC,QAAQ,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,OAAO,CAAC,CAAC,CAAC,EACjD,OAAO,CAAC,EAAE,wBAAwB,EAClC,eAAe,GAAE,MAAU,GACzB,OAAO,CAAC,CAAC,CAAC;IAiBb,IAAW,QAAQ,IAAI,MAAM,CAE5B;IAED,OAAO,CAAC,KAAK,CAAC,CAA4B;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;IAC/C,OAAO,CAAC,SAAS,CAAC,CAAS;IAE3B,SAAS,aACS,MAAM,EAAE,mBAAmB,EAC5C,KAAK,EAAE,yBAAyB,EACf,OAAO,GAAE,wBAA2D,EACpE,QAAQ,GAAE,OAAc;IAiBnC,cAAc,CACpB,KAAK,CAAC,EAAE,uBAAuB,EAC/B,eAAe,GAAE,MAAiB,GAChC,IAAI;IAIP,OAAO,CAAC,OAAO;IAWR,GAAG,CAAC,KAAK,CAAC,EAAE,uBAAuB,GAAG,IAAI;IAQjD,OAAO,CAAC,kBAAkB;IASnB,MAAM,CAAC,KAAK,CAAC,EAAE,uBAAuB,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI;IASrE;;OAEG;IACI,WAAW,CACjB,eAAe,EAAE,MAAM,EACvB,KAAK,CAAC,EAAE,uBAAuB,EAC/B,KAAK,CAAC,EAAE,OAAO,GACb,IAAI;IAoBP,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAA6B;IAC9D,OAAO,CAAC,MAAM,CAAC,YAAY;CAS3B;AAmBD;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACxC,CAAC,EAAE,6BAA6B,GAAG,MAAM,CAAC,6BAA6B,CAAC,GACtE,8BAA8B,GAAG,MAAM,CAAC,8BAA8B,CAAC,CAOzE;AA0BD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,OAAO,gGAIsB,8BAA8B,SAGlE,CAAC,UACE,CAAC,2CAGc,8BAA8B;;SAG3C,CAAC;;;SAID,CAAC;oDAoB0B,CAAC;AAEvC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,gBAAgB,oEAGa,8BAA8B,YAG/D,CAAC,2CAGc,8BAA8B;;SAG3C,iBAAiB,YAAY;;;SAI7B,iBAAiB,YAAY;oDAG6C,CAAC"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
package/dist/logger.js CHANGED
@@ -372,7 +372,7 @@ class MultiSinkLogger extends TelemetryLogger {
372
372
  constructor(namespace, properties, loggers = [], tryInheritProperties) {
373
373
  let realProperties = properties === undefined ? undefined : { ...properties };
374
374
  if (tryInheritProperties === true) {
375
- const merge = (realProperties ?? (realProperties = {}));
375
+ const merge = (realProperties ??= {});
376
376
  loggers
377
377
  .filter((l) => l instanceof TelemetryLogger)
378
378
  .map((l) => l.properties ?? {})
@@ -501,13 +501,13 @@ class PerformanceEvent {
501
501
  }
502
502
  }
503
503
  get duration() {
504
- return client_utils_1.performance.now() - this.startTime;
504
+ return (0, client_utils_1.performanceNow)() - this.startTime;
505
505
  }
506
506
  constructor(logger, event, markers = { end: true, cancel: "generic" }, emitLogs = true) {
507
507
  this.logger = logger;
508
508
  this.markers = markers;
509
509
  this.emitLogs = emitLogs;
510
- this.startTime = client_utils_1.performance.now();
510
+ this.startTime = (0, client_utils_1.performanceNow)();
511
511
  this.event = { ...event };
512
512
  if (this.markers.start) {
513
513
  this.reportEvent("start");
@@ -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 { performance } from \"@fluid-internal/client-utils\";\nimport {\n\ttype ITelemetryBaseEvent,\n\ttype ITelemetryBaseLogger,\n\tLogLevel,\n\ttype Tagged,\n\ttype TelemetryBaseEventPropertyType,\n} from \"@fluidframework/core-interfaces\";\n\nimport {\n\tCachedConfigProvider,\n\tloggerIsMonitoringContext,\n\tmixinMonitoringContext,\n} from \"./config.js\";\nimport {\n\textractLogSafeErrorProperties,\n\tgenerateStack,\n\tisILoggingError,\n\tisTaggedTelemetryPropertyValue,\n} from \"./errorLogging.js\";\nimport type {\n\tITelemetryErrorEventExt,\n\tITelemetryEventExt,\n\tITelemetryGenericEventExt,\n\tITelemetryLoggerExt,\n\tITelemetryPerformanceEventExt,\n\tITelemetryPropertiesExt,\n\tTelemetryEventCategory,\n\tTelemetryEventPropertyTypeExt,\n} from \"./telemetryTypes.js\";\n\n/**\n * Broad classifications to be applied to individual properties as they're prepared to be logged to telemetry.\n *\n * @privateRemarks Please do not modify existing entries, to maintain backwards compatibility.\n *\n * @internal\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\n/**\n * @legacy\n * @alpha\n */\nexport type TelemetryEventPropertyTypes = ITelemetryPropertiesExt[string];\n\n/**\n * @legacy\n * @alpha\n */\nexport type ITelemetryLoggerPropertyBag = Record<\n\tstring,\n\tTelemetryEventPropertyTypes | (() => TelemetryEventPropertyTypes)\n>;\n\n/**\n * @legacy\n * @alpha\n */\nexport interface ITelemetryLoggerPropertyBags {\n\tall?: ITelemetryLoggerPropertyBag;\n\terror?: ITelemetryLoggerPropertyBag;\n}\n\n/**\n * Attempts to parse number from string.\n * If it fails, it will return the original string.\n *\n * @remarks\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 * @internal\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\n// TODO: add docs\n// eslint-disable-next-line jsdoc/require-description\n/**\n * @internal\n */\nexport function formatTick(tick: number): number {\n\treturn Math.floor(tick);\n}\n\n/**\n * String used to concatenate the namespace of parent loggers and their child loggers.\n * @internal\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\t/**\n\t * {@inheritDoc eventNamespaceSeparator}\n\t */\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: ITelemetryErrorEventExt, 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<\n\t\tT extends ITelemetryLoggerPropertyBag = ITelemetryLoggerPropertyBag,\n\t>(toExtend: T, includeErrorProps: boolean): 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, getterOrValue] of Object.entries(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\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 *\n * @internal\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, taggableProp] of Object.entries(eventWithTagsMaybe)) {\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\t}\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\t}\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\t}\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\t}\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 *\n * @remarks\n * Passing in no props object (i.e. undefined) will return a logger that is effectively a no-op.\n *\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 * @legacy\n * @alpha\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\t? baseLogger.namespace\n\t\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(baseLogger ?? { send(): void {} }, namespace, properties);\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 * Input properties for {@link createMultiSinkLogger}.\n *\n * @internal\n */\nexport interface MultiSinkLoggerProperties {\n\t/**\n\t * Will be prefixed to all event names.\n\t */\n\tnamespace?: string;\n\n\t/**\n\t * Default properties that will be applied to all events flowing through this logger.\n\t */\n\tproperties?: ITelemetryLoggerPropertyBags;\n\n\t/**\n\t * The base loggers that this logger will forward the logs to, after it processes them.\n\t */\n\tloggers?: (ITelemetryBaseLogger | undefined)[];\n\n\t/**\n\t * If true, the logger will attempt to copy the custom properties (if they are of a known type, i.e. one from this package) of all the base loggers passed to it, to apply them itself to logs that flow through.\n\t */\n\ttryInheritProperties?: true;\n}\n\n/**\n * Create a logger which logs to multiple other loggers based on the provided props object.\n *\n * @internal\n */\nexport function createMultiSinkLogger(props: MultiSinkLoggerProperties): 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\tpublic constructor(\n\t\tnamespace?: string,\n\t\tproperties?: ITelemetryLoggerPropertyBags,\n\t\tloggers: ITelemetryBaseLogger[] = [],\n\t\ttryInheritProperties?: true,\n\t) {\n\t\tlet realProperties = properties === undefined ? undefined : { ...properties };\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 {@link PerformanceEvent} should log.\n *\n * @remarks\n * By default, all events are logged, but the client can override this behavior.\n *\n * For example, there is rarely a need to record a start event, as we're really after\n * success / failure tracking, including duration (on success).\n *\n * @internal\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 *\n * @internal\n */\nexport class PerformanceEvent {\n\t/**\n\t * Creates an instance of {@link PerformanceEvent} and starts measurements\n\t * @param logger - the logger to be used for publishing events\n\t * @param event - the logging event details which will be published with the performance measurements\n\t * @param markers - See {@link IPerformanceEventMarkers}\n\t * @param recordHeapSize - whether or not to also record memory performance\n\t * @param emitLogs - should this instance emit logs. If set to false, logs will not be emitted to the logger,\n\t * but measurements will still be performed and any specified markers will be generated.\n\t * @returns An instance of {@link PerformanceEvent}\n\t */\n\tpublic static start(\n\t\tlogger: ITelemetryLoggerExt,\n\t\tevent: ITelemetryGenericEventExt,\n\t\tmarkers?: IPerformanceEventMarkers,\n\t\temitLogs: boolean = true,\n\t): PerformanceEvent {\n\t\treturn new PerformanceEvent(logger, event, markers, emitLogs);\n\t}\n\n\t/**\n\t * Measure a synchronous task\n\t * @param logger - the logger to be used for publishing events\n\t * @param event - the logging event details which will be published with the performance measurements\n\t * @param callback - the task to be executed and measured\n\t * @param markers - See {@link IPerformanceEventMarkers}\n\t * @param sampleThreshold - events with the same name and category will be sent to the logger\n\t * only when we hit this many executions of the task. If unspecified, all events will be sent.\n\t * @returns The results of the executed task\n\t *\n\t * @remarks Note that if the \"same\" event (category + eventName) would be emitted by different\n\t * tasks (`callback`), `sampleThreshold` is still applied only based on the event's category + eventName,\n\t * so executing either of the tasks will increase the internal counter and they\n\t * effectively \"share\" the sampling rate for the event.\n\t */\n\tpublic static timedExec<T>(\n\t\tlogger: ITelemetryLoggerExt,\n\t\tevent: ITelemetryGenericEventExt,\n\t\tcallback: (event: PerformanceEvent) => T,\n\t\tmarkers?: IPerformanceEventMarkers,\n\t\tsampleThreshold: number = 1,\n\t): T {\n\t\tconst perfEvent = PerformanceEvent.start(\n\t\t\tlogger,\n\t\t\tevent,\n\t\t\tmarkers,\n\t\t\tPerformanceEvent.shouldReport(event, sampleThreshold),\n\t\t);\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\t/**\n\t * Measure an asynchronous task\n\t * @param logger - the logger to be used for publishing events\n\t * @param event - the logging event details which will be published with the performance measurements\n\t * @param callback - the task to be executed and measured\n\t * @param markers - See {@link IPerformanceEventMarkers}\n\t * @param recordHeapSize - whether or not to also record memory performance\n\t * @param sampleThreshold - events with the same name and category will be sent to the logger\n\t * only when we hit this many executions of the task. If unspecified, all events will be sent.\n\t * @returns The results of the executed task\n\t *\n\t * @remarks Note that if the \"same\" event (category + eventName) would be emitted by different\n\t * tasks (`callback`), `sampleThreshold` is still applied only based on the event's category + eventName,\n\t * so executing either of the tasks will increase the internal counter and they\n\t * effectively \"share\" the sampling rate for the event.\n\t */\n\tpublic static async timedExecAsync<T>(\n\t\tlogger: ITelemetryLoggerExt,\n\t\tevent: ITelemetryGenericEventExt,\n\t\tcallback: (event: PerformanceEvent) => Promise<T>,\n\t\tmarkers?: IPerformanceEventMarkers,\n\t\tsampleThreshold: number = 1,\n\t): Promise<T> {\n\t\tconst perfEvent = PerformanceEvent.start(\n\t\t\tlogger,\n\t\t\tevent,\n\t\t\tmarkers,\n\t\t\tPerformanceEvent.shouldReport(event, sampleThreshold),\n\t\t);\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?: ITelemetryGenericEventExt;\n\tprivate readonly startTime = performance.now();\n\tprivate startMark?: string;\n\n\tprotected constructor(\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t\tevent: ITelemetryGenericEventExt,\n\t\tprivate readonly markers: IPerformanceEventMarkers = { end: true, cancel: \"generic\" },\n\t\tprivate readonly emitLogs: boolean = true,\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 (\n\t\t\ttypeof window === \"object\" &&\n\t\t\twindow?.performance?.mark !== undefined &&\n\t\t\twindow?.performance?.mark !== null\n\t\t) {\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(\n\t\tprops?: ITelemetryPropertiesExt,\n\t\teventNameSuffix: string = \"update\",\n\t): 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\n\t\t// To prevent the event from being reported again later\n\t\tthis.event = undefined;\n\t}\n\n\tpublic end(props?: ITelemetryPropertiesExt): void {\n\t\tthis.reportEvent(\"end\", props);\n\t\tthis.performanceEndMark();\n\n\t\t// To prevent the event from being reported again later\n\t\tthis.event = undefined;\n\t}\n\n\tprivate performanceEndMark(): void {\n\t\tif (this.startMark !== undefined && 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?: ITelemetryPropertiesExt, 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\n\t\t// To prevent the event from being reported again later\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?: ITelemetryPropertiesExt,\n\t\terror?: unknown,\n\t): void {\n\t\t// If the caller invokes cancel or end directly inside the callback for timedExec[Async],\n\t\t// then it's possible to come back through reportEvent twice. Only the first time counts.\n\t\tif (!this.event) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.emitLogs) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst event: ITelemetryPerformanceEventExt = { ...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}\n\n\t\tthis.logger.sendPerformanceEvent(event, error);\n\t}\n\n\tprivate static readonly eventHits = new Map<string, number>();\n\tprivate static shouldReport(\n\t\tevent: ITelemetryGenericEventExt,\n\t\tsampleThreshold: number,\n\t): boolean {\n\t\tconst eventKey = `.${event.category}.${event.eventName}`;\n\t\tconst hitCount = PerformanceEvent.eventHits.get(eventKey) ?? 0;\n\t\tPerformanceEvent.eventHits.set(eventKey, hitCount >= sampleThreshold ? 1 : hitCount + 1);\n\t\treturn hitCount % sampleThreshold === 0;\n\t}\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<TelemetryBaseEventPropertyType> - 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): TelemetryBaseEventPropertyType | Tagged<TelemetryBaseEventPropertyType> {\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\t}\n\t\t: convertToBasePropertyTypeUntagged(x);\n}\n\nfunction convertToBasePropertyTypeUntagged(\n\tx: TelemetryEventPropertyTypeExt,\n): TelemetryBaseEventPropertyType {\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\t}\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\t}\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\t}\n\t}\n}\n\n/**\n * Tags all given `values` with the same `tag`.\n *\n * @param tag - The tag with which all `values` will be annotated.\n * @param values - The values to be tagged.\n *\n * @remarks\n * It supports properties of type {@link @fluidframework/core-interfaces#TelemetryBaseEventPropertyType},\n * as well as callbacks that return that type.\n *\n * @example Sample usage\n * ```typescript\n * {\n * \t// ...Other properties being added to a telemetry event\n * \t...tagData(\"someTag\", {foo: 1, bar: 2}),\n * \t// ...\n * }\n * ```\n * This will result in `foo` and `bar` added to the event with their values tagged.\n *\n * @internal\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\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\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\n\t\t.reduce((pv, cv) => {\n\t\t\tconst [key, value] = cv;\n\t\t\t// The ternary form is less legible in this case.\n\t\t\t// eslint-disable-next-line unicorn/prefer-ternary\n\t\t\tif (typeof value === \"function\") {\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 * Tags all provided `values` as {@link TelemetryDataTag.CodeArtifact}.\n *\n * @param values - The values to be tagged.\n *\n * @remarks\n * It supports properties of type {@link @fluidframework/core-interfaces#TelemetryBaseEventPropertyType},\n * as well as callbacks that return that type.\n *\n * @example Sample usage\n * ```typescript\n * {\n * \t// ...Other properties being added to a telemetry event\n * \t...tagCodeArtifacts(\"someTag\", {foo: 1, bar: 2}),\n * \t// ...\n * }\n * ```\n * This will result in `foo` and `bar` added to the event with their values tagged as {@link TelemetryDataTag.CodeArtifact}.\n *\n * @see {@link tagData}\n *\n * @internal\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\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\t})\n\t\t| (T[P] extends undefined ? undefined : never);\n} => tagData<TelemetryDataTag.CodeArtifact, T>(TelemetryDataTag.CodeArtifact, values);\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 { performanceNow } from \"@fluid-internal/client-utils\";\nimport {\n\ttype ITelemetryBaseEvent,\n\ttype ITelemetryBaseLogger,\n\tLogLevel,\n\ttype Tagged,\n\ttype TelemetryBaseEventPropertyType,\n} from \"@fluidframework/core-interfaces\";\n\nimport {\n\tCachedConfigProvider,\n\tloggerIsMonitoringContext,\n\tmixinMonitoringContext,\n} from \"./config.js\";\nimport {\n\textractLogSafeErrorProperties,\n\tgenerateStack,\n\tisILoggingError,\n\tisTaggedTelemetryPropertyValue,\n} from \"./errorLogging.js\";\nimport type {\n\tITelemetryErrorEventExt,\n\tITelemetryEventExt,\n\tITelemetryGenericEventExt,\n\tITelemetryLoggerExt,\n\tITelemetryPerformanceEventExt,\n\tITelemetryPropertiesExt,\n\tTelemetryEventCategory,\n\tTelemetryEventPropertyTypeExt,\n} from \"./telemetryTypes.js\";\n\n/**\n * Broad classifications to be applied to individual properties as they're prepared to be logged to telemetry.\n *\n * @privateRemarks Please do not modify existing entries, to maintain backwards compatibility.\n *\n * @internal\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\n/**\n * @legacy\n * @alpha\n */\nexport type TelemetryEventPropertyTypes = ITelemetryPropertiesExt[string];\n\n/**\n * @legacy\n * @alpha\n */\nexport type ITelemetryLoggerPropertyBag = Record<\n\tstring,\n\tTelemetryEventPropertyTypes | (() => TelemetryEventPropertyTypes)\n>;\n\n/**\n * @legacy\n * @alpha\n */\nexport interface ITelemetryLoggerPropertyBags {\n\tall?: ITelemetryLoggerPropertyBag;\n\terror?: ITelemetryLoggerPropertyBag;\n}\n\n/**\n * Attempts to parse number from string.\n * If it fails, it will return the original string.\n *\n * @remarks\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 * @internal\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\n// TODO: add docs\n// eslint-disable-next-line jsdoc/require-description\n/**\n * @internal\n */\nexport function formatTick(tick: number): number {\n\treturn Math.floor(tick);\n}\n\n/**\n * String used to concatenate the namespace of parent loggers and their child loggers.\n * @internal\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\t/**\n\t * {@inheritDoc eventNamespaceSeparator}\n\t */\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: ITelemetryErrorEventExt, 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<\n\t\tT extends ITelemetryLoggerPropertyBag = ITelemetryLoggerPropertyBag,\n\t>(toExtend: T, includeErrorProps: boolean): 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, getterOrValue] of Object.entries(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\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 *\n * @internal\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, taggableProp] of Object.entries(eventWithTagsMaybe)) {\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\t}\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\t}\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\t}\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\t}\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 *\n * @remarks\n * Passing in no props object (i.e. undefined) will return a logger that is effectively a no-op.\n *\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 * @legacy\n * @alpha\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\t? baseLogger.namespace\n\t\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(baseLogger ?? { send(): void {} }, namespace, properties);\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 * Input properties for {@link createMultiSinkLogger}.\n *\n * @internal\n */\nexport interface MultiSinkLoggerProperties {\n\t/**\n\t * Will be prefixed to all event names.\n\t */\n\tnamespace?: string;\n\n\t/**\n\t * Default properties that will be applied to all events flowing through this logger.\n\t */\n\tproperties?: ITelemetryLoggerPropertyBags;\n\n\t/**\n\t * The base loggers that this logger will forward the logs to, after it processes them.\n\t */\n\tloggers?: (ITelemetryBaseLogger | undefined)[];\n\n\t/**\n\t * If true, the logger will attempt to copy the custom properties (if they are of a known type, i.e. one from this package) of all the base loggers passed to it, to apply them itself to logs that flow through.\n\t */\n\ttryInheritProperties?: true;\n}\n\n/**\n * Create a logger which logs to multiple other loggers based on the provided props object.\n *\n * @internal\n */\nexport function createMultiSinkLogger(props: MultiSinkLoggerProperties): 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\tpublic constructor(\n\t\tnamespace?: string,\n\t\tproperties?: ITelemetryLoggerPropertyBags,\n\t\tloggers: ITelemetryBaseLogger[] = [],\n\t\ttryInheritProperties?: true,\n\t) {\n\t\tlet realProperties = properties === undefined ? undefined : { ...properties };\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 {@link PerformanceEvent} should log.\n *\n * @remarks\n * By default, all events are logged, but the client can override this behavior.\n *\n * For example, there is rarely a need to record a start event, as we're really after\n * success / failure tracking, including duration (on success).\n *\n * @internal\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 *\n * @internal\n */\nexport class PerformanceEvent {\n\t/**\n\t * Creates an instance of {@link PerformanceEvent} and starts measurements\n\t * @param logger - the logger to be used for publishing events\n\t * @param event - the logging event details which will be published with the performance measurements\n\t * @param markers - See {@link IPerformanceEventMarkers}\n\t * @param recordHeapSize - whether or not to also record memory performance\n\t * @param emitLogs - should this instance emit logs. If set to false, logs will not be emitted to the logger,\n\t * but measurements will still be performed and any specified markers will be generated.\n\t * @returns An instance of {@link PerformanceEvent}\n\t */\n\tpublic static start(\n\t\tlogger: ITelemetryLoggerExt,\n\t\tevent: ITelemetryGenericEventExt,\n\t\tmarkers?: IPerformanceEventMarkers,\n\t\temitLogs: boolean = true,\n\t): PerformanceEvent {\n\t\treturn new PerformanceEvent(logger, event, markers, emitLogs);\n\t}\n\n\t/**\n\t * Measure a synchronous task\n\t * @param logger - the logger to be used for publishing events\n\t * @param event - the logging event details which will be published with the performance measurements\n\t * @param callback - the task to be executed and measured\n\t * @param markers - See {@link IPerformanceEventMarkers}\n\t * @param sampleThreshold - events with the same name and category will be sent to the logger\n\t * only when we hit this many executions of the task. If unspecified, all events will be sent.\n\t * @returns The results of the executed task\n\t *\n\t * @remarks Note that if the \"same\" event (category + eventName) would be emitted by different\n\t * tasks (`callback`), `sampleThreshold` is still applied only based on the event's category + eventName,\n\t * so executing either of the tasks will increase the internal counter and they\n\t * effectively \"share\" the sampling rate for the event.\n\t */\n\tpublic static timedExec<T>(\n\t\tlogger: ITelemetryLoggerExt,\n\t\tevent: ITelemetryGenericEventExt,\n\t\tcallback: (event: PerformanceEvent) => T,\n\t\tmarkers?: IPerformanceEventMarkers,\n\t\tsampleThreshold: number = 1,\n\t): T {\n\t\tconst perfEvent = PerformanceEvent.start(\n\t\t\tlogger,\n\t\t\tevent,\n\t\t\tmarkers,\n\t\t\tPerformanceEvent.shouldReport(event, sampleThreshold),\n\t\t);\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\t/**\n\t * Measure an asynchronous task\n\t * @param logger - the logger to be used for publishing events\n\t * @param event - the logging event details which will be published with the performance measurements\n\t * @param callback - the task to be executed and measured\n\t * @param markers - See {@link IPerformanceEventMarkers}\n\t * @param recordHeapSize - whether or not to also record memory performance\n\t * @param sampleThreshold - events with the same name and category will be sent to the logger\n\t * only when we hit this many executions of the task. If unspecified, all events will be sent.\n\t * @returns The results of the executed task\n\t *\n\t * @remarks Note that if the \"same\" event (category + eventName) would be emitted by different\n\t * tasks (`callback`), `sampleThreshold` is still applied only based on the event's category + eventName,\n\t * so executing either of the tasks will increase the internal counter and they\n\t * effectively \"share\" the sampling rate for the event.\n\t */\n\tpublic static async timedExecAsync<T>(\n\t\tlogger: ITelemetryLoggerExt,\n\t\tevent: ITelemetryGenericEventExt,\n\t\tcallback: (event: PerformanceEvent) => Promise<T>,\n\t\tmarkers?: IPerformanceEventMarkers,\n\t\tsampleThreshold: number = 1,\n\t): Promise<T> {\n\t\tconst perfEvent = PerformanceEvent.start(\n\t\t\tlogger,\n\t\t\tevent,\n\t\t\tmarkers,\n\t\t\tPerformanceEvent.shouldReport(event, sampleThreshold),\n\t\t);\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 performanceNow() - this.startTime;\n\t}\n\n\tprivate event?: ITelemetryGenericEventExt;\n\tprivate readonly startTime = performanceNow();\n\tprivate startMark?: string;\n\n\tprotected constructor(\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t\tevent: ITelemetryGenericEventExt,\n\t\tprivate readonly markers: IPerformanceEventMarkers = { end: true, cancel: \"generic\" },\n\t\tprivate readonly emitLogs: boolean = true,\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 (\n\t\t\ttypeof window === \"object\" &&\n\t\t\twindow?.performance?.mark !== undefined &&\n\t\t\twindow?.performance?.mark !== null\n\t\t) {\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(\n\t\tprops?: ITelemetryPropertiesExt,\n\t\teventNameSuffix: string = \"update\",\n\t): 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\n\t\t// To prevent the event from being reported again later\n\t\tthis.event = undefined;\n\t}\n\n\tpublic end(props?: ITelemetryPropertiesExt): void {\n\t\tthis.reportEvent(\"end\", props);\n\t\tthis.performanceEndMark();\n\n\t\t// To prevent the event from being reported again later\n\t\tthis.event = undefined;\n\t}\n\n\tprivate performanceEndMark(): void {\n\t\tif (this.startMark !== undefined && 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?: ITelemetryPropertiesExt, 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\n\t\t// To prevent the event from being reported again later\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?: ITelemetryPropertiesExt,\n\t\terror?: unknown,\n\t): void {\n\t\t// If the caller invokes cancel or end directly inside the callback for timedExec[Async],\n\t\t// then it's possible to come back through reportEvent twice. Only the first time counts.\n\t\tif (!this.event) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.emitLogs) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst event: ITelemetryPerformanceEventExt = { ...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}\n\n\t\tthis.logger.sendPerformanceEvent(event, error);\n\t}\n\n\tprivate static readonly eventHits = new Map<string, number>();\n\tprivate static shouldReport(\n\t\tevent: ITelemetryGenericEventExt,\n\t\tsampleThreshold: number,\n\t): boolean {\n\t\tconst eventKey = `.${event.category}.${event.eventName}`;\n\t\tconst hitCount = PerformanceEvent.eventHits.get(eventKey) ?? 0;\n\t\tPerformanceEvent.eventHits.set(eventKey, hitCount >= sampleThreshold ? 1 : hitCount + 1);\n\t\treturn hitCount % sampleThreshold === 0;\n\t}\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<TelemetryBaseEventPropertyType> - 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): TelemetryBaseEventPropertyType | Tagged<TelemetryBaseEventPropertyType> {\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\t}\n\t\t: convertToBasePropertyTypeUntagged(x);\n}\n\nfunction convertToBasePropertyTypeUntagged(\n\tx: TelemetryEventPropertyTypeExt,\n): TelemetryBaseEventPropertyType {\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\t}\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\t}\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\t}\n\t}\n}\n\n/**\n * Tags all given `values` with the same `tag`.\n *\n * @param tag - The tag with which all `values` will be annotated.\n * @param values - The values to be tagged.\n *\n * @remarks\n * It supports properties of type {@link @fluidframework/core-interfaces#TelemetryBaseEventPropertyType},\n * as well as callbacks that return that type.\n *\n * @example Sample usage\n * ```typescript\n * {\n * \t// ...Other properties being added to a telemetry event\n * \t...tagData(\"someTag\", {foo: 1, bar: 2}),\n * \t// ...\n * }\n * ```\n * This will result in `foo` and `bar` added to the event with their values tagged.\n *\n * @internal\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\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\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\n\t\t.reduce((pv, cv) => {\n\t\t\tconst [key, value] = cv;\n\t\t\t// The ternary form is less legible in this case.\n\t\t\t// eslint-disable-next-line unicorn/prefer-ternary\n\t\t\tif (typeof value === \"function\") {\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 * Tags all provided `values` as {@link TelemetryDataTag.CodeArtifact}.\n *\n * @param values - The values to be tagged.\n *\n * @remarks\n * It supports properties of type {@link @fluidframework/core-interfaces#TelemetryBaseEventPropertyType},\n * as well as callbacks that return that type.\n *\n * @example Sample usage\n * ```typescript\n * {\n * \t// ...Other properties being added to a telemetry event\n * \t...tagCodeArtifacts(\"someTag\", {foo: 1, bar: 2}),\n * \t// ...\n * }\n * ```\n * This will result in `foo` and `bar` added to the event with their values tagged as {@link TelemetryDataTag.CodeArtifact}.\n *\n * @see {@link tagData}\n *\n * @internal\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\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\t})\n\t\t| (T[P] extends undefined ? undefined : never);\n} => tagData<TelemetryDataTag.CodeArtifact, T>(TelemetryDataTag.CodeArtifact, values);\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"mockLogger.d.ts","sourceRoot":"","sources":["../src/mockLogger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,QAAQ,EACR,MAAM,iCAAiC,CAAC;AAIzC,OAAO,KAAK,EACX,kBAAkB,EAClB,mBAAmB,EAEnB,MAAM,qBAAqB,CAAC;AAE7B;;;;;;;GAOG;AACH,qBAAa,UAAW,YAAW,oBAAoB;IACtD;;OAEG;IACH,IAAW,MAAM,IAAI,SAAS,mBAAmB,EAAE,CAElD;IAED,OAAO,CAAC,OAAO,CAA6B;IAE5C;;OAEG;IACH,SAAgB,WAAW,EAAE,QAAQ,CAAC;gBAEnB,WAAW,CAAC,EAAE,QAAQ;IAIzC;;OAEG;IACI,KAAK,IAAI,IAAI;IAIb,iBAAiB,IAAI,mBAAmB;IAI/C;;OAEG;IACI,IAAI,CAAC,KAAK,EAAE,mBAAmB,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI;IAMlE;;;;;;;;;OASG;IACI,WAAW,CACjB,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,iBAAiB,GAAE,OAAe,EAClC,qBAAqB,GAAE,OAAc,GACnC,OAAO;IAWV;;;;;;;;;;OAUG;IACI,WAAW,CACjB,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe,EAClC,qBAAqB,GAAE,OAAc,GACnC,IAAI;IAcP;;;;;;;;OAQG;IACI,aAAa,CACnB,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,iBAAiB,GAAE,OAAe,EAClC,qBAAqB,GAAE,OAAc,GACnC,OAAO;IASV;;;;;;;;;;OAUG;IACI,cAAc,CACpB,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe,EAClC,qBAAqB,GAAE,OAAc,GACnC,IAAI;IAcP;;;;;;;;;OASG;IACI,gBAAgB,CACtB,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,iBAAiB,GAAE,OAAe,EAClC,qBAAqB,GAAE,OAAc,GACnC,OAAO;IAYV;;;;;;;;;;OAUG;IACI,iBAAiB,CACvB,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe,EAClC,qBAAqB,GAAE,OAAc,GACnC,IAAI;IAcP;;;;;;;;;;OAUG;IACI,eAAe,CACrB,gBAAgB,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACzD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe,EAClC,qBAAqB,GAAE,OAAc,GACnC,IAAI;IAcP,OAAO,CAAC,qBAAqB;IAyB7B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAsB1B;;OAEG;IACI,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,qBAAqB,GAAE,OAAc,GAAG,IAAI;CAapF;AA+BD;;;;;;GAMG;AACH,MAAM,WAAW,cAAe,SAAQ,mBAAmB;IAC1D;;OAEG;IACH,MAAM,IAAI,SAAS,kBAAkB,EAAE,CAAC;CACxC;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,CAAC,EAAE,QAAQ,GAAG,cAAc,CAQ1E"}
1
+ {"version":3,"file":"mockLogger.d.ts","sourceRoot":"","sources":["../src/mockLogger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,QAAQ,EACR,MAAM,iCAAiC,CAAC;AAIzC,OAAO,KAAK,EACX,kBAAkB,EAClB,mBAAmB,EAEnB,MAAM,qBAAqB,CAAC;AAE7B;;;;;;;GAOG;AACH,qBAAa,UAAW,YAAW,oBAAoB;IACtD;;OAEG;IACH,IAAW,MAAM,IAAI,SAAS,mBAAmB,EAAE,CAElD;IAED,OAAO,CAAC,OAAO,CAA6B;IAE5C;;OAEG;IACH,SAAgB,WAAW,EAAE,QAAQ,CAAC;gBAEnB,WAAW,CAAC,EAAE,QAAQ;IAIzC;;OAEG;IACI,KAAK,IAAI,IAAI;IAIb,iBAAiB,IAAI,mBAAmB;IAI/C;;OAEG;IACI,IAAI,CAAC,KAAK,EAAE,mBAAmB,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI;IAMlE;;;;;;;;;OASG;IACI,WAAW,CACjB,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,iBAAiB,GAAE,OAAe,EAClC,qBAAqB,GAAE,OAAc,GACnC,OAAO;IAWV;;;;;;;;;;OAUG;IACI,WAAW,CACjB,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe,EAClC,qBAAqB,GAAE,OAAc,GACnC,IAAI;IAcP;;;;;;;;OAQG;IACI,aAAa,CACnB,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,iBAAiB,GAAE,OAAe,EAClC,qBAAqB,GAAE,OAAc,GACnC,OAAO;IASV;;;;;;;;;;OAUG;IACI,cAAc,CACpB,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe,EAClC,qBAAqB,GAAE,OAAc,GACnC,IAAI;IAcP;;;;;;;;;OASG;IACI,gBAAgB,CACtB,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,iBAAiB,GAAE,OAAe,EAClC,qBAAqB,GAAE,OAAc,GACnC,OAAO;IAYV;;;;;;;;;;OAUG;IACI,iBAAiB,CACvB,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe,EAClC,qBAAqB,GAAE,OAAc,GACnC,IAAI;IAcP;;;;;;;;;;OAUG;IACI,eAAe,CACrB,gBAAgB,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACzD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe,EAClC,qBAAqB,GAAE,OAAc,GACnC,IAAI;IAcP,OAAO,CAAC,qBAAqB;IA2B7B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAsB1B;;OAEG;IACI,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,qBAAqB,GAAE,OAAc,GAAG,IAAI;CAapF;AA+BD;;;;;;GAMG;AACH,MAAM,WAAW,cAAe,SAAQ,mBAAmB;IAC1D;;OAEG;IACH,MAAM,IAAI,SAAS,kBAAkB,EAAE,CAAC;CACxC;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,CAAC,EAAE,QAAQ,GAAG,cAAc,CAQ1E"}
@@ -188,8 +188,10 @@ ${JSON.stringify(actualEvents)}`);
188
188
  getMatchedEventsCount(expectedEvents, inlineDetailsProp, clearEventsAfterCheck) {
189
189
  let iExpectedEvent = 0;
190
190
  for (const event of this._events) {
191
+ const expectedEvent = expectedEvents[iExpectedEvent];
191
192
  if (iExpectedEvent < expectedEvents.length &&
192
- MockLogger.eventsMatch(event, expectedEvents[iExpectedEvent], inlineDetailsProp)) {
193
+ expectedEvent !== undefined &&
194
+ MockLogger.eventsMatch(event, expectedEvent, inlineDetailsProp)) {
193
195
  // We found the next expected event; increment
194
196
  ++iExpectedEvent;
195
197
  }
@@ -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 {\n\ttype ITelemetryBaseEvent,\n\ttype ITelemetryBaseLogger,\n\tLogLevel,\n} from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\nimport { createChildLogger } from \"./logger.js\";\nimport type {\n\tITelemetryEventExt,\n\tITelemetryLoggerExt,\n\tITelemetryPropertiesExt,\n} from \"./telemetryTypes.js\";\n\n/**\n * Mock {@link @fluidframework/core-interfaces#ITelemetryBaseLogger} implementation.\n *\n * Records events sent to it, and then can walk back over those events, searching for a set of expected events to\n * match against the logged events.\n *\n * @internal\n */\nexport class MockLogger implements ITelemetryBaseLogger {\n\t/**\n\t * Gets an immutable copy of the events logged thus far.\n\t */\n\tpublic get events(): readonly ITelemetryBaseEvent[] {\n\t\treturn [...this._events];\n\t}\n\n\tprivate _events: ITelemetryBaseEvent[] = [];\n\n\t/**\n\t * {@inheritDoc @fluidframework/core-interfaces#ITelemetryBaseLogger.minLogLevel}\n\t */\n\tpublic readonly minLogLevel: LogLevel;\n\n\tpublic constructor(minLogLevel?: LogLevel) {\n\t\tthis.minLogLevel = minLogLevel ?? LogLevel.default;\n\t}\n\n\t/**\n\t * Clears the events logged thus far.\n\t */\n\tpublic clear(): void {\n\t\tthis._events = [];\n\t}\n\n\tpublic toTelemetryLogger(): ITelemetryLoggerExt {\n\t\treturn createChildLogger({ logger: this });\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/core-interfaces#ITelemetryBaseLogger.send}\n\t */\n\tpublic send(event: ITelemetryBaseEvent, logLevel?: LogLevel): void {\n\t\tif ((logLevel ?? LogLevel.default) >= this.minLogLevel) {\n\t\t\tthis._events.push(event);\n\t\t}\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 * @param clearEventsAfterCheck - Whether or not to clear the logger's {@link MockLogger.events} after performing the check.\n\t * Default: true.\n\t */\n\tpublic matchEvents(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t\tclearEventsAfterCheck: boolean = true,\n\t): boolean {\n\t\tconst matchedExpectedEventCount = this.getMatchedEventsCount(\n\t\t\texpectedEvents,\n\t\t\tinlineDetailsProp,\n\t\t\tclearEventsAfterCheck,\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 {@link MockLogger.matchEvents} is `true` for the given events.\n\t * @param expectedEvents - The events expected to appear.\n\t * @param message - Optional error message to include in the thrown error, if the condition is not satisfied.\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 * @param clearEventsAfterCheck - Whether or not to clear the logger's {@link MockLogger.events} after performing the check.\n\t * Default: true.\n\t * @throws An error containing the actual/expected event data if the condition is not satisfied.\n\t */\n\tpublic assertMatch(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t\tclearEventsAfterCheck: boolean = true,\n\t): void {\n\t\t// Use copy to ensure events aren't cleared out from under us before we (potentially) throw\n\t\tconst actualEvents = this.events;\n\n\t\tif (!this.matchEvents(expectedEvents, inlineDetailsProp, clearEventsAfterCheck)) {\n\t\t\tthrow new Error(`${message ?? \"Logs don't match\"}\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\tpublic matchAnyEvent(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t\tclearEventsAfterCheck: boolean = true,\n\t): boolean {\n\t\tconst matchedExpectedEventCount = this.getMatchedEventsCount(\n\t\t\texpectedEvents,\n\t\t\tinlineDetailsProp,\n\t\t\tclearEventsAfterCheck,\n\t\t);\n\t\treturn matchedExpectedEventCount > 0;\n\t}\n\n\t/**\n\t * Asserts {@link MockLogger.matchAnyEvent} is `true` for the given events.\n\t * @param expectedEvents - The events expected to appear.\n\t * @param message - Optional error message to include in the thrown error, if the condition is not satisfied.\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 * @param clearEventsAfterCheck - Whether or not to clear the logger's {@link MockLogger.events} after performing the check.\n\t * Default: true.\n\t * @throws An error containing the actual/expected event data if the condition is not satisfied.\n\t */\n\tpublic assertMatchAny(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t\tclearEventsAfterCheck: boolean = true,\n\t): void {\n\t\t// Use copy to ensure events aren't cleared out from under us before we (potentially) throw\n\t\tconst actualEvents = this.events;\n\n\t\tif (!this.matchAnyEvent(expectedEvents, inlineDetailsProp, clearEventsAfterCheck)) {\n\t\t\tthrow new Error(`${message ?? \"Logs don't match\"}\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 * @param clearEventsAfterCheck - Whether or not to clear the logger's {@link MockLogger.events} after performing the check.\n\t * Default: true.\n\t */\n\tpublic matchEventStrict(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t\tclearEventsAfterCheck: boolean = true,\n\t): boolean {\n\t\tif (expectedEvents.length !== this._events.length) {\n\t\t\tif (clearEventsAfterCheck) {\n\t\t\t\tthis.clear();\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t// `events` will be cleared by the below check if requested.\n\t\treturn this.matchEvents(expectedEvents, inlineDetailsProp, clearEventsAfterCheck);\n\t}\n\n\t/**\n\t * Asserts {@link MockLogger.matchEvents} is `true` for the given events.\n\t * @param expectedEvents - The events expected to appear.\n\t * @param message - Optional error message to include in the thrown error, if the condition is not satisfied.\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 * @param clearEventsAfterCheck - Whether or not to clear the logger's {@link MockLogger.events} after performing the check.\n\t * Default: true.\n\t * @throws An error containing the actual/expected event data if the condition is not satisfied.\n\t */\n\tpublic assertMatchStrict(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t\tclearEventsAfterCheck: boolean = true,\n\t): void {\n\t\t// Use copy to ensure events aren't cleared out from under us before we (potentially) throw\n\t\tconst actualEvents = this.events;\n\n\t\tif (!this.matchEventStrict(expectedEvents, inlineDetailsProp, clearEventsAfterCheck)) {\n\t\t\tthrow new Error(`${message ?? \"Logs don't match\"}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/**\n\t * Asserts {@link MockLogger.matchAnyEvent} is `false` for the given events.\n\t * @param disallowedEvents - The events expected to not appear.\n\t * @param message - Optional error message to include in the thrown error, if the condition is not satisfied.\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 * @param clearEventsAfterCheck - Whether or not to clear the logger's {@link MockLogger.events} after performing the check.\n\t * Default: true.\n\t * @throws An error containing the actual/expected event data if the condition is not satisfied.\n\t */\n\tpublic assertMatchNone(\n\t\tdisallowedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t\tclearEventsAfterCheck: boolean = true,\n\t): void {\n\t\t// Use copy to ensure events aren't cleared out from under us before we (potentially) throw\n\t\tconst actualEvents = this.events;\n\n\t\tif (this.matchAnyEvent(disallowedEvents, inlineDetailsProp, clearEventsAfterCheck)) {\n\t\t\tthrow new Error(`${message ?? \"Logs don't match\"}\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\tclearEventsAfterCheck: 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\tif (clearEventsAfterCheck) {\n\t\t\tthis.clear();\n\t\t}\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\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\t/**\n\t * Throws if any errors were logged\n\t */\n\tpublic assertNoErrors(message?: string, clearEventsAfterCheck: boolean = true): void {\n\t\tconst actualEvents = this.events;\n\t\tconst errors = actualEvents.filter((event) => event.category === \"error\");\n\t\tif (clearEventsAfterCheck) {\n\t\t\tthis.clear();\n\t\t}\n\t\tif (errors.length > 0) {\n\t\t\tthrow new Error(`${message ?? \"Errors found in logs\"}\n\nerror logs:\n${JSON.stringify(errors)}`);\n\t\t}\n\t}\n}\n\nfunction matchObjects(\n\tactual: ITelemetryPropertiesExt,\n\texpected: ITelemetryPropertiesExt,\n): 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\n/**\n * Mock {@link ITelemetryLoggerExt} implementation.\n *\n * @remarks Can be created via {@link createMockLoggerExt}.\n *\n * @internal\n */\nexport interface IMockLoggerExt extends ITelemetryLoggerExt {\n\t/**\n\t * Gets the events that have been logged so far.\n\t */\n\tevents(): readonly ITelemetryEventExt[];\n}\n\n/**\n * Creates an {@link IMockLoggerExt}.\n *\n * @internal\n */\nexport function createMockLoggerExt(minLogLevel?: LogLevel): IMockLoggerExt {\n\tconst mockLogger = new MockLogger(minLogLevel);\n\tconst childLogger = createChildLogger({ logger: mockLogger });\n\tObject.assign(childLogger, {\n\t\tevents: (): readonly ITelemetryEventExt[] =>\n\t\t\tmockLogger.events.map((e) => e as ITelemetryEventExt),\n\t});\n\treturn childLogger as IMockLoggerExt;\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\ttype ITelemetryBaseEvent,\n\ttype ITelemetryBaseLogger,\n\tLogLevel,\n} from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\nimport { createChildLogger } from \"./logger.js\";\nimport type {\n\tITelemetryEventExt,\n\tITelemetryLoggerExt,\n\tITelemetryPropertiesExt,\n} from \"./telemetryTypes.js\";\n\n/**\n * Mock {@link @fluidframework/core-interfaces#ITelemetryBaseLogger} implementation.\n *\n * Records events sent to it, and then can walk back over those events, searching for a set of expected events to\n * match against the logged events.\n *\n * @internal\n */\nexport class MockLogger implements ITelemetryBaseLogger {\n\t/**\n\t * Gets an immutable copy of the events logged thus far.\n\t */\n\tpublic get events(): readonly ITelemetryBaseEvent[] {\n\t\treturn [...this._events];\n\t}\n\n\tprivate _events: ITelemetryBaseEvent[] = [];\n\n\t/**\n\t * {@inheritDoc @fluidframework/core-interfaces#ITelemetryBaseLogger.minLogLevel}\n\t */\n\tpublic readonly minLogLevel: LogLevel;\n\n\tpublic constructor(minLogLevel?: LogLevel) {\n\t\tthis.minLogLevel = minLogLevel ?? LogLevel.default;\n\t}\n\n\t/**\n\t * Clears the events logged thus far.\n\t */\n\tpublic clear(): void {\n\t\tthis._events = [];\n\t}\n\n\tpublic toTelemetryLogger(): ITelemetryLoggerExt {\n\t\treturn createChildLogger({ logger: this });\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/core-interfaces#ITelemetryBaseLogger.send}\n\t */\n\tpublic send(event: ITelemetryBaseEvent, logLevel?: LogLevel): void {\n\t\tif ((logLevel ?? LogLevel.default) >= this.minLogLevel) {\n\t\t\tthis._events.push(event);\n\t\t}\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 * @param clearEventsAfterCheck - Whether or not to clear the logger's {@link MockLogger.events} after performing the check.\n\t * Default: true.\n\t */\n\tpublic matchEvents(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t\tclearEventsAfterCheck: boolean = true,\n\t): boolean {\n\t\tconst matchedExpectedEventCount = this.getMatchedEventsCount(\n\t\t\texpectedEvents,\n\t\t\tinlineDetailsProp,\n\t\t\tclearEventsAfterCheck,\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 {@link MockLogger.matchEvents} is `true` for the given events.\n\t * @param expectedEvents - The events expected to appear.\n\t * @param message - Optional error message to include in the thrown error, if the condition is not satisfied.\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 * @param clearEventsAfterCheck - Whether or not to clear the logger's {@link MockLogger.events} after performing the check.\n\t * Default: true.\n\t * @throws An error containing the actual/expected event data if the condition is not satisfied.\n\t */\n\tpublic assertMatch(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t\tclearEventsAfterCheck: boolean = true,\n\t): void {\n\t\t// Use copy to ensure events aren't cleared out from under us before we (potentially) throw\n\t\tconst actualEvents = this.events;\n\n\t\tif (!this.matchEvents(expectedEvents, inlineDetailsProp, clearEventsAfterCheck)) {\n\t\t\tthrow new Error(`${message ?? \"Logs don't match\"}\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\tpublic matchAnyEvent(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t\tclearEventsAfterCheck: boolean = true,\n\t): boolean {\n\t\tconst matchedExpectedEventCount = this.getMatchedEventsCount(\n\t\t\texpectedEvents,\n\t\t\tinlineDetailsProp,\n\t\t\tclearEventsAfterCheck,\n\t\t);\n\t\treturn matchedExpectedEventCount > 0;\n\t}\n\n\t/**\n\t * Asserts {@link MockLogger.matchAnyEvent} is `true` for the given events.\n\t * @param expectedEvents - The events expected to appear.\n\t * @param message - Optional error message to include in the thrown error, if the condition is not satisfied.\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 * @param clearEventsAfterCheck - Whether or not to clear the logger's {@link MockLogger.events} after performing the check.\n\t * Default: true.\n\t * @throws An error containing the actual/expected event data if the condition is not satisfied.\n\t */\n\tpublic assertMatchAny(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t\tclearEventsAfterCheck: boolean = true,\n\t): void {\n\t\t// Use copy to ensure events aren't cleared out from under us before we (potentially) throw\n\t\tconst actualEvents = this.events;\n\n\t\tif (!this.matchAnyEvent(expectedEvents, inlineDetailsProp, clearEventsAfterCheck)) {\n\t\t\tthrow new Error(`${message ?? \"Logs don't match\"}\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 * @param clearEventsAfterCheck - Whether or not to clear the logger's {@link MockLogger.events} after performing the check.\n\t * Default: true.\n\t */\n\tpublic matchEventStrict(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t\tclearEventsAfterCheck: boolean = true,\n\t): boolean {\n\t\tif (expectedEvents.length !== this._events.length) {\n\t\t\tif (clearEventsAfterCheck) {\n\t\t\t\tthis.clear();\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t// `events` will be cleared by the below check if requested.\n\t\treturn this.matchEvents(expectedEvents, inlineDetailsProp, clearEventsAfterCheck);\n\t}\n\n\t/**\n\t * Asserts {@link MockLogger.matchEvents} is `true` for the given events.\n\t * @param expectedEvents - The events expected to appear.\n\t * @param message - Optional error message to include in the thrown error, if the condition is not satisfied.\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 * @param clearEventsAfterCheck - Whether or not to clear the logger's {@link MockLogger.events} after performing the check.\n\t * Default: true.\n\t * @throws An error containing the actual/expected event data if the condition is not satisfied.\n\t */\n\tpublic assertMatchStrict(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t\tclearEventsAfterCheck: boolean = true,\n\t): void {\n\t\t// Use copy to ensure events aren't cleared out from under us before we (potentially) throw\n\t\tconst actualEvents = this.events;\n\n\t\tif (!this.matchEventStrict(expectedEvents, inlineDetailsProp, clearEventsAfterCheck)) {\n\t\t\tthrow new Error(`${message ?? \"Logs don't match\"}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/**\n\t * Asserts {@link MockLogger.matchAnyEvent} is `false` for the given events.\n\t * @param disallowedEvents - The events expected to not appear.\n\t * @param message - Optional error message to include in the thrown error, if the condition is not satisfied.\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 * @param clearEventsAfterCheck - Whether or not to clear the logger's {@link MockLogger.events} after performing the check.\n\t * Default: true.\n\t * @throws An error containing the actual/expected event data if the condition is not satisfied.\n\t */\n\tpublic assertMatchNone(\n\t\tdisallowedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t\tclearEventsAfterCheck: boolean = true,\n\t): void {\n\t\t// Use copy to ensure events aren't cleared out from under us before we (potentially) throw\n\t\tconst actualEvents = this.events;\n\n\t\tif (this.matchAnyEvent(disallowedEvents, inlineDetailsProp, clearEventsAfterCheck)) {\n\t\t\tthrow new Error(`${message ?? \"Logs don't match\"}\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\tclearEventsAfterCheck: boolean,\n\t): number {\n\t\tlet iExpectedEvent = 0;\n\t\tfor (const event of this._events) {\n\t\t\tconst expectedEvent = expectedEvents[iExpectedEvent];\n\t\t\tif (\n\t\t\t\tiExpectedEvent < expectedEvents.length &&\n\t\t\t\texpectedEvent !== undefined &&\n\t\t\t\tMockLogger.eventsMatch(event, expectedEvent, 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\tif (clearEventsAfterCheck) {\n\t\t\tthis.clear();\n\t\t}\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\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\t/**\n\t * Throws if any errors were logged\n\t */\n\tpublic assertNoErrors(message?: string, clearEventsAfterCheck: boolean = true): void {\n\t\tconst actualEvents = this.events;\n\t\tconst errors = actualEvents.filter((event) => event.category === \"error\");\n\t\tif (clearEventsAfterCheck) {\n\t\t\tthis.clear();\n\t\t}\n\t\tif (errors.length > 0) {\n\t\t\tthrow new Error(`${message ?? \"Errors found in logs\"}\n\nerror logs:\n${JSON.stringify(errors)}`);\n\t\t}\n\t}\n}\n\nfunction matchObjects(\n\tactual: ITelemetryPropertiesExt,\n\texpected: ITelemetryPropertiesExt,\n): 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\n/**\n * Mock {@link ITelemetryLoggerExt} implementation.\n *\n * @remarks Can be created via {@link createMockLoggerExt}.\n *\n * @internal\n */\nexport interface IMockLoggerExt extends ITelemetryLoggerExt {\n\t/**\n\t * Gets the events that have been logged so far.\n\t */\n\tevents(): readonly ITelemetryEventExt[];\n}\n\n/**\n * Creates an {@link IMockLoggerExt}.\n *\n * @internal\n */\nexport function createMockLoggerExt(minLogLevel?: LogLevel): IMockLoggerExt {\n\tconst mockLogger = new MockLogger(minLogLevel);\n\tconst childLogger = createChildLogger({ logger: mockLogger });\n\tObject.assign(childLogger, {\n\t\tevents: (): readonly ITelemetryEventExt[] =>\n\t\t\tmockLogger.events.map((e) => e as ITelemetryEventExt),\n\t});\n\treturn childLogger as IMockLoggerExt;\n}\n"]}