Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add module name in winston log entries

Is there a possibility to save the current module name in order to be printed automatically in winston log entries when they are called later?

Currently, when I want to print the module name in logs, I have to add it manually:

var logHeader = 'mymodule'

log.info(logHeader + 'Hello')

For example, with debug, you can do (ignore the log format feature %s for now):

var debug = require('debug')('http')
  , name = 'My App'

debug('booting %s', name);

This will prin http prefix before the log:

http booting My App

Can this be done in winston? I have searched in the documentation but I couldn't find anything relevant.

like image 998
Alexandru Irimiea Avatar asked Mar 17 '17 13:03

Alexandru Irimiea


3 Answers

I found a better way to do this.

I added an additional layer over the winston logger, in this case a function, that keeps the module name for each module that needs the logger. So when a module requires my new logger, it actually calls the exported function with the module name, in this case __filename.

log.js

var winston = require('winston')

var winstonLogger = new (winston.Logger)({
    transports: [
        new (winston.transports.File) ({
            filename: 'MyLogs.txt',
            handleExceptions: true,
            humanReadableUnhandledException: true,
            level: 'info',
            timestamp: true,
            json: false
        }),
        new (winston.transports.Console) ({
            level: 'info',
            prettyPrint: true,
            colorize: true,
            timestamp: true
        })
    ]
})

module.exports = function(fileName) {    
    var myLogger = {
        error: function(text) {
            winstonLogger.error(fileName + ': ' + text)
        },
        info: function(text) {
            winstonLogger.info(fileName + ': ' + text)
        }
    }

    return myLogger
}

module1.js

var log = require('log')(__filename)

log.info('Info log example')

info: C:\Users\user1\project\module1.js: Info log example

module2.js

var log = require('log')(__filename)

log.error('Error log example')

error: C:\Users\user1\project\module2.js: Error log example

Also, this way, I didn't need to change anywhere the way I submit a text log; log.info('text') stays exactly like before.

like image 192
Alexandru Irimiea Avatar answered Sep 17 '22 21:09

Alexandru Irimiea


This is what Child Loggers are for. They might not have been available when this question was asked, but for future reference, you can create your main logger instance and then export a function that creates a child logger with some default options.

// logging.js
const winston = require('winston') 

const logger = winston.createLogger({
  transports: [
    new winston.transports.Console({
      format: winston.format.printf(options => {
        // you can pass any custom variable in options by calling
        // logger.log({level: 'debug', message: 'hi', moduleName: 'my_module' })
        return `[${options.moduleName}] ${options.level}: ${options.message}$`;
      })
    })
  ]
});

module.exports = function(name) {
  // set the default moduleName of the child
  return logger.child({moduleName: name});
}

Then at the top of each module, import the child using:

// my_module.js
const logger = require('./logging.js')('my_module_name');

logger.error('computer says no');
// output:
// [my_module_name] error: computer says no
like image 29
Papooch Avatar answered Sep 19 '22 21:09

Papooch


You can specify a custom log format with Winston -

var moduleName = 'myModule';

var logger = new (winston.Logger)({
  transports: [
    new (winston.transports.Console)({
      formatter: function(options) {
        // Return string will be passed to logger. 
        return moduleName + ' - ' + (options.message ? options.message : '')
      }
    })
  ]
});


logger.info('This is a log message');

This will print -

myModule - This is a log message

So your module name will be appended to every log messsage.

like image 32
Jyotman Singh Avatar answered Sep 16 '22 21:09

Jyotman Singh