First commit
This commit is contained in:
360
node_modules/mongodb/lib/mongo_logger.js
generated
vendored
Normal file
360
node_modules/mongodb/lib/mongo_logger.js
generated
vendored
Normal file
@@ -0,0 +1,360 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.MongoLogger = exports.stringifyWithMaxLen = exports.createStdioLogger = exports.MongoLoggableComponent = exports.SEVERITY_LEVEL_MAP = exports.DEFAULT_MAX_DOCUMENT_LENGTH = exports.SeverityLevel = void 0;
|
||||
const bson_1 = require("bson");
|
||||
const util_1 = require("util");
|
||||
const constants_1 = require("./constants");
|
||||
const utils_1 = require("./utils");
|
||||
/** @internal */
|
||||
exports.SeverityLevel = Object.freeze({
|
||||
EMERGENCY: 'emergency',
|
||||
ALERT: 'alert',
|
||||
CRITICAL: 'critical',
|
||||
ERROR: 'error',
|
||||
WARNING: 'warn',
|
||||
NOTICE: 'notice',
|
||||
INFORMATIONAL: 'info',
|
||||
DEBUG: 'debug',
|
||||
TRACE: 'trace',
|
||||
OFF: 'off'
|
||||
});
|
||||
/** @internal */
|
||||
exports.DEFAULT_MAX_DOCUMENT_LENGTH = 1000;
|
||||
/** @internal */
|
||||
class SeverityLevelMap extends Map {
|
||||
constructor(entries) {
|
||||
const newEntries = [];
|
||||
for (const [level, value] of entries) {
|
||||
newEntries.push([value, level]);
|
||||
}
|
||||
newEntries.push(...entries);
|
||||
super(newEntries);
|
||||
}
|
||||
getNumericSeverityLevel(severity) {
|
||||
return this.get(severity);
|
||||
}
|
||||
getSeverityLevelName(level) {
|
||||
return this.get(level);
|
||||
}
|
||||
}
|
||||
/** @internal */
|
||||
exports.SEVERITY_LEVEL_MAP = new SeverityLevelMap([
|
||||
[exports.SeverityLevel.OFF, -Infinity],
|
||||
[exports.SeverityLevel.EMERGENCY, 0],
|
||||
[exports.SeverityLevel.ALERT, 1],
|
||||
[exports.SeverityLevel.CRITICAL, 2],
|
||||
[exports.SeverityLevel.ERROR, 3],
|
||||
[exports.SeverityLevel.WARNING, 4],
|
||||
[exports.SeverityLevel.NOTICE, 5],
|
||||
[exports.SeverityLevel.INFORMATIONAL, 6],
|
||||
[exports.SeverityLevel.DEBUG, 7],
|
||||
[exports.SeverityLevel.TRACE, 8]
|
||||
]);
|
||||
/** @internal */
|
||||
exports.MongoLoggableComponent = Object.freeze({
|
||||
COMMAND: 'command',
|
||||
TOPOLOGY: 'topology',
|
||||
SERVER_SELECTION: 'serverSelection',
|
||||
CONNECTION: 'connection'
|
||||
});
|
||||
/**
|
||||
* Parses a string as one of SeverityLevel
|
||||
*
|
||||
* @param s - the value to be parsed
|
||||
* @returns one of SeverityLevel if value can be parsed as such, otherwise null
|
||||
*/
|
||||
function parseSeverityFromString(s) {
|
||||
const validSeverities = Object.values(exports.SeverityLevel);
|
||||
const lowerSeverity = s?.toLowerCase();
|
||||
if (lowerSeverity != null && validSeverities.includes(lowerSeverity)) {
|
||||
return lowerSeverity;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/** @internal */
|
||||
function createStdioLogger(stream) {
|
||||
return {
|
||||
write: (log) => {
|
||||
stream.write((0, util_1.inspect)(log, { compact: true, breakLength: Infinity }), 'utf-8');
|
||||
return;
|
||||
}
|
||||
};
|
||||
}
|
||||
exports.createStdioLogger = createStdioLogger;
|
||||
/**
|
||||
* resolves the MONGODB_LOG_PATH and mongodbLogPath options from the environment and the
|
||||
* mongo client options respectively. The mongodbLogPath can be either 'stdout', 'stderr', a NodeJS
|
||||
* Writable or an object which has a `write` method with the signature:
|
||||
* ```ts
|
||||
* write(log: Log): void
|
||||
* ```
|
||||
*
|
||||
* @returns the MongoDBLogWritable object to write logs to
|
||||
*/
|
||||
function resolveLogPath({ MONGODB_LOG_PATH }, { mongodbLogPath }) {
|
||||
if (typeof mongodbLogPath === 'string' && /^stderr$/i.test(mongodbLogPath)) {
|
||||
return createStdioLogger(process.stderr);
|
||||
}
|
||||
if (typeof mongodbLogPath === 'string' && /^stdout$/i.test(mongodbLogPath)) {
|
||||
return createStdioLogger(process.stdout);
|
||||
}
|
||||
if (typeof mongodbLogPath === 'object' && typeof mongodbLogPath?.write === 'function') {
|
||||
return mongodbLogPath;
|
||||
}
|
||||
if (MONGODB_LOG_PATH && /^stderr$/i.test(MONGODB_LOG_PATH)) {
|
||||
return createStdioLogger(process.stderr);
|
||||
}
|
||||
if (MONGODB_LOG_PATH && /^stdout$/i.test(MONGODB_LOG_PATH)) {
|
||||
return createStdioLogger(process.stdout);
|
||||
}
|
||||
return createStdioLogger(process.stderr);
|
||||
}
|
||||
function compareSeverity(s0, s1) {
|
||||
const s0Num = exports.SEVERITY_LEVEL_MAP.getNumericSeverityLevel(s0);
|
||||
const s1Num = exports.SEVERITY_LEVEL_MAP.getNumericSeverityLevel(s1);
|
||||
return s0Num < s1Num ? -1 : s0Num > s1Num ? 1 : 0;
|
||||
}
|
||||
/** @internal */
|
||||
function stringifyWithMaxLen(value, maxDocumentLength) {
|
||||
const ejson = bson_1.EJSON.stringify(value);
|
||||
return maxDocumentLength !== 0 && ejson.length > maxDocumentLength
|
||||
? `${ejson.slice(0, maxDocumentLength)}...`
|
||||
: ejson;
|
||||
}
|
||||
exports.stringifyWithMaxLen = stringifyWithMaxLen;
|
||||
function isLogConvertible(obj) {
|
||||
const objAsLogConvertible = obj;
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
return objAsLogConvertible.toLog !== undefined && typeof objAsLogConvertible.toLog === 'function';
|
||||
}
|
||||
function attachCommandFields(log, commandEvent) {
|
||||
log.commandName = commandEvent.commandName;
|
||||
log.requestId = commandEvent.requestId;
|
||||
log.driverConnectionId = commandEvent?.connectionId;
|
||||
const { host, port } = utils_1.HostAddress.fromString(commandEvent.address).toHostPort();
|
||||
log.serverHost = host;
|
||||
log.serverPort = port;
|
||||
if (commandEvent?.serviceId) {
|
||||
log.serviceId = commandEvent.serviceId.toHexString();
|
||||
}
|
||||
return log;
|
||||
}
|
||||
function attachConnectionFields(log, connectionPoolEvent) {
|
||||
const { host, port } = utils_1.HostAddress.fromString(connectionPoolEvent.address).toHostPort();
|
||||
log.serverHost = host;
|
||||
log.serverPort = port;
|
||||
return log;
|
||||
}
|
||||
function defaultLogTransform(logObject, maxDocumentLength = exports.DEFAULT_MAX_DOCUMENT_LENGTH) {
|
||||
let log = Object.create(null);
|
||||
switch (logObject.name) {
|
||||
case constants_1.COMMAND_STARTED:
|
||||
log = attachCommandFields(log, logObject);
|
||||
log.message = 'Command started';
|
||||
log.command = stringifyWithMaxLen(logObject.command, maxDocumentLength);
|
||||
log.databaseName = logObject.databaseName;
|
||||
return log;
|
||||
case constants_1.COMMAND_SUCCEEDED:
|
||||
log = attachCommandFields(log, logObject);
|
||||
log.message = 'Command succeeded';
|
||||
log.durationMS = logObject.duration;
|
||||
log.reply = stringifyWithMaxLen(logObject.reply, maxDocumentLength);
|
||||
return log;
|
||||
case constants_1.COMMAND_FAILED:
|
||||
log = attachCommandFields(log, logObject);
|
||||
log.message = 'Command failed';
|
||||
log.durationMS = logObject.duration;
|
||||
log.failure = logObject.failure;
|
||||
return log;
|
||||
case constants_1.CONNECTION_POOL_CREATED:
|
||||
log = attachConnectionFields(log, logObject);
|
||||
log.message = 'Connection pool created';
|
||||
if (logObject.options) {
|
||||
const { maxIdleTimeMS, minPoolSize, maxPoolSize, maxConnecting, waitQueueTimeoutMS } = logObject.options;
|
||||
log = {
|
||||
...log,
|
||||
maxIdleTimeMS,
|
||||
minPoolSize,
|
||||
maxPoolSize,
|
||||
maxConnecting,
|
||||
waitQueueTimeoutMS
|
||||
};
|
||||
}
|
||||
return log;
|
||||
case constants_1.CONNECTION_POOL_READY:
|
||||
log = attachConnectionFields(log, logObject);
|
||||
log.message = 'Connection pool ready';
|
||||
return log;
|
||||
case constants_1.CONNECTION_POOL_CLEARED:
|
||||
log = attachConnectionFields(log, logObject);
|
||||
log.message = 'Connection pool cleared';
|
||||
if (logObject.serviceId?._bsontype === 'ObjectId') {
|
||||
log.serviceId = logObject.serviceId.toHexString();
|
||||
}
|
||||
return log;
|
||||
case constants_1.CONNECTION_POOL_CLOSED:
|
||||
log = attachConnectionFields(log, logObject);
|
||||
log.message = 'Connection pool closed';
|
||||
return log;
|
||||
case constants_1.CONNECTION_CREATED:
|
||||
log = attachConnectionFields(log, logObject);
|
||||
log.message = 'Connection created';
|
||||
log.driverConnectionId = logObject.connectionId;
|
||||
return log;
|
||||
case constants_1.CONNECTION_READY:
|
||||
log = attachConnectionFields(log, logObject);
|
||||
log.message = 'Connection ready';
|
||||
log.driverConnectionId = logObject.connectionId;
|
||||
return log;
|
||||
case constants_1.CONNECTION_CLOSED:
|
||||
log = attachConnectionFields(log, logObject);
|
||||
log.message = 'Connection closed';
|
||||
log.driverConnectionId = logObject.connectionId;
|
||||
switch (logObject.reason) {
|
||||
case 'stale':
|
||||
log.reason = 'Connection became stale because the pool was cleared';
|
||||
break;
|
||||
case 'idle':
|
||||
log.reason =
|
||||
'Connection has been available but unused for longer than the configured max idle time';
|
||||
break;
|
||||
case 'error':
|
||||
log.reason = 'An error occurred while using the connection';
|
||||
if (logObject.error) {
|
||||
log.error = logObject.error;
|
||||
}
|
||||
break;
|
||||
case 'poolClosed':
|
||||
log.reason = 'Connection pool was closed';
|
||||
break;
|
||||
default:
|
||||
log.reason = `Unknown close reason: ${logObject.reason}`;
|
||||
}
|
||||
return log;
|
||||
case constants_1.CONNECTION_CHECK_OUT_STARTED:
|
||||
log = attachConnectionFields(log, logObject);
|
||||
log.message = 'Connection checkout started';
|
||||
return log;
|
||||
case constants_1.CONNECTION_CHECK_OUT_FAILED:
|
||||
log = attachConnectionFields(log, logObject);
|
||||
log.message = 'Connection checkout failed';
|
||||
switch (logObject.reason) {
|
||||
case 'poolClosed':
|
||||
log.reason = 'Connection pool was closed';
|
||||
break;
|
||||
case 'timeout':
|
||||
log.reason = 'Wait queue timeout elapsed without a connection becoming available';
|
||||
break;
|
||||
case 'connectionError':
|
||||
log.reason = 'An error occurred while trying to establish a new connection';
|
||||
if (logObject.error) {
|
||||
log.error = logObject.error;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
log.reason = `Unknown close reason: ${logObject.reason}`;
|
||||
}
|
||||
return log;
|
||||
case constants_1.CONNECTION_CHECKED_OUT:
|
||||
log = attachConnectionFields(log, logObject);
|
||||
log.message = 'Connection checked out';
|
||||
log.driverConnectionId = logObject.connectionId;
|
||||
return log;
|
||||
case constants_1.CONNECTION_CHECKED_IN:
|
||||
log = attachConnectionFields(log, logObject);
|
||||
log.message = 'Connection checked in';
|
||||
log.driverConnectionId = logObject.connectionId;
|
||||
return log;
|
||||
default:
|
||||
for (const [key, value] of Object.entries(logObject)) {
|
||||
if (value != null)
|
||||
log[key] = value;
|
||||
}
|
||||
}
|
||||
return log;
|
||||
}
|
||||
/** @internal */
|
||||
class MongoLogger {
|
||||
constructor(options) {
|
||||
/**
|
||||
* This method should be used when logging errors that do not have a public driver API for
|
||||
* reporting errors.
|
||||
*/
|
||||
this.error = this.log.bind(this, 'error');
|
||||
/**
|
||||
* This method should be used to log situations where undesirable application behaviour might
|
||||
* occur. For example, failing to end sessions on `MongoClient.close`.
|
||||
*/
|
||||
this.warn = this.log.bind(this, 'warn');
|
||||
/**
|
||||
* This method should be used to report high-level information about normal driver behaviour.
|
||||
* For example, the creation of a `MongoClient`.
|
||||
*/
|
||||
this.info = this.log.bind(this, 'info');
|
||||
/**
|
||||
* This method should be used to report information that would be helpful when debugging an
|
||||
* application. For example, a command starting, succeeding or failing.
|
||||
*/
|
||||
this.debug = this.log.bind(this, 'debug');
|
||||
/**
|
||||
* This method should be used to report fine-grained details related to logic flow. For example,
|
||||
* entering and exiting a function body.
|
||||
*/
|
||||
this.trace = this.log.bind(this, 'trace');
|
||||
this.componentSeverities = options.componentSeverities;
|
||||
this.maxDocumentLength = options.maxDocumentLength;
|
||||
this.logDestination = options.logDestination;
|
||||
}
|
||||
log(severity, component, message) {
|
||||
if (compareSeverity(severity, this.componentSeverities[component]) > 0)
|
||||
return;
|
||||
let logMessage = { t: new Date(), c: component, s: severity };
|
||||
if (typeof message === 'string') {
|
||||
logMessage.message = message;
|
||||
}
|
||||
else if (typeof message === 'object') {
|
||||
if (isLogConvertible(message)) {
|
||||
logMessage = { ...logMessage, ...message.toLog() };
|
||||
}
|
||||
else {
|
||||
logMessage = { ...logMessage, ...defaultLogTransform(message, this.maxDocumentLength) };
|
||||
}
|
||||
}
|
||||
this.logDestination.write(logMessage);
|
||||
}
|
||||
/**
|
||||
* Merges options set through environment variables and the MongoClient, preferring environment
|
||||
* variables when both are set, and substituting defaults for values not set. Options set in
|
||||
* constructor take precedence over both environment variables and MongoClient options.
|
||||
*
|
||||
* @remarks
|
||||
* When parsing component severity levels, invalid values are treated as unset and replaced with
|
||||
* the default severity.
|
||||
*
|
||||
* @param envOptions - options set for the logger from the environment
|
||||
* @param clientOptions - options set for the logger in the MongoClient options
|
||||
* @returns a MongoLoggerOptions object to be used when instantiating a new MongoLogger
|
||||
*/
|
||||
static resolveOptions(envOptions, clientOptions) {
|
||||
// client options take precedence over env options
|
||||
const combinedOptions = {
|
||||
...envOptions,
|
||||
...clientOptions,
|
||||
mongodbLogPath: resolveLogPath(envOptions, clientOptions)
|
||||
};
|
||||
const defaultSeverity = parseSeverityFromString(combinedOptions.MONGODB_LOG_ALL) ?? exports.SeverityLevel.OFF;
|
||||
return {
|
||||
componentSeverities: {
|
||||
command: parseSeverityFromString(combinedOptions.MONGODB_LOG_COMMAND) ?? defaultSeverity,
|
||||
topology: parseSeverityFromString(combinedOptions.MONGODB_LOG_TOPOLOGY) ?? defaultSeverity,
|
||||
serverSelection: parseSeverityFromString(combinedOptions.MONGODB_LOG_SERVER_SELECTION) ?? defaultSeverity,
|
||||
connection: parseSeverityFromString(combinedOptions.MONGODB_LOG_CONNECTION) ?? defaultSeverity,
|
||||
default: defaultSeverity
|
||||
},
|
||||
maxDocumentLength: (0, utils_1.parseUnsignedInteger)(combinedOptions.MONGODB_LOG_MAX_DOCUMENT_LENGTH) ?? 1000,
|
||||
logDestination: combinedOptions.mongodbLogPath
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.MongoLogger = MongoLogger;
|
||||
//# sourceMappingURL=mongo_logger.js.map
|
Reference in New Issue
Block a user