我正在尝试创建某种用于记录目的的请求ID,我可以通过请求流中的每个函数使用它。我想记录请求流的每一步,并用Id说明哪个日志行是针对哪个请求的。
我查看了一些想法,并提出了两个主要建议:
第一个是创建一个中间件,它会在'req'对象中添加一个字段(如建议的here):
var logIdIterator = 0;
app.all('*', function(req, res, next) {
req.log = {
id: ++logIdIterator
}
return next();
});
第二个是使用continuation-local-storage
问题是:
对于第一种方法 - 这意味着我将不得不向流中的每个函数传递一个额外的参数,这对于使用无数API和流程的成熟应用程序来说不是一个简单的解决方案。
第二个看起来很有希望,但遗憾的是它有一些问题导致状态丢失(例如见here)。 此外,当我们使用我们的redis库时,它发生了几次 - 这很糟糕,因为redis请求发生在我们的每个流上。
我想如果我找不到另一个解决方案,我将不得不使用第一种方法,只是我想避免将额外的参数传递给数千个现有函数。
我的问题是 - 您如何建议通过请求流维护请求ID?
答案 0 :(得分:1)
您可以使用此套件:https://www.npmjs.com/package/express-request-id
这是为每个请求附加uuid的中间件
var app = require('express')();
var addRequestId = require('express-request-id')();
app.use(addRequestId);
app.get('/', function (req, res, next) {
res.send(req.id);
next();
});
app.listen(3000, function() {
console.log('Listening on port %d', server.address().port);
});
// curl localhost:3000
// d7c32387-3feb-452b-8df1-2d8338b3ea22

答案 1 :(得分:0)
您可以通过以下方式使原始例程更加复杂:(a)将信息存储为仅服务器的cookie,以及(b)将更多信息放入cookie中,而不仅仅是计数器。例如,我使用以下内容作为对我的应用程序的所有调用的跟踪:
console.log('['+count+'] at: '+format.asString('hh:mm:ss.SSS', new Date())+' Url is: ' + req.url);
其中'count'从app start开始递增(是的,更好地使用持久单例)。这给了我每次调用服务器(req.url)以及确切调用的时间。如果您的应用正在进行会话级管理,则可以轻松扩展以获取sessionID。
答案 2 :(得分:0)
您有异步通信,并且您希望保留上下文而无需a)闭包或b)参数传递。我担心你最好的办法是将某些东西传递给所有需要知道它的函数 - 无论是req
对象,请求ID,还是curry {{ 1}}函数调用 - 某事。
无论你传递的是什么都可以很容易地重构到其他任何一个 - 一个普通的id可以从全局存储中查找一个对象(不是好,但是可能的)例。考虑到这一点 - 您可能已经将某些传递给唯一标识请求的方法;在这种情况下,使用它作为密钥并从全局存储中查找其他数据(即log
具有require
或其他内容的文件,没有理由污染全局名称空间。)
正如您已经注意到的那样,尝试使用该语言进行不可思议的事情往往很脆弱(特别是在遇到其他不稳定的事情时)。也就是说,您可以弄清module.exports.cache = new Map();
如何在内部工作,与破坏库一起调试,并使用它或自制解决方案。
您对维护此代码的成本感到不安。这是一种代码味道 - 并且添加隐式全局延续本地状态听起来像只会使理解和维护代码更难而不是更简单。您可以将此作为学习机会,并询问为什么您需要请求ID,以及为什么在编写代码时不需要它。对不起,如果不知道代码库本身,这是我能给出的最佳答案。