Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js + Express - How to log the request body and response body

I have a small api I have built using Node.js and express. I am trying to create a logger and I need log the request body AND response body.

app.use((req, res) => {

    console.log(req);            

    res.on("finish", () => {

        console.log(res);

    });

});

"express": "^4.16.3",

However, i am not able to find the body in the req or res object. Please tell me how i can get them. thanks.

like image 244
Kay Avatar asked Sep 13 '18 09:09

Kay


People also ask

How do I get a body from Express request?

Express has a built-in express. json() function that returns an Express middleware function that parses JSON HTTP request bodies into JavaScript objects. The json() middleware adds a body property to the Express request req . To access the parsed request body, use req.

How do you do the log Express response?

To log the response body with Express, we can create our own middleware to intercept the response and log it. const logResponseBody = (req, res, next) => { const oldWrite = res. write const oldEnd = res.


3 Answers

For res.body try the following snippet:

const endMiddleware = (req, res, next) => {
  const defaultWrite = res.write;
  const defaultEnd = res.end;
  const chunks = [];

  res.write = (...restArgs) => {
    chunks.push(new Buffer(restArgs[0]));
    defaultWrite.apply(res, restArgs);
  };

  res.end = (...restArgs) => {
    if (restArgs[0]) {
      chunks.push(new Buffer(restArgs[0]));
    }
    const body = Buffer.concat(chunks).toString('utf8');

    console.log(body);

    defaultEnd.apply(res, restArgs);
  };

  next();
};

app.use(endMiddleware)

// test
// HTTP GET /
res.status(200).send({ isAlive: true });
like image 160
Sid Avatar answered Nov 02 '22 08:11

Sid


You need body-parser that will create body object for you in your request.
To do that npm install body-parser

var bodyParser = require('body-parser')//add this

app.use(bodyParser())//add this before any route or before using req.body

app.use((req, res) => {
  console.log(req.body); // this is what you want           

  res.on("finish", () => {

    console.log(res);

  });

});
like image 11
Rajan Lagah Avatar answered Nov 02 '22 10:11

Rajan Lagah


Ran into this problem but didn't like the solutions. An easy way is to simply wrap the original res.send or res.json with your logger.

Put this as middleware before your routes.

app.use(function responseLogger(req, res, next) {
  const originalSendFunc = res.send.bind(res);
  res.send = function(body) {
    console.log(body);    // do whatever here
    return originalSendFunc(body);
  };
  next();
});

https://github.com/expressjs/express/blob/master/lib/response.js

res.send has signature of function(body) { return this; }

like image 5
James Avatar answered Nov 02 '22 10:11

James