最近想监控一下Nodejs的性能。记录分析Log太麻烦,最简单的方式是记录每个HTTP请求的处理时间,直接在HTTP Response Header中返回。
记录HTTP请求的时间很简单,就是收到请求记一个时间戳,响应请求的时候再记一个时间戳,两个时间戳之差就是处理时间。
但是,res.send()
代码遍布各个js文件,总不能把每个URL处理函数都改一遍吧。
正确的思路是用middleware实现。但是Nodejs没有任何拦截res.send()
的方法,怎么破?
其实只要稍微转换一下思路,放弃传统的OOP方式,以函数对象看待res.send()
,我们就可以先保存原始的处理函数res.send
,再用自己的处理函数替换res.send
:
app.use(function (req, res, next) {
// 记录start time:
var exec_start_at = Date.now();
// 保存原始处理函数:
var _send = res.send;
// 绑定我们自己的处理函数:
res.send = function () {
// 发送Header:
res.set('X-Execution-Time', String(Date.now() - exec_start_at));
// 调用原始处理函数:
return _send.apply(res, arguments);
};
next();
});
只用了几行代码,就把时间戳搞定了。
对于res.render()
方法不需要处理,因为res.render()
内部调用了res.send()
。
调用apply()
函数时,传入res
对象很重要,否则原始的处理函数的this
指向undefined
直接导致出错。
实测首页响应时间9毫秒: