在 node.js 应用程序中包装记录器的设计模式

design pattern for wrapping logger in node.js application

我正在编写 node.js 应用程序并使用 bunyan 进行日志记录。我想做的是在我的应用程序初始化时创建一个 bunyan 记录器实例,从现在开始我希望每个需要记录器的模块都将获得具有相同配置选项的相同实例。

// index.js
var logger = require('./app/utils/logger');
var config = require('./app/config');

config.init().then(function(configData) {
  // create the logger instance once
  var log = logger({
      name: 'appLogger'
      level: configData['log.level'],
      src: process.env.NODE_ENV === 'development',
      streams: [{
         path: path.resolve(configData['log.file']),
         type: 'file'
      }]
    });
 log.info('logger created');
}).catch(function(err) {
  console.log(err)
});

现在我希望我的应用程序中的每个模块都将获得相同的记录器实例:

// foo.js
var log = require('./app/utils/logger');
log.info('this should be logged in the file that was defined in index.js');

我应该在记录器模块中实现的推荐设计模式是什么?

// logger.js
var bunyan = require('bunyan');
// bunyan.createLogger(options)
// what should be here?

您可以让您的记录器既充当构造函数,又充当记录器单例,用于挂起您的 info()、debug()、warn() 和 error() 方法。

// logger.js
var bunyan = require('bunyan');
// bunyan.createLogger(options)

var name, level, src, streams;

var logger = function(params){
    name = params.name;
    level = params.level;
    src = params.src;
    streams = params.streams;

    logger.info = function(msg){
        console.log("writing to " + streams.path);
    };
    // logger.debug = ...

    return logger;
};

module.exports = logger;

注意 info() 和其他方法是如何在您实际调用记录器函数之前创建的。 logger() 函数实际上并没有创建单例记录器——它只是创建了挂起它的函数。