Skip to content

Instantly share code, notes, and snippets.

@SrejonKhan
Created March 8, 2024 13:40
Show Gist options
  • Save SrejonKhan/78700d914a36ea7bd689cb3fe40e7e93 to your computer and use it in GitHub Desktop.
Save SrejonKhan/78700d914a36ea7bd689cb3fe40e7e93 to your computer and use it in GitHub Desktop.
Winston Logger for General Purpose Logging (Overriding Console API), API Access Logging (WinstonExpress), API Error Logging (WinstonExpress) and Morgan Implementation to Winston Stream. ELK can be easily implemented.
const winston = require("winston");
const expressWinston = require("express-winston");
const config = require("./base");
/*-------------------GENERAL LOGGER-------------------*/
const generalLogger = winston.createLogger({
exitOnError: false,
format: winston.format.combine(winston.format.timestamp(), winston.format.json()),
transports: [
new winston.transports.File({ filename: "logs/error.log", level: "error" }),
new winston.transports.File({ filename: "logs/combined.log" }),
],
exceptionHandlers: [new winston.transports.File({ filename: "logs/uncaught_exceptions.log" })],
});
/*-------------------DEVELOPMENT LOGGER-------------------*/
const devLogger = winston.createLogger({
exitOnError: false,
format: winston.format.combine(winston.format.colorize(), winston.format.simple()),
transports: [new winston.transports.Console()],
});
devLogger.stream = {
write: function (message, encoding) {
devLogger.info(message);
},
};
if (config.ENV === "DEVELOPMENT") {
devLogger.exceptions.handle(new winston.transports.Console());
}
/*-------------------API ACCESS LOGGER-------------------*/
const accessLoggerWinston = winston.createLogger({
format: winston.format.combine(winston.format.timestamp(), winston.format.json()),
transports: [new winston.transports.File({ filename: "logs/api_access.log" })],
});
// enable detailed API logging in dev env
if (config.ENV === "DEVELOPMENT") {
expressWinston.requestWhitelist.push("body");
expressWinston.responseWhitelist.push("body");
}
const apiAccessLogger = expressWinston.logger({
winstonInstance: accessLoggerWinston,
meta: true,
msg: "HTTP {{res.statusCode}} {{req.method}} {{res.responseTime}}ms {{req.url}}",
expressFormat: false,
colorize: false,
});
/*-------------------API ERROR LOGGER-------------------*/
const apiErrorLogger = expressWinston.errorLogger({
format: winston.format.combine(winston.format.timestamp(), winston.format.json()),
transports: [new winston.transports.File({ json: true, filename: "logs/api_error.log", level: "error" })],
});
/*-------------------OVERRIDING CONSOLE API FOR LOGGING-------------------*/
const isProd = config.ENV === "PRODUCTION";
console.log = (...args) => {
if (!isProd) devLogger.info.call(devLogger, ...args);
generalLogger.info.call(generalLogger, ...args);
};
console.info = (...args) => {
if (!isProd) devLogger.info.call(devLogger, ...args);
generalLogger.info.call(generalLogger, ...args);
};
console.warn = (...args) => {
if (!isProd) devLogger.warn.call(devLogger, ...args);
generalLogger.warn.call(generalLogger, ...args);
};
console.error = (...args) => {
if (!isProd) devLogger.error.call(devLogger, ...args);
generalLogger.error.call(generalLogger, ...args);
};
console.debug = (...args) => {
if (!isProd) devLogger.debug.call(devLogger, ...args);
generalLogger.debug.call(generalLogger, ...args);
};
module.exports = { generalLogger, devLogger, apiAccessLogger, apiErrorLogger };
/*-------------------IMPLEMENTATION IN EXPRESS SERVER-------------------*/
const { apiAccessLogger, apiErrorLogger, devLogger } = require("./winston.logger");
server.use(morgan("short", { stream: devLogger.stream }));
server.use(apiAccessLogger);
/* ~all routers goes here~ */
server.use(apiErrorLogger);
/*-------------------IMPLEMENTATION WITH CONSOLE-------------------*/
console.log("This is simply a log");
console.error("YOU KNOW WHERE YOU'RE WITH, FLOOR COLLAPSING, FLOATING!");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment