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 に答える