Categories
Fastify

Server-Side Development with Fastify — Customize Logging

Spread the love

Fastify is a small Node framework for developing back end web apps.

In this article, we’ll look at how to create back end apps with Fastify.

Customize Logging

We can also customize how responses are logged.

For instance, we can write:

const fastify = require('fastify')({
  logger: {
    prettyPrint: true,
    serializers: {
      res (reply) {
        return {
          statusCode: reply.statusCode
        }
      },
      req (request) {
        return {
          method: request.method,
          url: request.url,
          path: request.path,
          parameters: request.parameters,
          headers: request.headers
        };
      }
    }
  }
});

fastify.get('/', (request, reply) => {
  request.log.info('Some info')
  reply.send({ hello: 'world' })
})

const start = async () => {
  try {
    await fastify.listen(3000, '0.0.0.0')
  } catch (err) {
    fastify.log.error(err)
    process.exit(1)
  }
}
start()

to serialize the response log content with the res method.

And we do the same for the request with the req method.

We set prettyPrint to true to pretty print our output.

We can add a hook to our request to log the request payload by writing:

const fastify = require('fastify')({
  logger: 'info'
});

fastify.addHook('preHandler', (req, reply, done) => {
  if (req.body) {
    req.log.info({ body: req.body }, 'parsed body')
  }
  done()
})

fastify.post('/', (request, reply) => {
  reply.send({ hello: 'world' })
})

const start = async () => {
  try {
    await fastify.listen(3000, '0.0.0.0')
  } catch (err) {
    fastify.log.error(err)
    process.exit(1)
  }
}
start()

We get the req.body and put that in the req.log.info call.

Also, we can use the logger outside route handlers.

For instance, we can write:

const log = require('pino')({ level: 'info' })
const fastify = require('fastify')({ logger: log })

log.info('does not have request information')

fastify.get('/', function (request, reply) {
  request.log.info('includes request information, but is the same logger instance as `log`')
  reply.send({ hello: 'world' })
})

const start = async () => {
  try {
    await fastify.listen(3000, '0.0.0.0')
  } catch (err) {
    fastify.log.error(err)
    process.exit(1)
  }
}
start()

We call log.info outside the route handler.

And we call request.log.info inside it.

We can redact log info with the redact property.

For example, we can write:

const split = require('split2')
const stream = split(JSON.parse)

const fastify = require('fastify')({
  logger: {
    stream,
    redact: ['req.headers.authorization'],
    level: 'info',
    serializers: {
      req (request) {
        return {
          method: request.method,
          url: request.url,
          headers: request.headers,
          hostname: request.hostname,
          remoteAddress: request.ip,
          remotePort: request.socket.remotePort
        }
      }
    }
  }
})

fastify.get('/', function (request, reply) {
  reply.send({ hello: 'world' })
})

const start = async () => {
  try {
    await fastify.listen(3000, '0.0.0.0')
  } catch (err) {
    fastify.log.error(err)
    process.exit(1)
  }
}
start()

We add the redact property to add the property paths to skip in ur log.

Now we won’t see the value of req.headers.authorization in our log.

Conclusion

We can customize our logging with Fastify.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *