如何通过Express中的中间件链来识别请求(通过ID)。

我正在开发node.js中的RESTful服务器,使用Express作为框架,目前Winston作为logging器模块。 这个服务器将处理大量的同时请求,并且使用诸如“请求ID”之类的东西来跟踪每个特定请求的日志条目对我来说是非常有用的。 直接的解决scheme就是在每次我想创build一个日志条目时添加这个ID作为另一条日志信息,但是这意味着将“请求ID”传递给服务器使用的每个方法。

我想知道是否有任何node.js / javascript模块或技术,可以让我这样做一个更简单的方式,而不是携带每个特定请求的请求ID。

你可以使用req对象,每个请求都附带express。
所以你在你的应用程序中要做的第一条路线是:

 var logIdIterator = 0; app.all('*', function(req, res, next) { req.log = { id: ++logIdIterator } return next(); }); 

然后在express中的任何地方,你可以在req对象中访问这个idreq.log.id ;
您仍然需要将一些数据传递到需要创build日志的函数中。 实际上,你可能在req.log对象中有日志loggingfunction,这样才能保证logging只有在req.log访问req.log对象时才会发生。

如果自动递增,那么以后的日志分析将无法唯一地识别请求,因为不同的实例会生成冲突的ID,并且重新启动应用程序将自动导致ID冲突。

这是另一个可能的解决scheme

安装cuid:

 npm install --save cuid 

然后在你的主应用程序文件中:

 var cuid = require('cuid'); var requestId = function requestId(req, res, next) { req.requestId = cuid(); next(); }; // Then, at the top of your middleware: app.use(requestId); 

现在,您将得到一个不太可能发生冲突的友好请求ID,并且您将能够唯一地识别您的日志分析和debugging请求,即使在多个实例中也可以重新启动服务器。

我正在努力寻找这个问题的解决scheme。 我不喜欢这里提到的解决scheme的事情是,他们暗示在项目的所有function中共享req对象。 我发现了一个混合你的方法的解决scheme(为每个请求创build一个uuid)和一个允许在模块之间共享名称空间的库(continuation-local-storage)。

你可以在这个答案中find解释: https : //stackoverflow.com/a/47261545/5710581

如果你想要更多的信息,我把所有这些想法和所有的代码写在一个文章中,以便在一个地方解释所有的东西: Express.js:用全球唯一的请求IDlogging信息 – Node.js

你不应该使用全局variables。

我喜欢做的是在每个请求之前填充一个META对象。

我使用UUID生成器( https://github.com/kelektiv/node-uuid )来标识请求

这是一个例子

  app.all('*', function(req, res, next) { req.meta = { ip: req.headers['x-forwarded-for'] || req.connection.remoteAddress, timestamp: uuid(), user_agent: req.headers['user-agent'], body: req.body, } return next(); })