【问题标题】:Add module name in winston log entries在 winston 日志条目中添加模块名称
【发布时间】:2017-08-09 01:46:31
【问题描述】:

是否有可能保存当前模块名称以便在以后调用它们时自动打印在winston 日志条目中?

目前,当我想在日志中打印模块名称时,我必须手动添加:

var logHeader = 'mymodule'

log.info(logHeader + 'Hello')

例如,使用debug,您可以这样做(暂时忽略日志格式功能%s):

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

debug('booting %s', name);

这将在日志前打印http 前缀:

http 启动我的应用程序

这可以在温斯顿完成吗?我在文档中进行了搜索,但找不到任何相关内容。

【问题讨论】:

    标签: node.js winston


    【解决方案1】:

    您可以使用 Winston 指定custom log format -

    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');
    

    这将打印 -

    myModule - This is a log message
    

    因此您的模块名称将附加到每个日志消息中。

    【讨论】:

    • 如果我理解正确,这将在所有日志消息中附加一个字符串。我问的是附加模块名称以记录来自该模块的消息。
    • 是的,因此您需要为每个模块实例化一个唯一的记录器,类似于您为 debug 模块所做的方式。
    • 为每个模块实例化一个记录器从来都不是一个好主意。而是第一个答案更好。
    【解决方案2】:

    我找到了更好的方法。

    我在winston 记录器上添加了一个附加层,在本例中是一个函数,它为需要记录器的每个模块保留模块名称。因此,当一个模块requires 我的新记录器时,它实际上使用模块名称调用导出的函数,在本例中为__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')
    

    信息:C:\Users\user1\project\module1.js:信息日志示例

    module2.js

    var log = require('log')(__filename)
    
    log.error('Error log example')
    

    错误:C:\Users\user1\project\module2.js:错误日志示例

    另外,这样一来,我提交文本日志的方式就无需更改任何地方; log.info('text') 和以前一样。

    【讨论】:

    • 谢谢。我考虑了这个解决方案,并试图找出是否有其他人这样做,您的解决方案比我想象的要好得多。
    【解决方案3】:

    使用 winston v3.3.3,您可以使用 winston.format.label 和自定义 winston.format.printf 来做到这一点:

    const winston = require('winston');
    
    const logger = winston.createLogger({
      format: winston.format.combine(
        winston.format.label({label: 'mymodule'}),
        winston.format.printf(({label, message}) => {
          return `${label}: ${message}`;
        })
      ),
      transports: [
        new winston.transports.Console(),
      ],
    });
    
    logger.info('Hello, World!'); // prints "mymodule: Hello, World!"
    

    【讨论】:

      【解决方案4】:

      这就是 Child Loggers 的用途。当被问到这个问题时,它们可能不可用,但为了将来参考,您可以创建主记录器实例,然后导出一个函数,该函数创建具有一些默认选项的子记录器。

      // 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});
      }
      

      然后在每个模块的顶部,使用以下命令导入子项:

      // my_module.js
      const logger = require('./logging.js')('my_module_name');
      
      logger.error('computer says no');
      // output:
      // [my_module_name] error: computer says no
      

      【讨论】:

      • 您还可以导出其他记录器,然后单独导入。 export const databaseLogger = logger.child({ label: 'database' });
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-21
      • 1970-01-01
      • 2013-10-15
      • 2014-06-16
      • 1970-01-01
      相关资源
      最近更新 更多