node.jsexpressloggingwinstonloggly

How to use "winston" to log every request that server receive to Loggly


I am using winston with winston-loggly-bulk to log messages to Loggly. I want to log all requests that my server receives. With morgan, I would do it simply like this:

app.use(morgan('dev'));

Can we do something similar with winston?


Solution

  • To make it work, I combined winston and morgan packages.

    1. Step

    Create a logger that you will use in your server to log messages to Loggly. For that, you can use winston and winston-loggly-bulk. You can create a custom format for logging, and I also added part of the code that will check if the environment is not a production and in that case, it will log messages in the console as well (good practice for development).

    const winston = require('winston');
    const { Loggly } = require('winston-loggly-bulk');
    
    // Levels: ['error', 'warn', 'info', 'http', 'verbose', 'debug', 'silly']
    const logger = winston.createLogger();
    
    logger.add(new Loggly({
      token: process.env.LOGGLY_TOKEN,
      subdomain: process.env.LOGGLY_SUBDOMAIN,
      tags: [process.env.NODE_ENV, process.env.SERVER_INSTANCE],
      json: true
    }));
    
    const custom_format = winston.format.printf(({ level, message, timestamp, ...metadata }) => `${level}: ${message}\n${(metadata && Object.keys(metadata).length) ? JSON.stringify(metadata, null, 4) : ''}`);
    
    //
    // If we're not in production then log to the `console` with the format:
    // `${info.level}: ${info.message} {...rest}`
    //
    if (process.env.NODE_ENV !== 'production') {
      logger.add(new winston.transports.Console({
        format: custom_format
      }));
    }
    
    module.exports = {
      logger
    };
    
    

    2. Step

    Import your logger in part of the code where you would use morgan for logging requests, and stream morgan messages in to the logger. Again, I checked if the environment is a production, since I don't want to log requests in development.

    if (process.env.NODE_ENV === 'development') {
      app.use(morgan('dev'));
    } else {
      app.use(morgan(':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" :response-time ms', { stream: { write: message => logger.log('info', message.trim(), { tags: ['http'] }) } }));
    }