UNPKG

mongodb-log-writer

Version:

A library for writing MongoDB logv2 messages

183 lines 5.47 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MongoLogWriter = void 0; exports.mongoLogId = mongoLogId; const bson_1 = require("bson"); const stream_1 = require("stream"); const util_1 = require("util"); const kFlushDummy = Symbol('kFlushDummy'); function mongoLogId(id) { return { __value: id }; } function validateLogEntry(info) { if (typeof info.s !== 'string') { return new TypeError('Cannot log messages without a severity field'); } if (typeof info.c !== 'string') { return new TypeError('Cannot log messages without a component field'); } if (typeof info.id?.__value !== 'number') { return new TypeError('Cannot log messages without an id field'); } if (typeof info.ctx !== 'string') { return new TypeError('Cannot log messages without a context field'); } if (typeof info.msg !== 'string') { return new TypeError('Cannot log messages without a message field'); } return null; } class MongoLogWriter extends stream_1.Writable { _logId; _logFilePath; _target; _now; constructor(logId, logFilePath, target, now) { super({ objectMode: true }); this._logId = logId; this._logFilePath = logFilePath; this._target = target; this._now = now ?? (() => new Date()); } get logId() { return this._logId; } get logFilePath() { return this._logFilePath; } get target() { return this._target; } _write(info, encoding, callback) { if (info === kFlushDummy) { this._target.write('', callback); return; } const validationError = validateLogEntry(info); if (validationError) { callback(validationError); return; } const fullInfo = { t: info.t ?? this._now(), s: info.s, c: info.c, id: info.id.__value, ctx: info.ctx, msg: info.msg, }; if (info.attr) { if (Object.prototype.toString.call(info.attr) === '[object Error]') { fullInfo.attr = { stack: info.attr.stack, name: info.attr.name, message: info.attr.message, code: info.attr.code, ...info.attr, }; } else { fullInfo.attr = info.attr; } } this.emit('log', fullInfo); try { bson_1.EJSON.stringify(fullInfo.attr); } catch { try { const v8 = require('v8'); const cloned = v8.deserialize(v8.serialize(fullInfo.attr)); bson_1.EJSON.stringify(cloned); fullInfo.attr = cloned; } catch { try { const cloned = JSON.parse(JSON.stringify(fullInfo.attr)); bson_1.EJSON.stringify(cloned); fullInfo.attr = cloned; } catch { fullInfo.attr = { _inspected: (0, util_1.inspect)(fullInfo.attr) }; } } } this._target.write(bson_1.EJSON.stringify(fullInfo, { relaxed: true }) + '\n', callback); } _final(callback) { this._target.end(callback); } async flush() { await new Promise((resolve) => this.write(kFlushDummy, resolve)); } info(component, id, context, message, attr) { const logEntry = { s: 'I', c: component, id: id, ctx: context, msg: message, attr: attr, }; this.write(logEntry); } warn(component, id, context, message, attr) { const logEntry = { s: 'W', c: component, id: id, ctx: context, msg: message, attr: attr, }; this.write(logEntry); } error(component, id, context, message, attr) { const logEntry = { s: 'E', c: component, id: id, ctx: context, msg: message, attr: attr, }; this.write(logEntry); } fatal(component, id, context, message, attr) { const logEntry = { s: 'F', c: component, id: id, ctx: context, msg: message, attr: attr, }; this.write(logEntry); } debug(component, id, context, message, attr, level = 1) { const logEntry = { s: `D${level}`, c: component, id: id, ctx: context, msg: message, attr: attr, }; this.write(logEntry); } bindComponent(component) { return { unbound: this, component: component, write: (entry, cb) => this.write({ c: component, ...entry }, cb), info: this.info.bind(this, component), warn: this.warn.bind(this, component), error: this.error.bind(this, component), fatal: this.fatal.bind(this, component), debug: this.debug.bind(this, component), }; } mongoLogId = mongoLogId; } exports.MongoLogWriter = MongoLogWriter; //# sourceMappingURL=mongo-log-writer.js.map