Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Express.js/Node disable certain request logs

Express.js/Node disable certain request logs

Problem

I have a script on a javascript page that polls a express path /api/foo. This often returns 304 (unchanged). How can I disable the console.log logging for just the 304 response?

Problem courtesy of: Christian Stewart

Solution

UPDATE: I successfully made changes to the Logger in Connect to address this problem (see history below). Those changes were included in Morgan, which is the replacement for logger when it was removed from Connect. See the Morgan documentation for the skip function property, which solves this problem neatly.

I have good news and bad news. The good news is that it can be done. The bad news is that it can't be done without modifying the logger.

The Express/Connect logger does actually do the logging after the route handler is invoked (unless you specify the immediate option when you create the logger). It does this by attaching itself to some Node events ('finish' and 'close', one of which will always be called before the response is sent to the client):

res.on('finish', logRequest);
res.on('close', logRequest);

(logRequest is an internal function that actually does the logging.)

So the problem is, there's no point of extensibility: we could also listen for those events, but we can't intercept or conditionally control the handler that the logger injects. There's no effective way to wrap the logger middleware to do conditional logging.

So there are two ways we can solve this problem. One is to write our own logger. That's actually not that horrible a proposition (it essentially replicates what logger is already doing):

app.use(function(req,res,next){

   function logRequest(){
      res.removeListener('finish', logRequest);
      res.removeListener('close', logRequest);
      if(res.statusCode!==304){
          console.log(/*whatever you want to actually log...*/);
      }
    };

    res.on('finish', logRequest);
    res.on('close', logRequest);
});

This isn't a great solution. The built-in logger does a lot for you, including all that snazzy built-in formatting. But for a quick and dirty solution, this could suffice.

Another solution is to modify logger itself. I basically downloaded the current logger source code (https://github.com/senchalabs/connect/blob/master/lib/middleware/logger.js), then modified the logRequest function (inside the logger method):

function logRequest(){
  res.removeListener('finish', logRequest);
  res.removeListener('close', logRequest);
  if(options.skip && options.skip(req,res)) return;
  var line = fmt(exports, req, res);
  if (null == line) return;
  stream.write(line + '\n');
};

You'll see that I check a function called options.skip; if that function returns true for the given request and response, logging is skipped. Save this file as conditionalLogger.js, install the lone dependency (npm install bytes --save), and then you're ready to rock and roll:

var logger = require('./conditionalLogger.js')({
    format: 'dev',
    skip: function(req,res) {
        return res.statusCode===304;
    }
});

This is a much more flexible solution in that we can now skip logging on pretty much any condition we want.

However, the downside (and it's a big one) is that now we've essentially forked some Connect code, and that's...something.

I think this is good functionality, so I'm going to go ahead and submit a pull request for this...we'll see if Sencha Labs likes it...I'll update this answer if so.

Solution courtesy of: Ethan Brown

Discussion

View additional discussion.



This post first appeared on Node.js Recipes, please read the originial post: here

Share the post

Express.js/Node disable certain request logs

×

Subscribe to Node.js Recipes

Get updates delivered right to your inbox!

Thank you for your subscription

×