How to profile/benchmark node http express js requests using winston.

Winston is a great logging library for nodejs. Not only you can collect log data for your application but you can also profile any part of your application.

There is an express middleware called express-winston on github for hooking express with winston. However it lacks the option to profile incoming requests.

Below is how you may achieve this using your own middleware.

A full working example available on github.

request-profiler.js

var winston = require('winston');  
var util    = require('util');

/**
 * A winston based profiler for express
 * @constructor
 */
function RequestProfiler() {

  /**
   * Tracks and profile all requests made to non static expressjs routes
   */
  var logger = new (winston.Logger)({
    transports: [
      new (winston.transports.Console)(),
      new (winston.transports.File)({ filename: 'express.log' })
    ]
  });

  /**
   * An express middleware for profiling requests made to API
   * @returns {Function}
   */
  function profile() {
    return function(req, res, next) {
      req.profileInfo = util.format('%s %s', req.method, req.originalUrl);
      logger.profile(req.profileInfo);

      // Apply the detour to the express res.send function
      var sendFn = res.send;
      res.send = function() {
        sendFn.apply(res, arguments);
        logger.profile(req.profileInfo);
      };
      next();
    };
  }

  return {
    profile : profile
  };
}

module.exports = new RequestProfiler();

app.js

var bodyParser      = require('body-parser');  
var express         = require('express');  
var RequestProfiler = require('./request-profiler');  
var app             = express();

// Allow reading of post data
app.use(bodyParser.json());

// Routes
app.use(RequestProfiler.profile());

// Routes
app.use('/', function(req, res, next) {  
  res.send('hello');
});

// 404s
app.use(function(req, res) {  
  res.status(404).json({
    message: '404 Not found'
  });
});

// Other errors
app.use(function(err, req, res) {  
  res.status(500).json({error: err});
});


var server = app.listen(3000, function() {  
  var host = 'localhost';
  var port = server.address().port;

  console.log('Running in ' + process.env.NODE_ENV +  ' environment');
  console.log('Node app listening at http://%s:%s', host, port);
});

Sid Dahari

I'm a Full stack web developer passionate about programming languages, web technologies and operating systems with vocation for open source & clean code. I'm also a big fan of kitesurfing.

St Kilda, Melbourne, Australia
comments powered by Disqus