Skip to content
Skillv1.0.0

pino

Log in Node.js with Pino. Use when a user asks to add structured logging, improve logging performance, configure log levels, format logs for production, or replace console.log with proper logging.

by terminalskills(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from terminalskills/skills (skills/pino/SKILL.md). Install upstream with npx skills add terminalskills/skills --skill pino. Copyright stays with the author (Apache-2.0).

Pino

Overview

Pino is the fastest Node.js logger — 5x faster than Winston. It outputs structured JSON logs by default, making them parseable by log aggregators (Datadog, Loki, ELK). Async logging ensures logging never blocks the event loop.

Instructions

Step 1: Basic Setup

// lib/logger.ts — Pino configuration
import pino from 'pino'

export const logger = pino({
  level: process.env.LOG_LEVEL || 'info',
  transport: process.env.NODE_ENV === 'development'
    ? { target: 'pino-pretty', options: { colorize: true } }    // pretty-print in dev
    : undefined,                                                   // JSON in production
  formatters: {
    level: (label) => ({ level: label }),                         // "level": "info" not "level": 30
  },
  base: {
    service: 'api',
    version: process.env.npm_package_version,
  },
})

// Usage
logger.info('Server started')
logger.info({ port: 3000, env: 'production' }, 'Server listening')
logger.error({ err, userId: '123' }, 'Payment processing failed')
logger.warn({ latencyMs: 2500, endpoint: '/api/reports' }, 'Slow request detected')

Step 2: Express Integration

// server.ts — Request logging middleware
import express from 'express'
import pinoHttp from 'pino-http'
import { logger } from './lib/logger'

const app = express()

app.use(pinoHttp({
  logger,
  autoLogging: true,
  customLogLevel: (req, res, err) => {
    if (res.statusCode >= 500 || err) return 'error'
    if (res.statusCode >= 400) return 'warn'
    return 'info'
  },
  customSuccessMessage: (req, res) =>
    `${req.method} ${req.url} ${res.statusCode}`,
  serializers: {
    req: (req) => ({
      method: req.method,
      url: req.url,
      query: req.query,
      userAgent: req.headers['user-agent'],
    }),
    res: (res) => ({
      statusCode: res.statusCode,
    }),
  },
}))

Step 3: Child Loggers

// Add context that persists across a request lifecycle
function createRequestLogger(req) {
  return logger.child({
    requestId: req.headers['x-request-id'] || crypto.randomUUID(),
    userId: req.user?.id,
    ip: req.ip,
  })
}

// Every log from this logger includes requestId, userId, ip
const reqLogger = createRequestLogger(req)
reqLogger.info('Processing order')
reqLogger.info({ orderId: 'ord_123', amount: 99.99 }, 'Order created')
// Output: {"level":"info","requestId":"abc-123","userId":"user-456","orderId":"ord_123","amount":99.99,"msg":"Order created"}

Guidelines

  • Always use structured JSON logging in production — not string interpolation.
  • Context first, message second: logger.info({ orderId }, 'Order created') not logger.info('Order created for ' + orderId).
  • Use child loggers to add request context (requestId, userId) that propagates to all logs.
  • Pino's async mode (pino({ transport })) prevents logging from blocking the event loop.
  • Use pino-pretty only in development — JSON logs are for machines, not humans.

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/terminalskills-skills-pino/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

terminalskills-skills-pino.ocm.jsonjson
{
  "ocm": "1",
  "id": "terminalskills-skills-pino",
  "kind": "skill",
  "name": "pino",
  "description": "Log in Node.js with Pino. Use when a user asks to add structured logging, improve logging performance, configure log levels, format logs for production, or replace console.log with proper logging.",
  "publisher": "terminalskills",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "general"
    ],
    "tags": [
      "skill-md",
      "pino",
      "logging",
      "nodejs",
      "structured",
      "observability",
      "skills-sh"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "Log in Node.js with Pino. Use when a user asks to add structured logging, improve logging performance, configure log levels, format logs for production, or replace console.log with proper logging."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "skills.sh",
      "repository": "https://github.com/terminalskills/skills",
      "path": "skills/pino/SKILL.md",
      "ref": "HEAD",
      "url": "https://github.com/terminalskills/skills/blob/HEAD/skills/pino/SKILL.md",
      "key": "terminalskills/skills/skills/pino/SKILL.md"
    },
    "compatibility": "Node.js 16+, Express, Fastify, Next.js",
    "license": "Apache-2.0"
  },
  "instructions": "# Pino\n\n## Overview\n\nPino is the fastest Node.js logger — 5x faster than Winston. It outputs structured JSON logs by default, making them parseable by log aggregators (Datadog, Loki, ELK). Async logging ensures logging never blocks the event loop.\n\n## Instructions\n\n### Step 1: Basic Setup\n\n```typescript\n// lib/logger.ts — Pino configuration\nimport pino from 'pino'\n\nexport const logger = pino({\n  level: process.env.LOG_LEVEL || 'info',\n  transport: process.env.NODE_ENV === 'development'\n    ? { target: 'pino-pretty', options: { colorize: true } }    // pretty-print in dev\n    : undefined,      ",
  "cost": {
    "context_tokens": 746
  }
}

Fetch it by URL: GET /api/v1/registry/terminalskills-skills-pino/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.