21

对进入我的节点应用程序的所有请求进行计时的最佳方法是什么?基本上我想在请求开始时获取当前时间戳,然后在请求结束时再次获取差异并记录它。关于在 NodeJS 和 Express 中执行此操作的最佳方法的建议?

这是我的应用程序的示例(尽管比这复杂得多)。

var express = require('express'),
    http = require('http'),
    app = express();

app.get('/', function (req, res, next) {
    res.send(200, 'hi');
});

app.get('/about', function(req, res, next) {
   res.send(200, 'something else');
});

var server = http.createServer(app);
server.listen(9000);
console.log("Express server listening...");

我想计时所有请求。所以我想计时/以及/about我可能添加的任何其他端点。

4

7 回答 7

58

这可能会奏效:http ://www.senchalabs.org/connect/responseTime.html

app.use(express.responseTime());

或者做这样的事情:

app.use(function(req, res, next) { req.start = Date.now(); next(); });

app.get(...);
app.get(...);

app.use(function(req, res) { var time = Date.now() - req.start; });

这要求您的所有路线都调用next().

或者这个(与 responseTime 中间件相同,但不设置标题):

app.use(function(req, res, next) {
    var start = Date.now();
    res.on('header', function() {
        var duration = Date.now() - start;
        // log duration
    });
    next();
});

标头事件由 Express 中的 Connect 中间件触发,该中间件自版本 4 起已删除。请按照此答案获取解决方案 - https://stackoverflow.com/a/27348342/4969957

无需侦听发送标头后触发的'header'事件res,您可以侦听该'finish'事件,具体取决于您要测量的内容。

于 2013-08-30T19:03:33.297 回答
6

您可以为此使用内置console.timeconsole.timeEnd函数:

console.time('handler name');
... handle the request
console.timeEnd('handler name');

输出到控制台:

handler name: 62ms
于 2013-08-30T17:46:53.110 回答
5

您可以将模块添加到中间件morgan并像这样使用它-

const morgan = require('morgan')
...
...
const app = express()
app.use(morgan('dev'))

然后日志将如下所示:

// :method :url :status :response-time ms - :res[content-length]
GET /myroute 200 339.051 ms - 242

检查摩根:)

于 2018-02-19T11:25:15.140 回答
3

或者,如果您想要更大的时间分辨率,您可以使用process.hrtime()或使用我构建的模块,该模块使用 hrtime 但会为您提供很多额外信息,例如平均值、中位数、总时间等。该模块称为exectimer。这是一个例子:

var t = require("exectimer");

app.use(function(req, res, next) {
  var tick = new t.Tick("responseTime");
  tick.start();
  res.on('header', function() {
    tick.stop();
  });
  next();
});

// when ready check the results with this:
var responseTime = t.timers.responseTime;
console.log(responseTime.min()); // minimal response time
console.log(responseTime.max()); // minimal response time
console.log(responseTime.mean()); // mean response time
console.log(responseTime.median()); // median response time

它非常准确,具有纳秒级的分辨率,没有额外的依赖性。

于 2014-08-27T12:10:12.297 回答
2
export const measureRequestDuration = (req, res, next) => {
const start = Date.now();
res.once('finish', () => {
    const duration = Date.now() - start; 
    console.log("Time taken to process " + req.originalUrl + " is: " + 
  duration);
   });
 next();
};

接着

app.use(measureRequestDuration);
于 2021-07-17T14:53:57.030 回答
1

我想 express 的响应时间中间件是 Trevor Dixon 在第一个答案中提到的。它现在允许您设置回调以获取响应时间,以防您不需要在响应中设置 X-Response-Time 标头。https://github.com/expressjs/response-time#responsetimefn

于 2015-03-14T00:02:05.380 回答
1

当您第一次获得请求的句柄时,只需以毫秒为单位获取当前时间(例如 via new Date()),然后是您完成响应的时间,并将差值作为经过的时间(以毫秒为单位)。

http.createServer(function(req, res) {
  res.timeStart = new Date();
  // ...
  res.end(...);
  var timeStop = new Date();
  console.log('Elapsed ' + (timeStop-req.timeStart) + 'ms');
});

请注意,您可以减去日期,因为Date#valueOf()以毫秒为单位返回它们的时间。

于 2013-08-30T17:40:09.603 回答