4 * Copyright(c) 2011 TJ Holowaychuk
9 * Profile the duration of a request.
11 * Typically this middleware should be utilized
12 * _above_ all others, as it proxies the `res.end()`
13 * method, being first allows it to encapsulate all
22 * heap before 3.76mb / 8.15mb
23 * heap after 3.80mb / 8.15mb
28 module.exports = function profiler(){
29 return function(req, res, next){
36 mem: process.memoryUsage()
42 res.end = function(data, encoding){
44 res.end(data, encoding);
45 compare(req, start, snapshot())
53 * Compare `start` / `end` snapshots.
55 * @param {IncomingRequest} req
56 * @param {Object} start
61 function compare(req, start, end) {
63 row(req.method, req.url);
64 row('response time:', (end.time - start.time) + 'ms');
65 row('memory rss:', formatBytes(end.mem.rss - start.mem.rss));
66 row('memory vsize:', formatBytes(end.mem.vsize - start.mem.vsize));
67 row('heap before:', formatBytes(start.mem.heapUsed) + ' / ' + formatBytes(start.mem.heapTotal));
68 row('heap after:', formatBytes(end.mem.heapUsed) + ' / ' + formatBytes(end.mem.heapTotal));
80 function row(key, val) {
81 console.log(' \033[90m%s\033[0m \033[36m%s\033[0m', key, val);
87 * @param {Number} bytes
92 function formatBytes(bytes) {
96 if (bytes < kb) return bytes + 'b';
97 if (bytes < mb) return (bytes / kb).toFixed(2) + 'kb';
98 if (bytes < gb) return (bytes / mb).toFixed(2) + 'mb';
99 return (bytes / gb).toFixed(2) + 'gb';