@azure/cosmos
Version:
Microsoft Azure Cosmos DB Service Node.js SDK for NOSQL API
335 lines (334 loc) • 13.2 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var DiagnosticNodeInternal_exports = {};
__export(DiagnosticNodeInternal_exports, {
DiagnosticNodeInternal: () => DiagnosticNodeInternal,
DiagnosticNodeType: () => DiagnosticNodeType
});
module.exports = __toCommonJS(DiagnosticNodeInternal_exports);
var import_CosmosDiagnosticsContext = require("./CosmosDiagnosticsContext.js");
var import_request = require("../request/index.js");
var import_CosmosDiagnostics = require("../CosmosDiagnostics.js");
var import_time = require("../utils/time.js");
var import_CosmosDbDiagnosticLevel = require("./CosmosDbDiagnosticLevel.js");
var import_common = require("../common/index.js");
var import_diagnosticLevelComparator = require("./diagnosticLevelComparator.js");
var import_core_util = require("@azure/core-util");
class DiagnosticNodeInternal {
id;
nodeType;
parent;
children;
data;
startTimeUTCInMs;
durationInMs;
diagnosticLevel;
diagnosticCtx;
encryptionDiagnostics;
/**
* @internal
*/
constructor(diagnosticLevel, type, parent, data = {}, startTimeUTCInMs = (0, import_time.getCurrentTimestampInMs)(), ctx = new import_CosmosDiagnosticsContext.CosmosDiagnosticContext()) {
this.id = (0, import_core_util.randomUUID)();
this.nodeType = type;
this.startTimeUTCInMs = startTimeUTCInMs;
this.data = data;
this.children = [];
this.durationInMs = 0;
this.parent = parent;
this.diagnosticCtx = ctx;
this.diagnosticLevel = diagnosticLevel;
this.encryptionDiagnostics = {
encryptContent: {},
decryptContent: {},
processingDurationInMs: 0
};
}
/**
* @internal
*/
addLog(msg) {
if (!this.data.log) {
this.data.log = [];
}
this.data.log.push(msg);
}
/**
* @internal
*/
sanitizeHeaders(headers) {
return headers;
}
/**
* Updated durationInMs for node, based on endTimeUTCInMs provided.
* @internal
*/
updateTimestamp(endTimeUTCInMs = (0, import_time.getCurrentTimestampInMs)()) {
this.durationInMs = endTimeUTCInMs - this.startTimeUTCInMs;
}
/**
* @internal
*/
recordSuccessfulNetworkCall(startTimeUTCInMs, requestContext, pipelineResponse, substatus, url) {
const responseHeaders = pipelineResponse.headers.toJSON();
const gatewayRequest = {
activityId: responseHeaders[import_common.Constants.HttpHeaders.ActivityId],
correlateActivityId: requestContext.headers[import_common.Constants.HttpHeaders.CorrelatedActivityId],
startTimeUTCInMs,
durationInMs: (0, import_time.getCurrentTimestampInMs)() - startTimeUTCInMs,
statusCode: pipelineResponse.status,
subStatusCode: substatus,
requestPayloadLengthInBytes: calculateRequestPayloadLength(requestContext),
responsePayloadLengthInBytes: calculateResponsePayloadLength(pipelineResponse),
operationType: requestContext.operationType,
resourceType: requestContext.resourceType,
partitionKeyRangeId: requestContext.partitionKeyRangeId
};
let requestData = {
OperationType: gatewayRequest.operationType,
resourceType: gatewayRequest.resourceType,
requestPayloadLengthInBytes: gatewayRequest.requestPayloadLengthInBytes
};
if ((0, import_diagnosticLevelComparator.allowTracing)(import_CosmosDbDiagnosticLevel.CosmosDbDiagnosticLevel.debugUnsafe, this.diagnosticLevel)) {
requestData = {
...requestData,
headers: this.sanitizeHeaders(requestContext.headers),
requestBody: requestContext.body,
responseBody: pipelineResponse.bodyAsText,
url
};
}
this.addData({
requestPayloadLengthInBytes: gatewayRequest.requestPayloadLengthInBytes,
responsePayloadLengthInBytes: gatewayRequest.responsePayloadLengthInBytes,
startTimeUTCInMs: gatewayRequest.startTimeUTCInMs,
durationInMs: gatewayRequest.durationInMs,
requestData
});
this.diagnosticCtx.recordNetworkCall(gatewayRequest);
}
/**
* @internal
*/
recordFailedNetworkCall(startTimeUTCInMs, requestContext, retryAttemptNumber, statusCode, substatusCode, responseHeaders) {
this.addData({ failedAttempty: true });
const requestPayloadLengthInBytes = calculateRequestPayloadLength(requestContext);
this.diagnosticCtx.recordFailedAttempt(
{
activityId: responseHeaders[import_common.Constants.HttpHeaders.ActivityId],
correlatedActivityId: requestContext.headers[import_common.Constants.HttpHeaders.CorrelatedActivityId],
startTimeUTCInMs,
durationInMs: (0, import_time.getCurrentTimestampInMs)() - startTimeUTCInMs,
statusCode,
subStatusCode: substatusCode,
requestPayloadLengthInBytes,
responsePayloadLengthInBytes: 0,
operationType: requestContext.operationType,
resourceType: requestContext.resourceType
},
retryAttemptNumber
);
let requestData = {
OperationType: requestContext.operationType,
resourceType: requestContext.resourceType,
requestPayloadLengthInBytes
};
if ((0, import_diagnosticLevelComparator.allowTracing)(import_CosmosDbDiagnosticLevel.CosmosDbDiagnosticLevel.debugUnsafe, this.diagnosticLevel)) {
requestData = {
...requestData,
headers: this.sanitizeHeaders(requestContext.headers),
requestBody: requestContext.body,
url: (0, import_common.prepareURL)(requestContext.endpoint, requestContext.path)
};
}
this.addData({
failedAttempty: true,
requestData
});
}
/**
* @internal
*/
recordEndpointResolution(location) {
this.addData({ selectedLocation: location });
this.diagnosticCtx.recordEndpointResolution(location);
}
/**
* @internal
*/
addData(data, msg, level = this.diagnosticLevel) {
if (level !== import_CosmosDbDiagnosticLevel.CosmosDbDiagnosticLevel.info) {
this.data = { ...this.data, ...data };
if (msg) {
this.addLog(msg);
}
}
}
/**
* Merge given DiagnosticNodeInternal's context to current node's DiagnosticContext, Treating GatewayRequests of
* given DiagnosticContext, as metadata requests. Given DiagnosticNodeInternal becomes a child of this node.
* @internal
*/
addChildNode(child, level, metadataType) {
this.diagnosticCtx.mergeDiagnostics(child.diagnosticCtx, metadataType);
if ((0, import_diagnosticLevelComparator.allowTracing)(level, this.diagnosticLevel)) {
child.parent = this;
this.children.push(child);
}
return child;
}
/**
* Merge given DiagnosticNodeInternal's context to current node's DiagnosticContext for bulk.
* Given DiagnosticNodeInternal becomes a child of this node.
* @internal
*/
addBulkChildNode(child, level) {
this.diagnosticCtx.mergeBulkDiagnostics(child.diagnosticCtx);
if ((0, import_diagnosticLevelComparator.allowTracing)(level, this.diagnosticLevel)) {
child.parent = this;
this.children.push(child);
}
return child;
}
/**
* @internal
*/
initializeChildNode(type, level, data = {}) {
if ((0, import_diagnosticLevelComparator.allowTracing)(level, this.diagnosticLevel)) {
const child = new DiagnosticNodeInternal(
this.diagnosticLevel,
type,
this,
data,
(0, import_time.getCurrentTimestampInMs)(),
this.diagnosticCtx
);
this.children.push(child);
return child;
} else {
return this;
}
}
/**
* @internal
*/
recordQueryResult(resources, level) {
if ((0, import_diagnosticLevelComparator.allowTracing)(level, this.diagnosticLevel)) {
const previousCount = this.data.queryRecordsRead ?? 0;
if (Array.isArray(resources)) {
this.data.queryRecordsRead = previousCount + resources.length;
}
}
}
/**
* @internal
* record startTime for encryption in an operation
*/
beginEncryptionDiagnostics(operation) {
const startTime = (0, import_time.getCurrentTimestampInMs)();
switch (operation) {
case import_common.Constants.Encryption.DiagnosticsEncryptOperation:
this.encryptionDiagnostics.encryptContent[import_common.Constants.Encryption.DiagnosticsStartTime] = startTime;
break;
case import_common.Constants.Encryption.DiagnosticsDecryptOperation:
this.encryptionDiagnostics.decryptContent[import_common.Constants.Encryption.DiagnosticsStartTime] = startTime;
break;
default:
throw new import_request.ErrorResponse("Invalid operation type for encryption diagnostics");
}
}
/**
* @internal
* record duration from startTime and properties count for encryption in an operation
*/
endEncryptionDiagnostics(operation, propertiesCount) {
const endTime = (0, import_time.getCurrentTimestampInMs)();
let processingDuration = 0;
switch (operation) {
case import_common.Constants.Encryption.DiagnosticsEncryptOperation:
processingDuration = endTime - this.encryptionDiagnostics.encryptContent[import_common.Constants.Encryption.DiagnosticsStartTime];
this.encryptionDiagnostics.encryptContent[import_common.Constants.Encryption.DiagnosticsDuration] = processingDuration;
if (propertiesCount !== void 0) {
this.encryptionDiagnostics.encryptContent[import_common.Constants.Encryption.DiagnosticsPropertiesEncryptedCount] = propertiesCount;
}
break;
case import_common.Constants.Encryption.DiagnosticsDecryptOperation:
processingDuration = endTime - this.encryptionDiagnostics.decryptContent[import_common.Constants.Encryption.DiagnosticsStartTime];
this.encryptionDiagnostics.decryptContent[import_common.Constants.Encryption.DiagnosticsDuration] = processingDuration;
if (propertiesCount !== void 0) {
this.encryptionDiagnostics.decryptContent[import_common.Constants.Encryption.DiagnosticsPropertiesDecryptedCount] = propertiesCount;
}
break;
default:
throw new import_request.ErrorResponse("Invalid operation type for encryption diagnostics");
}
this.diagnosticCtx.recordEncryptionDiagnostics(this.encryptionDiagnostics);
}
/**
* Convert DiagnosticNodeInternal (internal representation) to DiagnosticNode (public, sanitized representation)
* @internal
*/
toDiagnosticNode() {
return {
id: this.id,
nodeType: this.nodeType,
children: this.children.map((child) => child.toDiagnosticNode()),
data: this.data,
startTimeUTCInMs: this.startTimeUTCInMs,
durationInMs: this.durationInMs
};
}
/**
* Convert to CosmosDiagnostics
* @internal
*/
toDiagnostic(clientConfigDiagnostic) {
const rootNode = (0, import_CosmosDiagnostics.getRootNode)(this);
const diagnostiNode = (0, import_diagnosticLevelComparator.allowTracing)(import_CosmosDbDiagnosticLevel.CosmosDbDiagnosticLevel.debug, this.diagnosticLevel) ? rootNode.toDiagnosticNode() : void 0;
const clientConfig = (0, import_diagnosticLevelComparator.allowTracing)(import_CosmosDbDiagnosticLevel.CosmosDbDiagnosticLevel.debug, this.diagnosticLevel) ? clientConfigDiagnostic : void 0;
const cosmosDiagnostic = new import_CosmosDiagnostics.CosmosDiagnostics(
this.diagnosticCtx.getClientSideStats(),
diagnostiNode,
clientConfig
);
return cosmosDiagnostic;
}
}
var DiagnosticNodeType = /* @__PURE__ */ ((DiagnosticNodeType2) => {
DiagnosticNodeType2["CLIENT_REQUEST_NODE"] = "CLIENT_REQUEST_NODE";
DiagnosticNodeType2["METADATA_REQUEST_NODE"] = "METADATA_REQUEST_NODE";
DiagnosticNodeType2["HTTP_REQUEST"] = "HTTP_REQUEST";
DiagnosticNodeType2["BATCH_REQUEST"] = "BATCH_REQUEST";
DiagnosticNodeType2["PARALLEL_QUERY_NODE"] = "PARALLEL_QUERY_NODE";
DiagnosticNodeType2["DEFAULT_QUERY_NODE"] = "DEFAULT_QUERY_NODE";
DiagnosticNodeType2["QUERY_REPAIR_NODE"] = "QUERY_REPAIR_NODE";
DiagnosticNodeType2["BACKGROUND_REFRESH_THREAD"] = "BACKGROUND_REFRESH_THREAD";
DiagnosticNodeType2["REQUEST_ATTEMPTS"] = "REQUEST_ATTEMPTS";
return DiagnosticNodeType2;
})(DiagnosticNodeType || {});
function calculateResponsePayloadLength(response) {
return response?.bodyAsText?.length || 0;
}
function calculateRequestPayloadLength(requestContext) {
return requestContext.body ? requestContext.body.length : 0;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
DiagnosticNodeInternal,
DiagnosticNodeType
});