Creating a custom logger in Node JS using Winston
Ian Kamau
Posted on April 11, 2024
Hello fellow developers,
I am excited to share with you how you can use winston to develop a custom logger for your node js application. This is beginner friendly and anyone can follow.
Let's get started:
Create an empty directory:
mkdir node-logger
cd node-logger
code .
Open the terminal inside the VS code
Initialize package.json:
npm init -y
Install express, dotenv, winston and nodemon:
npm install --save-dev express dotenv winston nodemon
create the index.js
file:
touch index.js
After creating index.js
go to package.json
and add the start script
inside scripts
:
"scripts": {
"start": "nodemon index.js",
},
In index.js
lets set up the basic server configuration using Express.
const express = require("express");
const dotenv = require("dotenv");
dotenv.config();
const PORT = process.env.PORT || 8000;
const app = express();
app.listen(PORT, ()=>{
console.log(`listening on http://localhost:${PORT}`)
});
Let us now create the .env
file:
touch .env
Now add your environment variables inside your .env
file:
PORT=8000
NODE_ENV=development
With that done, in the terminal inside your VS code, create a folder utils
and inside utils
create a file called logger.js
:
mkdir utils
cd utils
touch logger.js
In logger.js
, lets write the logging logic. First let us import winston and configure dotenv:
const winston = require("winston");
const dotenv = require("dotenv");
dotenv.config();
Then we will define our security levels:
const levels = {
error: 0,
warn: 1,
info: 2,
http: 3,
debug: 4,
}
const level = () => {
const isDevelopment = process.env.NODE_ENV || "development";
return isDevelopment ? "debug" : "warn";
};
We will define different colors for each level and tell winston to use those colors:
const colors = {
error: "red",
warn: "yellow",
info: "green",
http: "magenta",
debug: "white",
};
winston.addColors(colors);
After that, select the aspect of our logging process to customize the log format:
const format = winston.format.combine(
winston.format.timestamp({
format: "YYYY-MM-DDTHH:mm:ss",
}),
winston.format.colorize({ all: true }),
winston.format.printf(
(info) => `${info.timestamp} ${info.level}: ${info.message}`
)
);
Let's define the transports that the logger must use for printing out messages:
const transports = [
// Allow the user to console/print the message
new winston.transports.Console(),
// Allow to print all error level messages inside the all.log file
new winston.transports.File({
filename: "logs/error.log",
level: "error",
}),
// Allow to print all messages inside the all.log file
new winston.transports.File({
filename: "logs/all.log",
}),
];
Configure the transports that the logger needs to employ for displaying messages:
const Logger = winston.createLogger({
level: level(),
levels: levels,
format: format,
transports: transports,
exitOnError: false,
});
module.exports = Logger;
In your index.js
import logger
from logger.js
:
const Logger = require("./utils/logger");
replace console.log
with Logger.http
Finally, start the server:
npm start
Posted on April 11, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.