DEV Community

Cover image for Creating a custom logger in Node JS using Winston
Ian Kamau
Ian Kamau

Posted on • Edited on

Creating a custom logger in Node JS using Winston

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 . 
Enter fullscreen mode Exit fullscreen mode

Open the terminal inside the VS code
Initialize package.json:

npm init -y 
Enter fullscreen mode Exit fullscreen mode

Install express, dotenv, winston and nodemon:

npm install --save-dev express dotenv winston nodemon 
Enter fullscreen mode Exit fullscreen mode

create the index.js file:

touch index.js 
Enter fullscreen mode Exit fullscreen mode

After creating index.js go to package.json and add the start script inside scripts:

"scripts": { "start": "nodemon index.js", }, 
Enter fullscreen mode Exit fullscreen mode

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}`) }); 
Enter fullscreen mode Exit fullscreen mode

Let us now create the .env file:
touch .env
Now add your environment variables inside your .env file:

PORT=8000 NODE_ENV=development 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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(); 
Enter fullscreen mode Exit fullscreen mode

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"; }; 
Enter fullscreen mode Exit fullscreen mode

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); 
Enter fullscreen mode Exit fullscreen mode

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}` ) ); 
Enter fullscreen mode Exit fullscreen mode

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", }), ]; 
Enter fullscreen mode Exit fullscreen mode

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; 
Enter fullscreen mode Exit fullscreen mode

In your index.js import logger from logger.js:

const Logger = require("./utils/logger"); 
Enter fullscreen mode Exit fullscreen mode

replace console.log with Logger.http
Finally, start the server:

npm start 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)