Search code examples
node.jswinston

Winston/Node.js how add a Transport only for certain environment?


I have the follow configuration:

var winston = require('winston');
var Mail = require('winston-mail').Mail;

var logger = new (winston.Logger)({
  transports: [
    new (winston.transports.Console)({ level: 'info', colorize: true }),
    new (winston.transports.File)({ level: 'info', filename: './logs/logs.log',
    new (Mail)({
              to: 'xxxxxx@xxxxxx.xx',
              from: 'winston@xxxxx.xx',
              subject: 'Errors occurred',
              level: 'error',
              host: 'smtp.xxxxx.xx',
              username: 'xxxx@xxxx.xx', 
              password: 'xxxxx',
              port: xxx
            })
  ],
  exceptionHandlers: [
    new (winston.transports.Console)(),
    new (winston.transports.File)({ filename: './logs/exceptions.log' }),
    new (Mail)({
              to: 'xxxxxx@xxxxxx.xx',
              from: 'winston@xxxxx.xx',
              subject: 'Errors occurred',
              level: 'error',
              host: 'smtp.xxxxx.xx',
              username: 'xxxx@xxxx.xx', 
              password: 'xxxxx',
              port: xxx
            })
 ]
});

I'd like add the Mail transport only for production environment not in staging or development.

I set a different log level as follow:

if (process.env.NODE_ENV === 'development') {
  logger.transports.console.level = 'debug';
  logger.transports.file.level = 'debug';
}

There is a way to do that also with transport?


Solution

  • The transports configuration is just a plain old Array. So we can use all the usual tricks on it. In this case, you want a conditional push().

    const winston = require('winston');
    const transports = [
        new winston.transports.Console({
            level    : 'info',
            colorize : true
        }),
        new winston.transports.File({
            level    : 'info',
            filename : './logs/logs.log'
        })
    ];
    
    if (process.env.NODE_ENV === 'production') {
        const Mail = require('winston-mail').Mail;
    
        transports.push(new Mail({
            to       : 'xxxxxx@xxxxxx.xx',
            from     : 'winston@xxxxx.xx',
            subject  : 'Errors occurred',
            level    : 'error',
            host     : 'smtp.xxxxx.xx',
            username : 'xxxx@xxxx.xx', 
            password : 'xxxxx',
            port     : 1234
        }));
    }
    
    const logger = new winston.Logger({
        transports
    });
    

    This code should be usable as is on Node.js >= 4, after filling in the mail configuration placeholders.

    The same principle can be applied to the exceptionHandlers.