@brainbits/node-logger-formatter-monolog
Version:
Logger for node projects
128 lines (121 loc) • 3.41 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = monolog;
var _jestGetType = require("jest-get-type");
var _dateFns = require("date-fns");
/**
* @description Get current timestamp
* @param {any} [timestampFormat=TIMESTAMP_FORMAT]
* @returns {string} Current timestamp in given format
*/
function timestamp(timestampFormat) {
return (0, _dateFns.format)(new Date(), timestampFormat);
}
/**
* @description Checks if the object is non empty or has undefined properties
* @export
* @param {any} object
* @returns {boolean} Returns true if the object is not empty
*/
function isNonEmptyObject(object) {
return typeof object === 'object' && Object.values(object).filter(entry => entry !== undefined).length > 0;
}
/**
* @description Make a string of an non empty object or return ‘[]' as a string
* @param {object} object
* @returns {string} The result as a string
*/
function stringifyExtras(object) {
return isNonEmptyObject(object) ? JSON.stringify(object) : '[]';
}
/**
* @description parse message of an error or object
* @param {object} object Object to parse
* @returns {object} An object with message, context and extras
*/
function parseObject({
message,
context,
name,
stack = [],
...extras
}) {
let stackTrace = stack;
let contextObject = context;
if (!Array.isArray(stackTrace)) {
stackTrace = stackTrace.split('\n').map(line => line.trim()).filter(line => !!line);
}
if (stackTrace.length) {
const linesToCut = 11;
const truncatedLines = stackTrace.length - linesToCut;
stackTrace = stackTrace.slice(1, linesToCut);
if (truncatedLines > 0) {
stackTrace.push(`${truncatedLines} more line${truncatedLines <= 1 ? '' : 's'} ...`);
}
contextObject = {
...contextObject,
stackTrace
};
}
return {
message: name ? `${name} - ${message || '-'}` : message,
context: contextObject,
extras
};
}
/**
* @description Generate the monolog string
* @param {string} channel Channel of the node-logger
* @param {string} level Level of the node-logger
* @param {object} logData Data from our object with message, context and extras
* @param {object} meta Some meta information for context
* @returns {string} Monolog string
*/
function formatMonologMessage(channel, level, logData, meta = {}) {
const formatString = 'yyyy-MM-dd HH:mm:ss';
const context = stringifyExtras({
...logData.context,
...meta
});
const extras = stringifyExtras(logData.extras);
// Monolog formatString: "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"
return `[${timestamp(formatString)}] ${channel}.${level.toUpperCase()}: ${logData.message || '-'} ${context} ${extras}`;
}
/**
* @description Formatter function
* @export
* @param {object} event
* @returns {function} formatter function for node-logger
*/
function monolog({
channel,
level,
message,
meta
}) {
let logData = {
message: null,
context: [],
extra: []
};
switch ((0, _jestGetType.getType)(message)) {
case 'object':
logData = parseObject(message);
break;
case 'array':
logData = {
...logData,
message: message.join(' ')
};
break;
default:
logData = {
...logData,
message
};
break;
}
return formatMonologMessage(channel, level, logData, meta);
}