---
name: pino
description: Guides AI agents to use Pino logging correctly — levels, structured logs, child loggers, and Fastify integration.
metadata:
  tags:
    - pino
    - logging
    - fastify
    - nodejs
---

# Pino Skill

Use this skill when writing any logging code with Pino: creating loggers, choosing log levels, adding context, or configuring Fastify's built-in logger.

## When to Use

- Configuring the Fastify logger at startup
- Adding log statements to route handlers, plugins, or services
- Creating child loggers with bound context
- Logging errors with full detail
- Configuring log output for development vs. production

## Rules

1. [rules/levels.md](rules/levels.md) — When to use each log level (`trace`, `debug`, `info`, `warn`, `error`, `fatal`).
2. [rules/structured-logging.md](rules/structured-logging.md) — How to write structured log entries with context objects.
3. [rules/child-loggers.md](rules/child-loggers.md) — Creating child loggers to bind persistent context (request ID, user ID, module name).
4. [rules/fastify-integration.md](rules/fastify-integration.md) — Fastify logger configuration, `request.log`, and serializers.

## Quick Reference

```js
// Fastify uses Pino by default — enable it at startup
const app = Fastify({ logger: true });

// In route handlers, always use request.log (bound to request id)
fastify.get('/users/:id', async (request) => {
  request.log.info({ userId: request.params.id }, 'fetching user');
  const user = await db.findUser(request.params.id);
  if (!user) {
    request.log.warn({ userId: request.params.id }, 'user not found');
    throw fastify.httpErrors.notFound();
  }
  return user;
});

// Log errors with the err key — Pino serializes Error objects automatically
try {
  await riskyOp();
} catch (err) {
  request.log.error({ err }, 'riskyOp failed');
  throw err;
}
```
