{"version":3,"file":"PerformanceClient.js","sources":["../../../src/telemetry/performance/PerformanceClient.ts"],"sourcesContent":["/*\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ApplicationTelemetry } from \"../../config/ClientConfiguration\";\nimport { Logger } from \"../../logger/Logger\";\nimport { InProgressPerformanceEvent, IPerformanceClient, PerformanceCallbackFunction } from \"./IPerformanceClient\";\nimport { IPerformanceMeasurement } from \"./IPerformanceMeasurement\";\nimport { PerformanceEvent, PerformanceEvents, PerformanceEventStatus } from \"./PerformanceEvent\";\n\nexport abstract class PerformanceClient implements IPerformanceClient {\n protected authority: string;\n protected libraryName: string;\n protected libraryVersion: string;\n protected applicationTelemetry: ApplicationTelemetry;\n protected clientId: string;\n protected logger: Logger;\n protected callbacks: Map;\n\n /**\n * Multiple events with the same correlation id.\n * Double keyed by correlation id and event id.\n * @protected\n * @type {Map>}\n */\n protected eventsByCorrelationId: Map>;\n\n /**\n * Underlying performance measurements for each operation\n *\n * @protected\n * @type {Map}\n */\n protected measurementsById: Map;\n\n /**\n * Creates an instance of PerformanceClient, \n * an abstract class containing core performance telemetry logic.\n *\n * @constructor\n * @param {string} clientId Client ID of the application\n * @param {string} authority Authority used by the application\n * @param {Logger} logger Logger used by the application\n * @param {string} libraryName Name of the library\n * @param {string} libraryVersion Version of the library\n */\n constructor(clientId: string, authority: string, logger: Logger, libraryName: string, libraryVersion: string, applicationTelemetry: ApplicationTelemetry) {\n this.authority = authority;\n this.libraryName = libraryName;\n this.libraryVersion = libraryVersion;\n this.applicationTelemetry = applicationTelemetry;\n this.clientId = clientId;\n this.logger = logger;\n this.callbacks = new Map();\n this.eventsByCorrelationId = new Map();\n this.measurementsById = new Map();\n }\n\n /**\n * Starts and returns an platform-specific implementation of IPerformanceMeasurement.\n *\n * @abstract\n * @param {string} measureName\n * @param {string} correlationId\n * @returns {IPerformanceMeasurement}\n */\n abstract startPerformanceMeasuremeant(measureName: string, correlationId: string): IPerformanceMeasurement;\n\n /**\n * Generates and returns a unique id, typically a guid.\n *\n * @abstract\n * @returns {string}\n */\n abstract generateId(): string;\n\n /**\n * Starts measuring performance for a given operation. Returns a function that should be used to end the measurement.\n *\n * @param {PerformanceEvents} measureName\n * @param {?string} [correlationId]\n * @returns {InProgressPerformanceEvent}\n */\n startMeasurement(measureName: PerformanceEvents, correlationId?: string): InProgressPerformanceEvent {\n // Generate a placeholder correlation if the request does not provide one\n const eventCorrelationId = correlationId || this.generateId();\n if (!correlationId) {\n this.logger.info(`PerformanceClient: No correlation id provided for ${measureName}, generating`, eventCorrelationId);\n }\n\n this.logger.trace(`PerformanceClient: Performance measurement started for ${measureName}`, eventCorrelationId);\n const performanceMeasurement = this.startPerformanceMeasuremeant(measureName, eventCorrelationId);\n performanceMeasurement.startMeasurement();\n\n const inProgressEvent: PerformanceEvent = {\n eventId: this.generateId(),\n status: PerformanceEventStatus.InProgress,\n authority: this.authority,\n libraryName: this.libraryName,\n libraryVersion: this.libraryVersion,\n appName: this.applicationTelemetry?.appName,\n appVersion: this.applicationTelemetry?.appVersion,\n clientId: this.clientId,\n name: measureName,\n startTimeMs: Date.now(),\n correlationId: eventCorrelationId,\n };\n\n // Store in progress events so they can be discarded if not ended properly\n this.cacheEventByCorrelationId(inProgressEvent);\n this.cacheMeasurement(inProgressEvent, performanceMeasurement);\n\n // Return the event and functions the caller can use to properly end/flush the measurement\n return {\n endMeasurement: (event?: Partial): PerformanceEvent | null => {\n const completedEvent = this.endMeasurement({\n // Initial set of event properties\n ...inProgressEvent,\n // Properties set when event ends\n ...event\n });\n\n if (completedEvent) {\n // Cache event so that submeasurements can be added downstream\n this.cacheEventByCorrelationId(completedEvent);\n }\n\n return completedEvent;\n },\n flushMeasurement: () => {\n return this.flushMeasurements(inProgressEvent.name, inProgressEvent.correlationId);\n },\n discardMeasurement: () => {\n return this.discardMeasurements(inProgressEvent.correlationId);\n },\n measurement: performanceMeasurement,\n event: inProgressEvent\n };\n\n }\n\n /**\n * Stops measuring the performance for an operation. Should only be called directly by PerformanceClient classes,\n * as consumers should instead use the function returned by startMeasurement.\n *\n * @param {PerformanceEvent} event\n * @returns {(PerformanceEvent | null)}\n */\n endMeasurement(event: PerformanceEvent): PerformanceEvent | null {\n const performanceMeasurement = this.measurementsById.get(event.eventId);\n if (performanceMeasurement) {\n // Immediately delete so that the same event isnt ended twice\n this.measurementsById.delete(event.eventId);\n performanceMeasurement.endMeasurement();\n const durationMs = performanceMeasurement.flushMeasurement();\n // null indicates no measurement was taken (e.g. needed performance APIs not present)\n if (durationMs !== null) {\n this.logger.trace(`PerformanceClient: Performance measurement ended for ${event.name}: ${durationMs} ms`, event.correlationId);\n\n const completedEvent: PerformanceEvent = {\n // Allow duration to be overwritten when event ends (e.g. testing), but not status\n durationMs: Math.round(durationMs),\n ...event,\n status: PerformanceEventStatus.Completed,\n };\n\n return completedEvent;\n } else {\n this.logger.trace(\"PerformanceClient: Performance measurement not taken\", event.correlationId);\n }\n } else {\n this.logger.trace(`PerformanceClient: Measurement not found for ${event.eventId}`, event.correlationId);\n }\n\n return null;\n }\n\n /**\n * Upserts event into event cache.\n * First key is the correlation id, second key is the event id.\n * Allows for events to be grouped by correlation id,\n * and to easily allow for properties on them to be updated.\n *\n * @private\n * @param {PerformanceEvent} event\n */\n private cacheEventByCorrelationId(event: PerformanceEvent) {\n const existingEvents = this.eventsByCorrelationId.get(event.correlationId);\n if (existingEvents) {\n this.logger.trace(`PerformanceClient: Performance measurement for ${event.name} added/updated`, event.correlationId);\n existingEvents.set(event.eventId, event);\n } else {\n this.logger.trace(`PerformanceClient: Performance measurement for ${event.name} started`, event.correlationId);\n this.eventsByCorrelationId.set(event.correlationId, new Map().set(event.eventId, event));\n }\n }\n\n /**\n * Cache measurements by their id.\n *\n * @private\n * @param {PerformanceEvent} event\n * @param {IPerformanceMeasurement} measurement\n */\n private cacheMeasurement(event: PerformanceEvent, measurement: IPerformanceMeasurement) {\n this.measurementsById.set(event.eventId, measurement);\n }\n\n /**\n * Gathers and emits performance events for measurements taked for the given top-level API and correlation ID.\n *\n * @param {PerformanceEvents} measureName\n * @param {string} correlationId\n */\n flushMeasurements(measureName: PerformanceEvents, correlationId: string): void {\n this.logger.trace(`PerformanceClient: Performance measurements flushed for ${measureName}`, correlationId);\n const eventsForCorrelationId = this.eventsByCorrelationId.get(correlationId);\n if (eventsForCorrelationId) {\n this.discardMeasurements(correlationId);\n\n /*\n * Manually end incomplete submeasurements to ensure there arent orphaned/never ending events.\n * Incomplete submeasurements are likely an instrumentation bug that should be fixed.\n * IE only supports Map.forEach.\n */\n const completedEvents: PerformanceEvent[] = [];\n eventsForCorrelationId.forEach(event => {\n if (event.name !== measureName && event.status !== PerformanceEventStatus.Completed) {\n this.logger.trace(`PerformanceClient: Incomplete submeasurement ${event.name} found for ${measureName}`, correlationId);\n\n const completedEvent = this.endMeasurement(event);\n if (completedEvent) {\n completedEvents.push(completedEvent);\n }\n }\n\n completedEvents.push(event);\n });\n\n // Sort events by start time (earliest first)\n const sortedCompletedEvents = completedEvents.sort((eventA, eventB) => eventA.startTimeMs - eventB.startTimeMs);\n\n // Take completed top level event and add completed submeasurements durations as properties\n const topLevelEvents = sortedCompletedEvents.filter(event => event.name === measureName && event.status === PerformanceEventStatus.Completed);\n if (topLevelEvents.length > 0) {\n /*\n * Only take the first top-level event if there are multiple events with the same correlation id.\n * This greatly simplifies logic for submeasurements.\n */\n if (topLevelEvents.length > 1) {\n this.logger.verbose(\"PerformanceClient: Multiple distinct top-level performance events found, using the first\", correlationId);\n }\n const topLevelEvent = topLevelEvents[0];\n\n this.logger.verbose(`PerformanceClient: Measurement found for ${measureName}`, correlationId);\n\n // Build event object with top level and sub measurements\n const eventToEmit = sortedCompletedEvents.reduce((previous, current) => {\n if (current.name !== measureName) {\n this.logger.trace(`PerformanceClient: Complete submeasurement found for ${current.name}`, correlationId);\n // TODO: Emit additional properties for each subMeasurement\n const subMeasurementName = `${current.name}DurationMs`;\n /*\n * Some code paths, such as resolving an authority, can occur multiple times.\n * Only take the first measurement, since the second could be read from the cache,\n * or due to the same correlation id being used for two distinct requests.\n */\n if (!previous[subMeasurementName]) {\n previous[subMeasurementName] = current.durationMs;\n } else {\n this.logger.verbose(`PerformanceClient: Submeasurement for ${measureName} already exists for ${current.name}, ignoring`, correlationId);\n }\n if (current.accessTokenSize) {\n previous.accessTokenSize = current.accessTokenSize;\n }\n if (current.idTokenSize) {\n previous.idTokenSize = current.idTokenSize;\n }\n if (current.refreshTokenSize) {\n previous.refreshTokenSize = current.refreshTokenSize;\n }\n }\n\n return previous;\n }, topLevelEvent);\n\n this.emitEvents([eventToEmit], eventToEmit.correlationId);\n } else {\n this.logger.verbose(`PerformanceClient: No completed top-level measurements found for ${measureName}`, correlationId);\n }\n } else {\n this.logger.verbose(\"PerformanceClient: No measurements found\", correlationId);\n }\n }\n\n /**\n * Removes measurements for a given correlation id.\n *\n * @param {string} correlationId\n */\n discardMeasurements(correlationId: string): void {\n this.logger.trace(\"PerformanceClient: Performance measurements discarded\", correlationId);\n this.eventsByCorrelationId.delete(correlationId);\n }\n\n /**\n * Registers a callback function to receive performance events.\n *\n * @param {PerformanceCallbackFunction} callback\n * @returns {string}\n */\n addPerformanceCallback(callback: PerformanceCallbackFunction): string {\n const callbackId = this.generateId();\n this.callbacks.set(callbackId, callback);\n this.logger.verbose(`PerformanceClient: Performance callback registered with id: ${callbackId}`);\n\n return callbackId;\n }\n\n /**\n * Removes a callback registered with addPerformanceCallback.\n *\n * @param {string} callbackId\n * @returns {boolean}\n */\n removePerformanceCallback(callbackId: string): boolean {\n const result = this.callbacks.delete(callbackId);\n\n if (result) {\n this.logger.verbose(`PerformanceClient: Performance callback ${callbackId} removed.`);\n } else {\n this.logger.verbose(`PerformanceClient: Performance callback ${callbackId} not removed.`);\n }\n\n return result;\n }\n\n /**\n * Emits events to all registered callbacks.\n *\n * @param {PerformanceEvent[]} events\n * @param {?string} [correlationId]\n */\n emitEvents(events: PerformanceEvent[], correlationId: string): void {\n this.logger.verbose(\"PerformanceClient: Emitting performance events\", correlationId);\n\n this.callbacks.forEach((callback: PerformanceCallbackFunction, callbackId: string) => {\n this.logger.trace(`PerformanceClient: Emitting event to callback ${callbackId}`, correlationId);\n callback.apply(null, [events]);\n });\n }\n\n}\n"],"names":[],"mappings":"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"}