mongodb-log-writer
Version:
A library for writing MongoDB logv2 messages
183 lines • 5.47 kB
JavaScript
;
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