2016-05-31 100 views
10

我正在尝试为日志记录目的创建某种请求ID,这将通过请求流中的每个函数提供给我。我想记录请求流的每一步,并在一个Id中指出哪个日志行是哪个请求的。node.js快速请求Id

我看过了一些想法,跑进2点主要建议:

首先是创建将在“请求”对象添加一个字段像这样一个中间件(如建议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

为什么传递'req'对象只有一个属性(这只是一个数字)会成为一个问题?我不认为这会导致任何明显的性能下降? – leroydev

+0

这不是我担心的表现。为大量函数添加额外的参数是耗时且易出错的 –

+0

为什么您需要添加额外的参数才能实现? – leroydev

回答

0

您可以通过(a)将信息存储为仅限服务器的cookie和(b)将更多信息放入cookie而不仅仅是一个计数器,从而使您的原始程序更加复杂一些。例如,我用以下为我的应用程序的所有呼叫跟踪:

console.log('['+count+'] at: '+format.asString('hh:mm:ss.SSS', new Date())+' Url is: ' + req.url); 

其中“数”是从应用开始增加(是的,最好使用一个持久单)。这给了我对服务器的每一次调用(req.url)以及调用的完成时间。如果您的应用正在进行会话级别管理,则可以轻松扩展此选项以获取sessionID。

+0

我不太明白这个解决方案。 比方说,我刚开始应用程序 - 所以计数器为0,然后我在服务器中处理3个并发请求。计数器现在将被设置为3--这意味着如果我想记录整个函数的流程,那么所有的请求都会得到3,这不会帮助我区分它们。 我错过了什么吗? –

0

您可以使用此包: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

0

你有异步通信,并且要保持上下文,没有a)封闭或b)参数传递。恐怕你最好的选择是将的东西传递给所有需要知道它的函数 - 无论是req对象,请求ID,还是咖喱log函数调用 - 的东西。

无论你传递可以很轻松地重构到任何其他的 - 普通的ID可以查找来自全球存储对象(不,但可能)为例。考虑到这一点 - 你可能已经有东西被传递给唯一标识请求的方法;在这种情况下,将其用作关键字并从全局存储中查找其他数据(即require带有module.exports.cache = new Map();或其他东西的文件,没有理由污染全局名称空间)。如你所注意到的,尝试用语言做一些奇特的事情往往是脆弱的(特别是在遇到其他不可思议的事物时)。也就是说,你可以弄清楚continuation-local-storage是如何在内部工作的,如何调试它以及破解库,并使用它或自制解决方案。

您听起来不舒服,因为维护此代码的成本。这是一种代码异味 - 并且增加隐式全局延续本地状态听起来像是只会使代码更难向前移动而不是更简单。您可能会将此作为一个学习机会,并询问为什么您需要请求ID,并且为什么当编写代码的人不需要时。我很抱歉,如果不知道代码库本身,这是我能给出的最佳答案。