发送/接收的Node.js HTTP请求的字节数

一旦HTTP请求被服务,我想logging发送/接收的字节数。

这个数据的简单来源是req.connection.bytesRead / .bytesWritten 。 但是,这对于HTTP 1.1保持连接是有问题的,因为同一个套接字可以用于多个请求。 我需要logging每个请求,而不是每个连接。

解决scheme必须在HTTP的一面,但我没有看到获取我需要的数据的方法。

计算由Node.js的http.Server服务的HTTP请求读取/写入的字节的正确方法是什么?

不幸的是,我从来没有find正确的方法来做到这一点。 我使用了一些相当可怕的鸭子冲刺,但它适用于我的特殊用例。 如果有其他人绊倒这个问题,你可以从这里开始,并从那里改进。

模块#1:“额外事件”

所有这个模块做的是使响应对象发出一个finishBeforeSocketDestroy事件。 由于我在我的应用程序的几个地方需要这个事件,所以我有效地为这个鸭子打了一个单独的模块。 app.use()在Module#2之前。

 module.exports = function (req, res, next) { var end = res.end; res.end = function () { res.end = end; res.emit('finishBeforeSocketDestroy'); res.end.apply(this, arguments); } next(); } 

模块#2:“统计”

这个模块创build了一个req.stats对象,其中包含了在连接使用过程中跟踪带宽使用的各种有用的好东西,并且在完成之后。

 var pollTime = 1000; module.exports = function (req, res, next) { var pollInterval; function pollStats () { if (typeof req.stats._lastMeasuredTime === 'object') { var secondsSinceLastMeasurement = ((new Date() - req.stats._lastMeasuredTime) / 1000); req.stats.averageRate = { read: (req.socket.bytesRead - req.stats.bytesRead) / secondsSinceLastMeasurement, write: (req.socket.bytesWritten - req.stats.bytesWritten) / secondsSinceLastMeasurement }; } req.stats._lastMeasuredTime = new Date(); req.stats.bytesRead = req.socket.bytesRead; req.stats.bytesWritten = req.socket.bytesWritten; } req.stats = { startTime: new Date(), endTime: null, averageRate: {read: null, write: null}, bytesRead: req.socket.bytesRead, bytesWritten: req.socket.bytesWritten, _lastMeasuredTime: new Date() }; pollInterval = setInterval(pollStats, pollTime); res.on('finishBeforeSocketDestroy', function () { clearInterval(pollInterval); pollStats(); req.stats.endTime = new Date(); }); next(); } 

就像我说的…凌乱。 我只是把它作为鸭子冲可能是你唯一的select。 另外请注意, socket可能会被重用于多个HTTP请求,如果您不小心,可能会导致您对某些字节进行双重计数。

只需在每个响应之后存储stream量值并计算“完成”或“结束”处理程序中的差异:

 // server.onRequest: ... req._prevBytesWritten = 0; // response.onFinish/onEnd: ... responseLen = req.socket.bytesWritten - req._prevBytesWritten; req._prevBytesWritten = req.socket.bytesWritten;