Express.js每个请求外部路由的唯一variables
在我的快速应用程序中,我有一个叫helpers的模块,几乎所有的路由和模块都需要这个模块。 这个模块有一个logging器方法,logging到fluentd(但这不重要)。 在构build要logging的数据时,我想添加请求的唯一标识符,以便为同一个请求写入的所有日志具有相同的唯一ID。 在应用程序入口点app.use中使用全局variables不起作用,因为每次新请求命中时都会覆盖该variables,所以全局uuid将会在高负载或长时间运行的任务中发生明显变化。 res.locals在路由之外是不可用的,所以我不能在这个问题上使用它。 有没有办法创build一个var,每个请求都是唯一的,每个模块都可以使用,或者可以通过一种方式访问路由之外的res.locals数据? 谢谢
编辑
也许一个例子将有助于更好地理解这个问题。 假设我有一个叫做helpers.js的模块,像这样:
let helpers = {}; helpers.log = (logData, logName) => { fluentLogger.emit('', { name: logName, //uuid: the needed uuid, message: logData }); } module.exports = helpers;
现在显然我可以在我的app.js入口点做到这一点:
app.use(function (req, res, next) { res.locals.uuid = uuid.v4(); next(); });
然后在每个需要帮助器的加载中间件模块中(向helpers.log方法中添加一个新的参数):
const helpers = require('helpers'); router.post('/', (req, res, next) => { helpers.log('my log message', 'myLogName', res.locals.uuid); next(); });
这通常会起作用。 但假设有大量或中等规模的项目,其中有数百个定制模块和模型(而不是中间件)和一个模块,可能需要其他模块需要最后需要辅助模块的其他模块。 在这种情况下,我应该将res.locals.uuid作为parameter passing给每个方法的每个方法,以便在logging器方法中使用它。 不是一个好主意。 假设我有一个名为dbmodel.js的新模块,它在中间件function中是必需的:
const helpers = require('helpers'); let dbmodel = {}; dbmodel.getSomeData = (someParam) => { //some logic helpers.log('my log message', 'myLogName'); } module.exports = dbmodel;
如果我不从中间件传递数据,dbmodel不知道res.locals数据,所以helpers.log方法也不知道这个。
在PHP中,通常会在应用程序的入口点写一个GLOBAL var,所以假设的logging器函数可以从任何应用程序类的每个方法请求中访问这个全局variables。
希望这个解释能帮助:)谢谢
编辑2
这种问题的解决scheme是CLS 。 感谢@robertklep的提示。 一个很好的slideshare解释完全相同的问题(具有唯一ID的logging器)并解释CLS解决scheme可以在这里find: https : //www.slideshare.net/isharabash/cls-and-asynclistener
我在这里回答了一个非常类似的问题,可以解决这个问题。 我用来解决库节点uuid和continuation-local-storage的问题。 看看这个问题的答案,看看是否有帮助:
NodeJS Express – 全球唯一的请求ID
而你想要一个更大的解释,看看这里:
Express.js:使用全局唯一请求标识logging信息 – Node.js
是的,你可以用一种方法做到这一点。
每个请求都会通过他的路由传递给中间件。 假设你有
app.get('/', function(req, res) { res.sendFile(path.join(public + "index.html")); });
一个要求。
把中间件放在它里面,编辑req字段,这样你将得到每个请求的唯一variables值
看看这个。 https://expressjs.com/en/guide/writing-middleware.html
喜欢这个
var requestTime = function (req, res, next) { req.requestTime = Date.now() next() } app.use(requestTime) app.get('/', function (req, res) { var responseText = 'Hello World!<br>' responseText += '<small>Requested at: ' + req.requestTime + '</small>' res.send(responseText) })
这里req.requestTime是每个请求唯一的。