Last active
November 20, 2021 19:53
-
-
Save akirattii/08375d495b8e45d6ff5fb98fc4de7f7d to your computer and use it in GitHub Desktop.
NodeJS: A simple winston logger wrapper, which is the daily logging rotation (even hourly, minutely and secondly rotation) available.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* A logger module, which is a simple `winston`(v3) wrapper. | |
* @version 1.0.1 | |
* lastUpdated: 2019-02-13 | |
* | |
* # Usage: | |
* ```js | |
* const logCfg = { | |
* // Label name. It's up to you: | |
* "label": "server", | |
* // Logging level: | |
* "level": "error", | |
* "filename": "./log/web-prod.log", | |
* // whether outputs logs on console or not: | |
* "useConsole": false, | |
* // max logfile size: | |
* "maxSize": "10m", | |
* // max logfile count to be remained: | |
* "maxFiles": 7, // The latest 7 files will be kept. | |
* // Date pattern. It uses `moment` date format: http://momentjs.com/docs/#/displaying/format/ | |
* // NOTE: If you want to rotate logs hourly, set "YYYY-MM-DD-HH": | |
* "datePattern": "YYYY-MM-DD", | |
* }; | |
* const Logger = require("./Logger.js"); // "./Logger.js" is this js file. | |
* const logger = Logger.getLogger(logCfg); | |
* | |
* logger.info("Hello: %s", "Akira"); | |
* logger.warn("Age: %d", 99); | |
* logger.debug("Item: %o", { aaa: 123 }); | |
* logger.error("Oops! %o", Error("OOPS!")); | |
* ``` | |
*/ | |
const winston = require("winston"); | |
const DailyRotateFile = require('winston-daily-rotate-file'); | |
/** | |
* Get a logger instance. | |
* | |
* @param label {String} - Defaults to "default" | |
* @param level {String} - log level. Defaults to "info" | |
* LogLevels: { | |
* error: 0, | |
* warn: 1, | |
* info: 2, | |
* verbose: 3, | |
* debug: 4, | |
* silly: 5 | |
* } | |
* @param filename {String} - log file path. Defaults to "./log/app.log" | |
* @param useConsole {Boolean} - whether logs output to console or not. Defaults to false. | |
* @param maxSize {Number} - max file size. Defaults to "10m" (10MB). | |
* @param maxFiles {Number} - max files count to be kept. Defaults to 7. | |
* @param datePattern {Boolean} - moment date form. Defaults to "YYYY-MM-DD". | |
* See: http://momentjs.com/docs/#/displaying/format/ | |
*/ | |
module.exports.getLogger = function(p) { | |
// Set the setting: | |
const label = (p && p.label) ? p.label : "default"; | |
const level = (p && p.level) ? p.level : "info"; | |
const filename = (p && p.filename) ? p.filename : "./log/app.log"; | |
const useConsole = (p && p.useConsole) ? p.useConsole : false; // whether uses Console transport or not | |
const maxSize = (p && p.maxSize) ? p.maxSize : "10m"; // 10MB | |
const maxFiles = (p && p.maxFiles) ? p.maxFiles : 7; // 7 files will be kept | |
const datePattern = (p && p.datePattern) ? p.datePattern : "YYYY-MM-DD"; // moment date format: http://momentjs.com/docs/#/displaying/format/ | |
// | |
// Create transports | |
// | |
const transports = []; | |
// [DailyRotateFile] transport: | |
transports.push(new DailyRotateFile({ | |
filename, | |
level, | |
zippedArchive: true, | |
maxSize, | |
maxFiles, | |
datePattern, | |
})); | |
// // [File] transport: | |
// transports.push(new winston.transports.File({ | |
// filename, | |
// level, | |
// maxsize: maxSize, | |
// })); | |
// [Console] transport: | |
if (useConsole && process.env.NODE_ENV !== "production") { | |
transports.push(new winston.transports.Console({ | |
level, | |
})); | |
} | |
// | |
// Create my format | |
// | |
const myFormat = winston.format.printf(({ level, message, label, timestamp }) => { | |
const logmsg = `${timestamp} [${label}] ${level.toUpperCase()}: ${message}`; | |
if (!useConsole) return logmsg; | |
return colorize(logmsg, level); | |
}); | |
// | |
// Create a logger instance | |
// | |
const logger = winston.createLogger({ | |
format: winston.format.combine( | |
winston.format.splat(), | |
winston.format.label({ label }), | |
winston.format.timestamp(), | |
myFormat | |
), | |
transports, | |
}); | |
return logger; | |
}; | |
/* COLOR CODES */ | |
const COLOR_CODES = { | |
Reset: "\x1b[0m", | |
Bright: "\x1b[1m", | |
Dim: "\x1b[2m", | |
Underscore: "\x1b[4m", | |
Blink: "\x1b[5m", | |
Reverse: "\x1b[7m", | |
Hidden: "\x1b[8m", | |
FgBlack: "\x1b[30m", | |
FgRed: "\x1b[31m", | |
FgGreen: "\x1b[32m", | |
FgYellow: "\x1b[33m", | |
FgBlue: "\x1b[34m", | |
FgMagenta: "\x1b[35m", | |
FgCyan: "\x1b[36m", | |
FgWhite: "\x1b[37m", | |
BgBlack: "\x1b[40m", | |
BgRed: "\x1b[41m", | |
BgGreen: "\x1b[42m", | |
BgYellow: "\x1b[43m", | |
BgBlue: "\x1b[44m", | |
BgMagenta: "\x1b[45m", | |
BgCyan: "\x1b[46m", | |
BgWhite: "\x1b[47m", | |
}; | |
function colorize(msg, level = "info") { | |
level = level.toLowerCase(); | |
let colorCode = COLOR_CODES.FgGreen; | |
if (level === "error") { | |
colorCode = COLOR_CODES.FgRed; | |
} else if (level === "warn") { | |
colorCode = COLOR_CODES.FgYellow; | |
} else if (level === "debug") { | |
colorCode = COLOR_CODES.FgCyan; | |
} else if (level === "info") { | |
colorCode = COLOR_CODES.FgGreen; | |
} | |
return `${colorCode}${msg}${COLOR_CODES.Reset}`; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment