Javascript 节点请求/连接特定变量

Javascript 节点请求/连接特定变量,javascript,node.js,logging,Javascript,Node.js,Logging,上下文: 我正在尝试将日志条目链接到与生成这些条目相关联的请求。我喜欢bunyan的childlogger的概念,它允许我将请求id附加到由child logger生成的任何后续条目上。我想在其他模块中使用这个记录器,所以我需要一个带有getter的文件来获取子记录器。这允许一个单独的事件(如获取小部件)链接到导致该条目的请求 人为的例子: index.js var widget = require('./widget'); var logging = require('./logging');

上下文:

我正在尝试将日志条目链接到与生成这些条目相关联的请求。我喜欢bunyan的
child
logger的概念,它允许我将请求id附加到由child logger生成的任何后续条目上。我想在其他模块中使用这个记录器,所以我需要一个带有getter的文件来获取子记录器。这允许一个单独的事件(如
获取小部件
)链接到导致该条目的请求

人为的例子:

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());
};
//...
var logging = require('./logging');
//...
exports = module.exports = {
    getAll: function () {
        logging.getLogger().info("getting widgets");
        return widgets;
    }
}
widget.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());
};
//...
var logging = require('./logging');
//...
exports = module.exports = {
    getAll: function () {
        logging.getLogger().info("getting widgets");
        return widgets;
    }
}
问题是状态在请求之间共享(单例?),因此如果两个请求几乎同时发出,“获取小部件”日志条目将
requestId
属性设置为第二个请求的id

问题:

有没有一种方法可以使变量的作用域附加到请求,而不必注入和传递
req
对象(例如
newwidget()
和/或
widget.setRequest(req)
),或实例化为注入
日志记录
对象?将这样的对象传递到其他模块感觉像是违反了关注点的分离


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

通过将代码更改为:

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


logging.setLogger(logging.getLogger().
…我的眼睛开始灼热。在x之前,我从未见过如此详细的node.js。x@PatrickRoberts这是一个非常做作的例子,只是为了让大家明白这一点。建议?更多的行会有帮助吗?我找不到任何引用
req.id
的文档。这是从哪里来的?它本身并不存在,它是在先前的中间件,并添加到
req
对象中(在
/…
行的某处)为了确保我理解总体目标,它需要控制台日志以唯一的请求ID作为前缀?该死的,比我快…我已经解释了一半。我的逻辑是:如果你需要控制台日志,而不是将引用存储在在
logging
模块中,您可以将其直接连接到
req
对象,因为与该
req
关联的任何控制台日志都很可能具有对该
req
对象的作用域访问权。我在问题中提到了这一点,“无需注入和传递req对象”。当小部件的依赖项有进一步的依赖项时,它会变得更复杂,然后也需要
req
对象,或者当小部件不需要它,但它的依赖项却需要它。这就是为什么它似乎违反了SoC原则。如果将它注入到所有依赖项和子依赖项中是获得功能的唯一方法,那么正如我所希望的,我想我只需要接受它,你不必将它附加到
req
。例如,你可以直接传递它。然而,这将需要所有需要进行日志记录的函数现在接受另一个参数——这更复杂,也不总是可能的e
req
对象通常是获得所需内容的最便宜的方法。已经通过
req
对象的函数可以免费获得记录器。