NodeJS Express – 全球唯一的请求ID

是否可以定义每个日志语句中包含的唯一请求标识,而无需将logging器交给每个方法/函数调用?

使用中的技术:NodeJS,Express,Winston

我们在几个项目中遇到了同样的问题,我无法find任何完整的解决scheme。 我们使用相同的技术(Node.js,Express.js和Winston的日志)我find了一个解决scheme,使用一些库和包装温斯顿库:node-uuid创build每个请求的唯一标识符 – continuation-local-存储在不同的模块之间共享这个ID,而不用在所有的调用中发送req对象。

首先我需要创build并设置每个请求的唯一标识符。 我在中间件中做:

 var uuid = require('node-uuid'); var createNamespace = require('continuation-local-storage').createNamespace; var myRequest = createNamespace('my request'); // Run the context for each request. Assign a unique identifier to each request app.use(function(req, res, next) { myRequest.run(function() { myRequest.set('reqId', uuid.v1()); next(); }); }); 

之后,我不得不打包Winston库,从上下文恢复ID并添加到日志的消息:

 var winston = require('winston'); var getNamespace = require('continuation-local-storage').getNamespace; // Wrap Winston logger to print reqId in each log var formatMessage = function(message) { var myRequest = getNamespace('my request'); message = myRequest && myRequest.get('reqId') ? message + " reqId: " + myRequest.get('reqId') : message; return message; }; var logger = { log: function(level, message) { winstonLogger.log(level, formatMessage(message)); }, error: function(message) { winstonLogger.error(formatMessage(message)); }, warn: function(message) { winstonLogger.warn(formatMessage(message)); }, verbose: function(message) { winstonLogger.verbose(formatMessage(message)); }, info: function(message) { winstonLogger.info(formatMessage(message)); }, debug: function(message) { winstonLogger.debug(formatMessage(message)); }, silly: function(message) { winstonLogger.silly(formatMessage(message)); } }; module.exports = logger; 

我觉得这有点复杂,所以我决定把它写下来。 您可以从这里获取更多信息: Express.js:使用全局唯一请求标识logging信息 – Node.js

我希望这可以帮助你的问题。

第一个答案有一个问题:每次节点进程重新启动时,计数器都会回到0。 事实certificate,使用uuid标记每个请求的快速中间件相当简单:

const uuid = require('uuid'); const app = express(); app.use(function (req, next) { req.id = uuid.v4(); next(); });

在请求处理的一开始,添加如下内容(或将其放在自己的文件中):

 var makeID = (function() { var index = 0; return function() { return index++; } })(); app.use(function(req, res, next) { req.id = makeID() next() }) 

这将给每个请求一个唯一(顺序)的ID。 不要让人们认同它,只能在内部使用!

loginWinston时,可以input元数据,在消息之后显示(forms${name}=${value} ),看起来像这样

 app.use(function(req, res) { winston.log('info', 'Test Log Message', { id: req.id }); res.end("Done.") }); 

希望这是有帮助的。