5

How can I log the response body in Fastify? The body doesn't seem to be exposed as part of the response object:

const fastify = require('fastify')({
  logger: {
    serializers: {
      res: function (res) { 
        // No body in req afaik
        return {  } 
      }
    }
  }
})
cyberwombat
  • 38,105
  • 35
  • 175
  • 251

2 Answers2

8

Try this:

const fastify = require('fastify')({
  logger: {
    serializers: {
      res: function (res) {
        return {
          statusCode: res.statusCode,
          payload: res.payload,
        }
      },
    }
  }
})

fastify.addHook('onSend', function (_request, reply, payload, next) {
  Object.assign(reply.res, { payload });
  next();
})

If some of your payloads are objects and you want to get them in serialize before they are - well, serialized - you can add preSerialization hook as well:

fastify
  .addHook('preSerialization', (_request, reply, payload, next) => {
    Object.assign(reply.res, { payload });
    next();
  })
  .addHook('onSend', (_request, reply, payload, next) => {
    if (!reply.res.payload) Object.assign(reply.res, { payload });
    next();
  });
dols3m
  • 1,676
  • 2
  • 16
  • 25
1

here you are a working example. I think that this kind of usage need to be used only for debugging because you are slowing down if you have many req/sec.

I have also added a JSON Schema validation as demo:

const fastify = require('fastify')({ logger: true })

fastify.register(async function (fastify, opts) {
  fastify.addHook('onSend', function (request, reply, payload, next) {
    console.log(payload);
    next()
  })

  fastify.get('/', {
    schema: {
      response: {
        '2xx': { properties: { this: { type: 'string' } } }
      }
    }
  }, async function () {
    return { this: 'is', a: 'json' }
  })
})

fastify.listen(3000)

You will get:

curl http://localhost:3000/

{"this":"is"}

Manuel Spigolon
  • 11,003
  • 5
  • 50
  • 73