UNPKG

@azure/cosmos

Version:
125 lines 6.61 kB
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. import { Constants } from "../common/index.js"; import { getCurrentTimestampInMs } from "../utils/time.js"; /** * @hidden * Internal class to hold CosmosDiagnostic aggregate information all through the lifecycle of a request. * This object gathers diagnostic information throughout Client operation which may span across multiple * Server call, retries etc. * Functions - recordFailedAttempt, recordMetaDataQuery, recordEndpointContactEvent are used to ingest * data into the context. At the end of operation, getDiagnostics() is used to * get final CosmosDiagnostic object. */ export class CosmosDiagnosticContext { requestStartTimeUTCinMs; failedAttempts = []; metadataLookups = []; gatewayStatistics = []; locationEndpointsContacted = new Set(); encryptionDiagnostics; constructor() { this.requestStartTimeUTCinMs = getCurrentTimestampInMs(); } recordFailedAttempt(gatewayStatistics, retryAttemptNumber) { const attempt = { attemptNumber: retryAttemptNumber, startTimeUTCInMs: gatewayStatistics.startTimeUTCInMs, durationInMs: gatewayStatistics.durationInMs, statusCode: gatewayStatistics.statusCode, substatusCode: gatewayStatistics.subStatusCode, requestPayloadLengthInBytes: gatewayStatistics.requestPayloadLengthInBytes, responsePayloadLengthInBytes: gatewayStatistics.responsePayloadLengthInBytes, activityId: gatewayStatistics.activityId, operationType: gatewayStatistics.operationType, resourceType: gatewayStatistics.resourceType, }; this.failedAttempts.push(attempt); } recordNetworkCall(gatewayStatistics) { this.gatewayStatistics.push(gatewayStatistics); } recordEncryptionDiagnostics(encryptionDiagnostics) { const { encryptContent, decryptContent } = encryptionDiagnostics; const encryptionDuration = encryptContent[Constants.Encryption.DiagnosticsDuration] ?? 0; const decryptionDuration = decryptContent[Constants.Encryption.DiagnosticsDuration] ?? 0; encryptionDiagnostics.processingDurationInMs = encryptionDuration + decryptionDuration; this.encryptionDiagnostics = encryptionDiagnostics; } /** * Merge given DiagnosticContext to current node's DiagnosticContext, Treating GatewayRequests of * given DiagnosticContext, as metadata requests. */ mergeDiagnostics(childDiagnostics, metadataType) { // Copy Location endpoints contacted. childDiagnostics.locationEndpointsContacted.forEach((endpoint) => this.locationEndpointsContacted.add(endpoint)); // Copy child nodes's GatewayStatistics to parent's metadata lookups. childDiagnostics.gatewayStatistics.forEach((gateway) => this.metadataLookups.push({ activityId: gateway.activityId, requestPayloadLengthInBytes: gateway.requestPayloadLengthInBytes, responsePayloadLengthInBytes: gateway.responsePayloadLengthInBytes, startTimeUTCInMs: gateway.startTimeUTCInMs, operationType: gateway.operationType, resourceType: gateway.resourceType, durationInMs: gateway.durationInMs, metaDataType: metadataType, })); } /** * Merge given DiagnosticContext to current node's DiagnosticContext for bulk */ mergeBulkDiagnostics(childDiagnostics) { // Copy Location endpoints contacted. childDiagnostics.locationEndpointsContacted.forEach((endpoint) => this.locationEndpointsContacted.add(endpoint)); // Copy child nodes's GatewayStatistics to parent's gateway statistics. childDiagnostics.gatewayStatistics.forEach((gateway) => this.gatewayStatistics.push(gateway)); // merge metadata lookups and failed attempts childDiagnostics.metadataLookups.forEach((lookup) => this.metadataLookups.push(lookup)); childDiagnostics.failedAttempts.forEach((lookup) => this.failedAttempts.push(lookup)); if (!this.encryptionDiagnostics) { this.encryptionDiagnostics = childDiagnostics.encryptionDiagnostics; } else if (childDiagnostics.encryptionDiagnostics) { this.encryptionDiagnostics.decryptContent = childDiagnostics.encryptionDiagnostics.decryptContent; this.encryptionDiagnostics.processingDurationInMs = (this.encryptionDiagnostics.processingDurationInMs || 0) + (childDiagnostics.encryptionDiagnostics.processingDurationInMs || 0); } } getClientSideStats(endTimeUTCInMs = getCurrentTimestampInMs()) { return { requestStartTimeUTCInMs: this.requestStartTimeUTCinMs, requestDurationInMs: endTimeUTCInMs - this.requestStartTimeUTCinMs, totalRequestPayloadLengthInBytes: this.getTotalRequestPayloadLength(), totalResponsePayloadLengthInBytes: this.getTotalResponsePayloadLength(), locationEndpointsContacted: [...this.locationEndpointsContacted.values()], metadataDiagnostics: { metadataLookups: [...this.metadataLookups], }, retryDiagnostics: { failedAttempts: [...this.failedAttempts], }, gatewayStatistics: this.gatewayStatistics, encryptionDiagnostics: this.encryptionDiagnostics, }; } getTotalRequestPayloadLength() { let totalRequestPayloadLength = 0; this.gatewayStatistics.forEach((req) => (totalRequestPayloadLength += req.requestPayloadLengthInBytes)); this.metadataLookups.forEach((req) => (totalRequestPayloadLength += req.requestPayloadLengthInBytes)); this.failedAttempts.forEach((req) => (totalRequestPayloadLength += req.requestPayloadLengthInBytes)); return totalRequestPayloadLength; } getTotalResponsePayloadLength() { let totalResponsePayloadLength = 0; this.gatewayStatistics.forEach((req) => (totalResponsePayloadLength += req.responsePayloadLengthInBytes)); this.metadataLookups.forEach((req) => (totalResponsePayloadLength += req.responsePayloadLengthInBytes)); this.failedAttempts.forEach((req) => (totalResponsePayloadLength += req.responsePayloadLengthInBytes)); return totalResponsePayloadLength; } recordEndpointResolution(location) { this.locationEndpointsContacted.add(location); } } //# sourceMappingURL=CosmosDiagnosticsContext.js.map