DEV Community

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

Posted on • Edited on

2 1

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

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay