Javascript 节点、express应用程序的通用日志记录--最佳实践?

Javascript 节点、express应用程序的通用日志记录--最佳实践?,javascript,node.js,express,logging,bunyan,Javascript,Node.js,Express,Logging,Bunyan,我正在开发一个包含几十个模块的node.js应用程序,并使用bunyan进行日志记录(JSON输出,多个可配置流)。我一直在寻找如何在所有模块中实现一个实例的好例子,但还没有看到我可以从中学习到的真正干净的例子 下面说明了一种有效的方法,但对我来说似乎很不雅观(丑陋)。一般来说,我对node&commonjsjavascript还不熟悉,所以我想了解如何改进它的建议 模块:./lib/logger // load config file (would like this to be passed

我正在开发一个包含几十个模块的node.js应用程序,并使用bunyan进行日志记录(JSON输出,多个可配置流)。我一直在寻找如何在所有模块中实现一个实例的好例子,但还没有看到我可以从中学习到的真正干净的例子

下面说明了一种有效的方法,但对我来说似乎很不雅观(丑陋)。一般来说,我对node&commonjsjavascript还不熟悉,所以我想了解如何改进它的建议

模块:./lib/logger

// load config file (would like this to be passed in to the constructor)
nconf.file({ file: fileConfig});
var logSetting = nconf.get('log');

// instantiate the logger
var Bunyan = require('bunyan');
var log = new Bunyan({
    name: logSetting.name,
streams : [
        { stream  : process.stdout, 
        level : logSetting.stdoutLevel},
        {    path : logSetting.logfile, 
            level : logSetting.logfileLevel}
    ],
serializers : Bunyan.stdSerializers
});

function Logger() {
};

Logger.prototype.info = function info(e) { log.info(e) };
Logger.prototype.debug = function debug(e) { log.debug(e) };
Logger.prototype.trace = function trace(e) { log.trace(e) };
Logger.prototype.error = function error(e) { log.error(e) };
Logger.prototype.warn = function warn(e) {  log.warn(e) };

module.exports = Logger;
模块:主应用程序

// create the logger
var logger = require('./lib/logger)
var log = new logger();

// note: would like to pass in options -->  new logger(options)


module: any project module using logger
// open the logger (new, rely on singleton...)
var logger = require('./lib/logger');
var log = new logger();

有什么建议吗

编辑:

我修改了构造函数,使单例模式显式(而不是隐式)成为“require”行为的一部分

var log = null;
function Logger(option) {

// make the singleton pattern explicit
if (!Logger.log) {
    Logger.log = this;
}
    return Logger.log;
};  
然后将初始化更改为采用选项参数

// initialize the logger 
Logger.prototype.init = function init(options) {
log = new Bunyan({
    name: options.name,
    streams : [
        { stream  : process.stdout, 
            level : options.stdoutLevel},
        {    path : options.logfile, 
            level : options.logfileLevel}
    ],
    serializers : Bunyan.stdSerializers     
    });
};

如果将express与node.js一起使用,则可以尝试此方法。 默认情况下,在Express中禁用日志记录。您必须执行某些操作才能使应用程序的日志正常工作。对于访问日志,我们需要使用日志记录中间件;对于错误日志,我们将永远使用。希望它能帮到您。。 下面是node.js中的一个很好的示例和错误 实际上,节点环境中可能不需要singleton。您只需在单独的文件中创建一个记录器,例如logger.js:

var bunyan = require("bunyan"); // Bunyan dependency var logger = bunyan.createLogger({name: "myLogger"}); module.exports = logger; var bunyan=require(“bunyan”);//bunyan依赖关系 var logger=bunyan.createLogger({name:“myLogger”}); module.exports=记录器; 然后,从另一个模块检索此记录器:

var logger = require("./logger"); logger.info("Anything you like"); var记录器=需要(“./记录器”); logger.info(“任何你喜欢的”);
您所拥有的看起来像是使用require的功能构建的基本单例。您可以实现自己的单例,但不一定会更好。可能可以进行依赖项注入?感谢您的回答--是的,这是一个基本单例。有几件事让我感到困扰(a)单例行为是隐含的,而不是显式的,(b)我没有找到一种干净的方法让构造函数获取参数(比如一个选项JSON),而不必确定它们是否已经被前一个模块加载,以及(c)传递引用(作为参数)的替代方法每个模块看起来都很混乱/冗长。感谢您的回复!是的,这是一个基本的单例,尽管它似乎是一个隐含的行为,而不是一个定义的行为。我已经研究了[bad practice?](),[singleton pattern]()以及[using require for singleton]()他们似乎比上面更好地解决了构造函数行为。谢谢,这是一个有用的参考。我已经使用类似的模式使用Bunyan的express日志中间件,我正在努力创建一个干净的包装类,它允许我在所有模块中使用同一个实例,并使用初始化方法允许传入选项的od。将发布我的想法…我喜欢这种方法,但在首次使用之前如何配置记录器?我想这样使用它,但我想设置输出路径。我尝试在logger.js中包含“init”函数并设置“module.exports”在它里面,但是不太好。@lixiang这不是每次需要时都要创建一个新的logger实例吗?@PixMach,不,require模块将缓存对象instanceOh,这意味着require(“./logger”)实际上是一个单例,不是吗?@mogsie,是的,如果我们导出一个对象,它就是单例。如果我们导出一个函数,它不是单例。