节点请求/特定于连接的变量

时间:2016-01-22 21:36:52

标签: javascript node.js logging

上下文

我试图将日志条目链接到与这些条目的生成相关联的请求。我喜欢bunyan' child记录器的概念,它允许我将请求ID附加到子记录器生成的任何后续条目。我希望这个记录器可以在其他模块中使用,所以我require一个带有getter的文件来获取子记录器。这允许将诸如getting widgets之类的其他孤立事件链接到导致该条目的请求

受挫的例子:

index.js

var widget = require('./widget');
var logging = require('./logging');
//...
app.use('*', function(req, res, next) {
    var logger = logging.getLogger();
    var child = logger.child({requestId: req.id}); //req.id set in earlier middleware
    logging.setLogger(child);
};
app.get('/widgets', function(req, res, next) { 
    res.json(widgets.getAll());
};
//...

widget.js

var logging = require('./logging');
//...
exports = module.exports = {
    getAll: function () {
        logging.getLogger().info("getting widgets");
        return widgets;
    }
}

问题在于请求(单例?)之间共享状态,因此如果几乎同时发出两个请求,那么"获取小部件"日志条目将requestId属性设置为第二个请求的id。

问题:

是否有办法让范围附加到请求的变量,而不必注入和传递req对象(例如new widget()和/或widget.setRequest(req)),或者实例化为注入logging对象?将这样的对象传递到其他模块感觉就像违反了关注点分离

换句话说,为了实现我想要实现的目标,为请求而不是跨请求共享状态的最佳方式是什么?

1 个答案:

答案 0 :(得分:0)

您可以通过将代码更改为:

,为每个请求提供自己的私有子记录器
app.use('*', function(req, res, next) { 
    req.fooBarLogger = logging.getLogger().child({requestId: req.id});
});
app.get('/widgets', function(req, res, next) { 
    res.json(widgets.getAll(req));
});
module.exports = {
    getAll: function(req) {
        req.fooBarLogger.info("getting widgets");
        return widgets;
    }
};