Structured Logs Out of the Box
Pino Logging
Fastify uses Pino — a fast structured JSON logger with per-request child loggers and a pino-pretty transport for development.
What you'll learn
- Enable the logger via Fastify factory options
- Use app.log and request.log
- Switch to pretty output during development
Fastify integrates Pino directly, so every app gets fast structured logging without extra setup.
Enabling the Logger
const app = Fastify({
logger: {
level: process.env.LOG_LEVEL ?? 'info',
},
}); By default each request logs incoming request and request completed lines with reqId,
method, URL, status, and response time.
App and Request Loggers
app.log.info({ version: '1.0.0' }, 'booting');
app.post('/login', async (req) => {
req.log.info({ email: req.body.email }, 'login attempt');
return { ok: true };
}); request.log is a child logger pre-bound with the reqId, so every line tied to that request
is correlated.
Pretty Output in Dev
npm i -D pino-pretty const app = Fastify({
logger: {
level: 'debug',
transport:
process.env.NODE_ENV !== 'production'
? { target: 'pino-pretty', options: { colorize: true } }
: undefined,
},
}); Production keeps raw JSON so log aggregators (Loki, Datadog, CloudWatch) can index every field.
Per-Route Log Level
You can tune verbosity for a single noisy route:
app.get('/healthz', { logLevel: 'warn' }, async () => ({ ok: true }));