NodeJS/Express中的时间请求

tbe*_*ais 17 node.js express

将所有请求计入我的节点应用程序的最佳方法是什么?基本上我想在请求的最开始时获取当前时间戳,然后在请求的最后再次获取,获取差异并记录它.有关在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...");
Run Code Online (Sandbox Code Playgroud)

我想要时间所有请求.所以我想要时间/和/about我可能添加的任何其他端点.

Tre*_*xon 48

这可能会起到作用:http://www.senchalabs.org/connect/responseTime.html

app.use(express.responseTime());
Run Code Online (Sandbox Code Playgroud)

或者做这样的事情:

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; });
Run Code Online (Sandbox Code Playgroud)

这要求您的所有路线都要拨打电话next().

或许这(与responseTime中间件相同,但不设置标头):

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

header事件是由快递中的Connect中间件触发的,从版本4开始删除.请按照以下答案寻求解决方案 - /sf/answers/1914383971/

您可以根据要测量的内容监听'header'事件,而不是res在发送标题后监听触发'finish'事件.

  • 批准的答案有两个问题:1)我应该注意到并不是每个请求都进入“完成”状态,在现实生活中,客户端可以在发送响应之前关闭连接。在这种情况下,Node.js 只发出 res.on('close') 事件。2) JavaScript Date 类(例如 Date.getTime())有几个缺点,例如毫秒限制(难以测量执行几分之一毫秒的函数)和时钟漂移的脆弱性。我写了一篇关于测量请求持续时间的文章,请查看(https://slao.io/blog/posts/request-duration/) (4认同)
  • 这是唯一能够理解Express中间件基础知识的答案.+1 (2认同)

cra*_*eem 7

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();
};
Run Code Online (Sandbox Code Playgroud)

进而

app.use(measureRequestDuration);
Run Code Online (Sandbox Code Playgroud)


Joh*_*yHK 6

您可以使用内置console.time和console.timeEnd函数:

console.time('handler name');
... handle the request
console.timeEnd('handler name');
Run Code Online (Sandbox Code Playgroud)

输出到控制台:

handler name: 62ms
Run Code Online (Sandbox Code Playgroud)

  • 很酷,这是否可以包装为所有路由的节点中间件? (2认同)

Dav*_*idA 5

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

const morgan = require('morgan')
...
...
const app = express()
app.use(morgan('dev'))
Run Code Online (Sandbox Code Playgroud)

然后日志将如下所示:

// :method :url :status :response-time ms - :res[content-length]
GET /myroute 200 339.051 ms - 242
Run Code Online (Sandbox Code Playgroud)

检查摩根:)