21

提供 HTTP 请求后,我想记录发送/接收的字节数。

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

解决方案必须位于 HTTP 方面,但我没有看到用于获取所需数据的方法。

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

4

2 回答 2

16

不幸的是,我从来没有找到合适的方法来做到这一点。我已经采取了一些相当可怕的打鸭方法,但它适用于我的特定用例。如果其他人遇到此问题,您可以从这里开始并从那里进行改进。

模块 #1:“额外事件”

这个模块所做的就是让响应对象发出一个finishBeforeSocketDestroy事件。由于我在我的应用程序的几个地方需要这个事件,我有效地为这个鸭拳制作了一个单独的模块。 app.use()它在模块 #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:“统计”

该模块创建一个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();
}

就像我说的……乱七八糟。我只是发布它,因为打鸭可能是你唯一的选择。另请注意,socket可能会重复用于多个 HTTP 请求,如果您不小心,可能会导致您重复计算某些字节。

于 2013-10-08T05:20:30.263 回答
2

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

// server.onRequest:
  ...
  req._prevBytesWritten = 0;

// response.onFinish/onEnd:
  ...
  responseLen = req.socket.bytesWritten - req._prevBytesWritten;
  req._prevBytesWritten = req.socket.bytesWritten;
于 2017-05-03T08:06:13.963 回答