100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Node.js

Logging in Node.js Apps

Learn why console.log is insufficient in production and how to implement structured logging with Winston or Pino.

Testing & DebuggingIntermediate10 min readJul 8, 2026
Analogies

Introduction

Logging records what an application is doing at runtime, which is essential for diagnosing issues in production. While console.log() is convenient during development, production applications need structured, leveled, and configurable logging provided by dedicated libraries such as Winston or Pino, which support log levels, JSON output, and multiple transports.

🏏

Cricket analogy: A commentator's quick shout during a friendly net session is fine, but a Test match needs the official scorer logging every ball, run, and dismissal in a structured scorecard for later review.

Syntax

javascript
// Using Winston
const winston = require('winston');

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  transports: [
    new winston.transports.Console(),
    new winston.transports.File({ filename: 'error.log', level: 'error' }),
  ],
});

logger.info('Server started');
logger.error('Something failed', { errorCode: 500 });

Explanation

console.log() writes unstructured text to stdout with no severity levels, no timestamps by default, and no way to route output to files or external services. Structured logging libraries like Winston and Pino solve this by supporting log levels (error, warn, info, debug), outputting logs as JSON for easy parsing by log aggregators (like ELK or Datadog), and supporting multiple transports so the same log call can write to the console, a file, and a remote service simultaneously. Pino is optimized for very high throughput with minimal overhead, making it a popular choice for performance-sensitive services.

🏏

Cricket analogy: Shouting the score across the field with no record is like console.log; a proper scorebook records overs, wickets, and timestamps in structured columns that Winston or Pino mimic with JSON fields.

Example

javascript
// Using Pino with Express
const express = require('express');
const pino = require('pino');
const pinoHttp = require('pino-http');

const logger = pino({
  level: process.env.LOG_LEVEL || 'info',
  transport: {
    target: 'pino-pretty', // human-readable output in development
  },
});

const app = express();
app.use(pinoHttp({ logger }));

app.get('/api/orders/:id', (req, res) => {
  req.log.info({ orderId: req.params.id }, 'Fetching order');

  if (req.params.id === '404') {
    req.log.warn({ orderId: req.params.id }, 'Order not found');
    return res.status(404).json({ error: 'Not found' });
  }

  res.json({ id: req.params.id, status: 'shipped' });
});

app.listen(3000, () => {
  logger.info('Server listening on port 3000');
});

Output

By default Pino emits newline-delimited JSON, e.g. {"level":30,"time":1690000000,"msg":"Fetching order","orderId":"404"}. With pino-pretty in development, the same log prints as readable colored text with a timestamp and level label. pino-http automatically logs each incoming request and its response status, and the req.log calls include contextual fields like orderId that are easy to filter and search in a log aggregation tool.

🏏

Cricket analogy: Pino's compact JSON line is like the raw ball-by-ball data feed a broadcaster receives, while pino-pretty is the commentator translating that feed into readable, colorful commentary for viewers at home.

Key Takeaways

  • console.log() lacks severity levels, structured output, and transport routing, making it unsuitable alone for production.
  • Winston and Pino support log levels (error, warn, info, debug) and multiple transports (console, file, remote services).
  • Structured JSON logs are easy to parse and search using log aggregation platforms like ELK or Datadog.
  • Pino is designed for high throughput with low overhead, while Winston offers rich configurability and formatting options.

Practice what you learned

Was this page helpful?

Topics covered

#NodeJs#NodeJsExpressStudyNotes#WebDevelopment#LoggingInNodeJsApps#Logging#Node#Apps#Syntax#StudyNotes#SkillVeris