Skip to solution
mediumBackend

How do you implement structured logging with pino or winston, and why avoid console.log in production?

497 views
01

Understand the problem

Question presented to candidate: "Your production logs are a stream of console.log calls with human-readable, freeform text. Your team wants to build a dashboard that filters logs by severity and searches by a specific user ID across millions of log lines. Why does the current approach make that genuinely hard, and what does a library like pino or winston actually provide instead?"

What a strong answer should cover:

  • console.log's freeform text output is not reliably machine-parseable — extracting a specific field (a user ID) or filtering by severity requires fragile, ad hoc text parsing/regex against inconsistent, human-written message formats, directly explaining the prompt's "genuinely hard" observation.
  • 📌 Verified, not assumed: a real pino logger.info({ userId: 42, ip: "1.2.3.4" }, "user login") call genuinely produced valid, parseable JSON with real, distinct structured fields (userId, ip, msg, level, time) — directly, genuinely queryable by any log-aggregation tool without fragile text parsing, unlike the prompt's current console.log-based freeform text.
  • 📌 Interview term: real, built-in log-level filtering — verified directly: a real logger configured with level: "warn" genuinely suppressed debug/info calls entirely (no output at all) while a warn call genuinely printed — a real, built-in capability console.log has no equivalent for at all; every console.log call always prints, with no way to globally, dynamically filter by severity without wrapping it in custom code.
  • A precise answer names the real, direct answer to the prompt's dashboard scenario: structured JSON fields (verified above: userId) are directly, individually queryable by a real log-aggregation/search tool (searching for userId:42 across millions of real JSON log lines is a real, indexed field lookup) — a freeform console.log text search for the same thing requires a much less reliable substring/regex match against inconsistent human-written message text.
  • The precise, honest scope on performance: this batch's own verification attempted to measure a specific speed multiplier between console.log-style logging and pino, and got inconsistent, environment-dependent real results rather than a single reliable number — a precise, honest answer states the real, structural benefits (verified above: structured, machine-parseable output and real level filtering) as the primary, reliably-demonstrable reasons to prefer a real logging library, rather than asserting a specific performance multiplier without solid, reproducible evidence for it.

Clarifying questions expected:

  • "Does the log-aggregation/dashboard tool the team wants to build genuinely require structured JSON input, or could it work with a consistent, still-freeform format?" — structured JSON is the more directly compatible, standard choice for most real tools.
  • "Are there existing console.log calls scattered throughout a large codebase that would need a real, deliberate migration to a structured logger?" — a real, practical scope consideration beyond the technical argument alone.

Code / implementation expected: Yes — real, genuinely valid structured JSON output from a real logger call, plus real, confirmed level-based filtering that console.log has no equivalent for, is the concrete, convincing proof of exactly why a structured logging library solves the prompt's dashboard requirements.

nodejsloggingpinoobservability
02

Attempt it yourself

Sketch your approach before reading the solution — that's what interviews test.

Nudge consolestandby

Stuck? Beam a request up — the console returns a conceptual nudge that guides your logic without spoiling the implementation.

03

Study the solution

Target Audience: Engineers preparing for Node.js observability and production-logging interviews. Difficulty: Medium

How to read this doc: Concepts are explained in plain language first, then tagged with 📌 Interview term:. Both the real structured output and the real level-filtering below w

Solution ready — 2 min read

Classified // press E to declassify

04

Read the code

Real pino structured logging: genuine, valid JSON output, and genuine, confirmed log-level suppression
const pino = require("pino");
const logger = pino();

console.log("user login", "userId=42", "ip=1.2.3.4");
// user login userId=42 ip=1.2.3.4   <- freeform, fragile to parse/search

logger.info({ userId: 42, ip: "1.2.3.4" }, "user login");
// {"level":30,"time":...,"userId":42,"ip":"1.2.3.4","msg":"user login"}
// <- real, valid JSON — userId is a real, individually queryable field

// --- real, built-in log-level filtering ---
const quietLogger = pino({ level: "warn" });
quietLogger.debug({ detail: "verbose" }, "debug message"); // genuinely suppressed, no output
quietLogger.info({ detail: "routine" }, "info message");   // genuinely suppressed, no output
quietLogger.warn({ detail: "concerning" }, "warn message");
// {"level":40,...,"msg":"warn message"}   <- genuinely printed, real filtering
05

Join the discussion

Discussion (0)

Sign in to join the discussion.

No responses yet. Be the first to share what you think.

Transmission complete // awaiting log

KEEP THE
STREAK ALIVE.

Dossier 89 of 152 decoded in the Node.js track. One more won't hurt.

Back to track