结构node.js带模块的App

Nic*_*ico 2 javascript logging node.js

我想用模块构建我的Node.js应用程序.例如,我使用bunyan作为记录器.

我有一个文件main.js

//configs
var logfile = __dirname + '/log.txt';

//my own modules
var log = require("./modules/log"),
    init = require("./modules/init");
Run Code Online (Sandbox Code Playgroud)

所以我将日志文件+路径传递给日志模块.

我的log.js

var bunyan    = require('bunyan');

function init(logfile){

var log = bunyan.createLogger({
  name: "myapp",
  streams: [{
    path: logfile
  }]
});
  return log;
};

module.exports.init = init;
Run Code Online (Sandbox Code Playgroud)

而init.js目前只捕获未被捕获的异常:

var logging = require('./log'),
    log = logging.init;

process.on('uncaughtException', function(err) {

  //print to console
  console.error((new Date).toUTCString() + ' uncaughtException:', err.message);
  console.error(err.stack);

  //print to bunyan logger
  log.error((new Date).toUTCString() + ' uncaughtException:', err.message);
  log.error(err.stack);

});
Run Code Online (Sandbox Code Playgroud)

我现在的主要问题是我想在每个模块中使用记录器.但是,当我这样做

var logging = require('./log'),
    log = logging.init;
Run Code Online (Sandbox Code Playgroud)

在每个文件中,它每次都会创建记录器.我只想初始化一次,然后在每个模块中使用它.

我想删除记录器的功能:

log.js

var bunyan    = require('bunyan');
var log = bunyan.createLogger({
  name: "juntidos",
  streams: [{
    path: logfile
  }]
});
Run Code Online (Sandbox Code Playgroud)

当我加载模块时,它只会被调用一次.但是如何传递filename参数呢?

Nat*_*ate 5

所以我将日志文件+路径传递给日志模块.

我看到logfilerequire在日志模块之前定义,但与浏览器中的JavaScript不同,Node.js变量默认不是全局变量.

您的日志文件路径对任何模块都不可见.


如果你想(1)初始化你的记录器,以便它可以在你的整个应用程序中使用,并且(2)传递日志文件名而不是硬编码到你的log.js模块中,一种方法是这样做:

// log.js

var bunyan = require('bunyan');

module.exports = {
    logger: undefined,

    init: function(logfile) {
        this.logger = bunyan.createLogger({
            name: 'myapp',
            streams: [{
                path: logfile    
            }]
        });
    }
};
Run Code Online (Sandbox Code Playgroud)

现在,您只需要确保init()只调用一次,并且这任何其他模块加载之前发生.这应该很容易:

// main.js

var logfile = __dirname + '/log.txt';

var log = require('./modules/log.js').init(logfile),    // init() called here
    anotherModule = require('./modules/anotherModule.js')
    someOtherModule = require('./modules/someOtherModule.js');
Run Code Online (Sandbox Code Playgroud)

在您的子模块中,执行以下操作:

// someOtherModule.js

var log = require('./log.js');
log.logger.warn('someOtherModule was loaded');
Run Code Online (Sandbox Code Playgroud)