Skip to content

Instantly share code, notes, and snippets.

@ManotLuijiu
Created June 6, 2021 22:07
Show Gist options
  • Select an option

  • Save ManotLuijiu/5e6cf551dc1506fc878f7697bf2fe582 to your computer and use it in GitHub Desktop.

Select an option

Save ManotLuijiu/5e6cf551dc1506fc878f7697bf2fe582 to your computer and use it in GitHub Desktop.
Log node.js project with winston and morgan
const winston = require('winston');
require('winston-daily-rotate-file');
const path = require('path');
const PROJECT_ROOT = path.join(__dirname, '..');
const highlight = require('cli-highlight').highlight;
// const options = {
// file: {
// level: 'info',
// filename: `${PROJECT_ROOT}/logs/app.log`,
// handleExceptions: true,
// json: true,
// maxSize: 5242880, // 5MB
// maxFiles: 5,
// colorize: false,
// },
// errorFile: {
// level: 'error',
// filename: `${PROJECT_ROOT}/logs/error.log`,
// handleExceptions: true,
// json: true,
// maxSize: 5242880, // 5MB
// maxFiles: 5,
// colorize: false,
// },
// console: {
// level: 'debug',
// handleExceptions: true,
// json: false,
// colorize: true,
// },
// };
const logger = winston.createLogger({
transports: [
new winston.transports.DailyRotateFile({
filename: `${PROJECT_ROOT}/logs/nodejs-guide-%DATE%.log`,
datePattern: 'YYYY-MM-DD',
zippedArchive: true,
maxSize: '20m',
maxFiles: '14d',
}),
new winston.transports.File({
level: 'info',
filename: `${PROJECT_ROOT}/logs/server.log`,
handleExceptions: true,
json: true,
maxSize: 5242880, // 5MB
maxFiles: 5,
colorize: true,
}),
new winston.transports.File({
level: 'error',
filename: `${PROJECT_ROOT}/logs/errors.log`,
handleExceptions: true,
json: true,
maxSize: 5242880, // 5MB
maxFiles: 5,
colorize: true,
}),
new winston.transports.Console({
level: 'debug',
handleExceptions: true,
json: false,
colorize: true,
}),
],
exitOnError: false,
});
logger.stream = {
write: function (message) {
logger.info(message);
},
};
module.exports.debug = module.exports.log = function () {
logger.debug.apply(logger, formatLogArguments(arguments));
};
module.exports.info = function () {
logger.info.apply(logger, formatLogArguments(arguments));
};
module.exports.warn = function () {
logger.warn.apply(logger, formatLogArguments(arguments));
};
module.exports.error = function () {
logger.error.apply(logger, formatLogArguments(arguments));
};
module.exports.stream = logger.stream;
/**
* Attempts to add file and line number info to the given log arguments.
* @param {*} args
*/
function formatLogArguments(args) {
args = Array.prototype.slice.call(args);
// console.log('args', args);
const stackInfo = getStackInfo(1);
if (stackInfo) {
// get file path relative to project root
// const calleeStr = '(' + stackInfo.relativePath + ':' + stackInfo.line + ')';
const calleeStr = `(${stackInfo.relativePath}:${stackInfo.line})`;
// console.log(calleeStr);
const calleeStrHl = highlight(calleeStr);
// console.log(calleeStrHl);
if (typeof args[0] === 'string') {
console.log(calleeStrHl);
// args[0] = calleeStr + ' ' + args[0];
args[0] = `log => ${args[0]}`;
} else {
console.log(calleeStrHl);
console.log(JSON.stringify(args, null, 2));
args.unshift(calleeStr);
}
}
return args;
}
/**
* Parses and returns info about the call stack at the given index.
*/
function getStackInfo(stackIndex) {
// get call stack, and analyze it
// get all file, method, and line numbers
const stacklist = new Error().stack.split('\n').slice(3);
// stack trace format:
// http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
// do not remove the regex expresses to outside of this method (due to a BUG in node.js)
const stackReg = /at\s+(.*)\s+\((.*):(\d*):(\d*)\)/gi;
const stackReg2 = /at\s+()(.*):(\d*):(\d*)/gi;
const s = stacklist[stackIndex] || stacklist[0];
const sp = stackReg.exec(s) || stackReg2.exec(s);
if (sp && sp.length === 5) {
return {
method: sp[1],
relativePath: path.relative(PROJECT_ROOT, sp[2]),
line: sp[3],
pos: sp[4],
file: path.basename(sp[2]),
stack: stacklist.join('\n'),
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment