| Basic logger |
pino() |
Defaults: level info, JSON to stdout |
| Set level |
pino({ level: 'debug' }) |
fatal > error > warn > info > debug > trace |
| Log with context |
logger.info({ userId }, 'msg') |
First arg is merged object, second is message |
| Error logging |
logger.error({ err }, 'failed') |
Pass errors as err key for serialization |
| Child logger |
logger.child({ requestId }) |
Bindings persist on all child logs |
| Redaction |
pino({ redact: ['password'] }) |
Paths use dot notation, supports wildcards |
| Transport (worker) |
pino({ transport: { target } }) |
Runs in worker thread, non-blocking |
| Multiple transports |
transport: { targets: [...] } |
Different levels per destination |
| Pretty print (dev) |
target: 'pino-pretty' |
Dev only — not for production |
| File transport |
target: 'pino/file' |
Built-in, with mkdir option |
| Rotating files |
target: 'pino-roll' |
Size and time-based rotation |
| HTTP middleware |
pinoHttp() from pino-http |
Auto request/response logging |
| Request ID |
genReqId option in pino-http |
Generate or forward X-Request-Id |
| Serializers |
serializers: { req, res, err } |
Transform objects before logging |
| Formatters |
formatters: { level, log } |
Rename fields, transform output |
| Custom levels |
customLevels: { http: 35 } |
Add levels between built-in ones |
| Async destination |
pino.destination({ sync: false }) |
Buffered async writes |
| Fastify |
fastify({ logger: true }) |
Built-in pino, request.log |
| Hono |
hono-pino middleware |
c.get('logger') in handlers |