Learn / Frameworks / Express / Logging and Request Ids

Express · Lesson 14 of 15

Logging and Request Ids

Structured logs with pino, a request id, and what never to log.

  • Advanced
  • 14 min read
  • 3 objectives

Before this lessonLesson 13: Layered Project Structure

What you will learn

  • Log JSON
  • Stamp a request id
  • Redact secrets

Your Progress

0 of 15 lessons 0%

  • Lessons0 / 15
  • Completed0
  • Est. time left~ 4 hours

Create a free account to keep your progress on every device.

console.log is not a log pipeline. Pino writes JSON, is fast, and works with request ids.

Pino HTTP

import pino from "pino";
import pinoHttp from "pino-http";
import { randomUUID } from "node:crypto";

export const logger = pino({ level: process.env.LOG_LEVEL || "info" });

app.use(pinoHttp({
  logger,
  genReqId: (req) => req.headers["x-request-id"] || randomUUID(),
  customProps: (req) => ({ userId: req.userId }),
  serializers: {
    req(req) { return { method: req.method, url: req.url }; },
  },
}));

Never log

  • Passwords, tokens, cookies, full authorization headers.
  • Entire request bodies that might contain PII.
  • Stack traces to the client (only to the log).

In development, pino-pretty makes JSON readable. In production, ship JSON to your host's log drain.

Up next · Lesson 15Deploy with DockerA production Node image, health checks, graceful shutdown and env-based config.