Logging in Node with Winston

What is Winston?

Winston is a simple and universal logging library.

Why use a logging library?

When developing an application, sometimes we need to get information about how the application is running. We can use functions like console.log, console.error, console.warn to accomplish this. A logging library, such as Winston, allows us to output similar types of data except it can send this data (log data) to locations other than just the console. For example, an external file.

The basic idea of logging

Basically, you have a logger that writes to an arbitrary amount of transports. A transport is essentially a storage device for your logs. Some common transports include:

  • stdout (console)
  • file
  • HTTP
  • Datadog (log aggregator)

Log levels

Log levels allow us to categorize the entries in a log file by urgency. The higher up it is, the more severe it is. As you can see, fatal is the most severe.

These are npm log levels:

{
   fatal: 0,
   error: 0,
   info: 0,
   http: 0,
   verbose: 0,
   debug: 0,
}

Setting up a simple logger in Winston

The recommended way to use winston is to create your own logger. The simplest way to do this is using winston.createLogger.

Install Winston in project

npm install winston

In a new file, create a logger with winston.createLogger

const winston = require('winston');

const logger = winston.createLogger({

});

module.exports = logger;

Add custom properties to logger

const winston = require('winston');

const logger = winston.createLogger({
   format: winston.format.simple(),
   transports: [new winston.transports.Console()],
});

module.exports = logger;

The format property controls how the logs are displayed visually.

transports is an array of the places (transports) to send the log data to. In the above example, our only transport is the console.

Use the logger

const logger = require('./logger')   // access the file you created earlier

logger.info('text info');
logger.warn('text warn');
logger.error('text error');
logger.debug('text debug');

The output should look something like this:

Why is the debug log not showing up? The default log level for a Winston logger is info. This means that Winston will only log the info level and all levels ABOVE it (warn, error, etc.)

Creating custom log format in Winston

Destructure Winston import

This is just for our own ease of use. No change to the logic.

const { createLogger, format, transports } = require('winston');
const { timestamp, combine, printf } = format;

const logger = createLogger({
  format: format.simple(),
  transports: [new transports.Console()]
});

Create custom format

const myFormat = printf(({ level, message, timestamp }) => {
  return `${timestamp} ${level}: ${message}`;
});

Add the format to your logger

const logger = createLogger({
  format: combine(timestamp(), myFormat),
  transports: [new transports.Console()]
});

Final code

const { createLogger, format, transports } = require('winston');

const myFormat = printf(({ level, message, timestamp }) => {
  return `${timestamp} ${level}: ${message}`;
});

const logger = createLogger({
  format: combine(timestamp(), myFormat),
  transports: [new transports.Console()]
});

Here is another custom log format

const logger = createLogger({
  format: combine(
       format.colorize(),
       timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), 
       myFormat
  ),
  transports: [new transports.Console()]
});

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s