Mic*_*zka 5 logging asynchronous mdc node.js promise
在我的node.js应用程序中,每当我收到请求时,我都想用一些唯一的ID“标记”它,并能够通过该ID跟踪与该请求相关的所有活动(日志语句)。因此,当请求传入并且我将其处理传递给较低的应用程序层(服务、数据库调用等)时,我希望能够收集与给定请求 ID 匹配的所有日志,以重建其通过应用程序的旅程。
有了这张图片,我现在使用request-local模块,但它做了一些让我失败的重大魔法(来自多个请求的日志获得相同的 ID)。
该代码主要基于 Promises(不是普通的旧节点回调),并且我使用高阶函数来提供对我的实际函数的依赖项(在启动期间构建应用程序树)。
第一个也是非常明显的解决方案是将这个请求 ID 传递给每个调用的函数,但这是一场灾难,我不会这样做。
您如何(可靠地)进行这种请求跟踪,而不显式将此 id/上下文作为额外参数传递给所有级别的函数?
小智 1
我相信您正在寻找的是一个逻辑流 ID,它应该是唯一的,并且是在后端启动的每个新请求时生成的。如果这个假设是正确的,我通常做的是在我的 Express 路由器上创建一个中间件来生成一个新的随机流 id (带有randomstring)。为了确保该流 ID 是唯一的,我向其中添加了时间戳。为了将此流 ID 传递给下一个中间件,我们应该将其存储在 res.locals 下(此处为文档),您的中间件可能如下所示:
//middleware flow.js
var random = require('randomstring');
var generate = function(){
var dt = new Date();
return random.generate() + dt.toISOString();
}
module.exports.createID = function(req, res, next){
//store flowid in res - this hold state over the request life time
res.locals.flowid = generate();
next();
}
Run Code Online (Sandbox Code Playgroud)
现在我们可以使用以下命令将此中间件注入到应用程序中:
var flowcontrol = require('flow.js');
var middleware = require('middleware.js');
app.use(flowcontrol.createID);
//route example
app.get('/api/awesomeresource', middlewares.first, middlewares.second);
Run Code Online (Sandbox Code Playgroud)
使用这种方法,您将能够在每个中间件上记录相同的流 ID,例如:
//middleware.js
module.exports.first = function(req, res, next){
console.log(res.locals.flowid + " - First i did this...");
//your logic here
next();
}
module.exports.second = function(req, res, next){
console.log(res.locals.flowid + " - Second i did this...");
//your logic here before the response
res.sendStatus(200);
}
Run Code Online (Sandbox Code Playgroud)
结果
GET /api/awesomeresource HTTP/1.1
将是以下控制台日志:
> R90A56nEmZWYK73NOEVbWv2RS6DolO4D2017-12-07T10:29:39.291Z - First i did
> this...
> R90A56nEmZWYK73NOEVbWv2RS6DolO4D2017-12-07T10:29:39.291Z -
> Second i did this...
Run Code Online (Sandbox Code Playgroud)
这意味着您可以通过此标记跟踪某种日志文件,并在需要时调试后端逻辑。
干杯
| 归档时间: |
|
| 查看次数: |
2783 次 |
| 最近记录: |