Maikel Ruiz
Maikel Ruiz

Reputation: 1462

Logging requests and responses in express middleware

I'm trying to implement a logger in an Express application. I need it to be able to log requests and the response (status code and body) sent back for each request. I started writing a middleware that looks like this:

function (req, res, next) {
    ...
    res.on('finish', function () {
       Logger.debug('For request', req);
       Logger.debug('Response sent');
    });
    ...
}

I need to access the data passed to the res object method used to send the response. For example, if in one controller I had:

res.json({ foo: 'bar' })

I need a way to get that { foo: 'bar' } object, something like this maybe:

function (req, res, next) {
    ...
    res.on('finish', function () {
       Logger.debug('For request', req);
       var data = res.data; // or res.body, or whatever
       Logger.debug('Response: ' + res.statusCode, data);
    });
    ...
}

Is there any property or method in the Express res object that I could use for that? Or, is there a better strategy for logging requests and the responses for them?

Upvotes: 9

Views: 17687

Answers (2)

Jakub Kukul
Jakub Kukul

Reputation: 14582

I found an existing module, morgan-body that accomplishes what you're trying to do.

Here's how you'd use the middleware, per the documentation:

const morganBody = require('morgan-body');
const bodyParser = require('body-parser');
const express = require("express");

const app = express();

// must parse body before morganBody as body will be logged
app.use(bodyParser.json());

// hook morganBody to express app (Unlike typical express middleware you're passing the actual app into the function)
morganBody(app);

This answer could be useful if you want to use an out of the box solution or are looking for some reference points on how to implement it yourself.

Upvotes: 5

muratgozel
muratgozel

Reputation: 2609

You need an event listener that will be triggered when response.end (or send) methods are called. Express doesn't have such listener but node.js raw api does have.

There is a finish event in node.js http server instances which makes you able to do things after you sent your response to the client.

You can easily integrate with your existing Express server:

response.on('finish', () => {
  // Do your logging here.
});

I recommend that save your logs in a javascript object during request and send them inside of finish event's callback when response has sent.

Upvotes: 9

Related Questions