Search code examples
node.jswinston

Log error using a custom formatter in winston


I have a custom formatter added in winston. The code looks like below:-

'use strict';

const winston = require('winston');
winston.transports.DailyRotateFile = require('winston-daily-rotate-file');

var timeStampFormat = "YYYY-MM-DDTHH:mm:ss.SSSZ";
var moment = require('moment');

function logTemplate(level, meta, message){
    return "{" +
        "\"timestamp\" : \"" + moment().format(timeStampFormat) + "\" ," +
        "\"level\" : \"" + level + "\"," +
        meta +
        "\"content\" :" + message +
        "}";
}

function formatter(args) {
    var message = "";
    var metaString = "";


    message = JSON.stringify(args.message); 
    var reqId = "1212121211";
    var metaString = "\"reqId\" : \"" + reqId + "\", ";
    console.dir(JSON.stringify(args))
    return logTemplate(args.level, metaString, message);    
}




class Logger {
    constructor(appName, stream, shouldConsole) {
        stream.formatter = formatter;
        this.logger = new winston.Logger({
            level: stream.level,
            transports: [
                new (winston.transports.Console)(),
                new (winston.transports.DailyRotateFile)(stream)
            ]
        });
        this.logger.level = "silly";
        this.logger.cli();
        return this;
    }

    trace() {
        return this.logger.log("trace", arguments);
    }

    debug() {
        return this.logger.log("debug", arguments);
    }

    info() {
        return this.logger.log("info", arguments);
    }

    warn() {
        return this.logger.log("warn", arguments);
    }

    error() {
        return this.logger.log("error", arguments);
    }

    fatal() {
        return this.logger.log("fatal", arguments)
    }
}

exports = module.exports = Logger;

I am logging using a string or object:-

var x = {};
x.a = "Hello";
x.b = "World";
log.info("Error Message Test", x);

Output

{"timestamp" : "2016-11-10T12:53:22.334+05:30" ,"level" : "info","reqId" : "1212121211", "content" :"   { '0': 'Error Message Test', '1': { a: 'Hello', b: 'World' } }"}

When I am trying to log an Error object like below:-

log.info(new Error("The error message"));

Output:-

{"timestamp" : "2016-11-10T03:43:47.613+05:30" ,"level" : "info","reqId" : "1212121211", "content" :"   { '0': \n   Error: The error message\n     at Server.<anonymous> (/Users/debraj/code/github/jabong/JARVIS/server.js:91:15)\n     at Server.g (events.js:286:16)\n     at emitNone (events.js:86:13)\n     at Server.emit (events.js:185:7)\n     at emitListeningNT (net.js:1279:10)\n     at _combinedTickCallback (internal/process/next_tick.js:71:11)\n     at process._tickCallback (internal/process/next_tick.js:98:9)\n     at Function.Module.runMain (module.js:577:11)\n     at startup (node.js:160:18)\n     at node.js:449:3\n    }"}

Can some one let me know how can I log the Error object properly formatted like the Error Message inside a errMsg field and stack-trace inside a trace field in the json log using winston?


Solution

  • How about this:

    const formatter = name => options => {
      let stack = '';
      if (options.meta) {
        if(options.meta.stack) {
          stack += '\n' + options.meta.stack;
          options.meta.stack = undefined;
        }
        if(options.meta.errorStack) {
          if(stack !== '') {
            stack += '\n';
          }
          stack += options.meta.errorStack;
          options.meta.errorStack = undefined;
        }
      }
      return timestamp() + ' - ' + name + ' - ' + formatLevel[options.level] + ' '
        + (options.message ? JSON.stringify(options.message) : '')
        + (options.meta && Object.keys(options.meta).length ? '\n\t' + JSON.stringify(options.meta) : '' )
        + stack;
    };
    
    // config:
    {
      transports: [
        new winston.transports.Console({... loggingConfig.console, formatter: formatter(name)})
      ],
      exitOnError: false
    }