Logging for JavaScript (Node.js): Best Solutions

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Logging for JavaScript (Node.js): Best Solutions



Logging is the foundation of monitoring and debugging any web application. In the Node.js world, there are several mature and popular libraries that allow flexible configuration of log collection, formatting, and storage. In this article, we will look at four best solutions: Winston, Pino, Bunyan, and Morgan. You will learn their features, strengths, and get practical usage examples.



Why do you need logging in Node.js?

Unlike browser JavaScript, a server-side application runs without direct access to the developer console. Logs allow you to:

  • Track errors and exceptions in real time.
  • Analyze performance (response time, requests).
  • Record audit events (user login, data changes).
  • Integrate with external monitoring systems (ELK, Datadog, Splunk).


1. Winston — The Universal Standard

Winston is the most popular logging library for Node.js. Its main advantage is transports (where to write logs) and formats (how to represent them).

Installation:

npm install winston


Basic setup example:

const winston = require('winston');

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

logger.info('Server started on port 3000');logger.error('Database connection error', { db: 'main' });


Key features:

  • Support for multiple transports (console, file, HTTP, MongoDB, Elasticsearch).
  • Custom formats (JSON, plain text, with timestamps).
  • Filtering by level (error, warn, info, verbose, debug, silly).
  • Creating child loggers for different modules.

When to choose: for complex projects that require flexible log routing and integration with external services.



2. Pino — Ultra-Fast Logger

Pino is built for maximum performance. It is 5-10 times faster than Winston due to the use of structured JSON and minimal overhead.

Installation:

npm install pino


Usage example:

const pino = require('pino');

const logger = pino({ level: 'info', transport: { target: 'pino-pretty', // for pretty console output options: { colorize: true } }});

logger.info({ user: 42 }, 'User logged in');logger.error(new Error('Failed to load file'));


Features:

  • Minimal CPU and memory consumption.
  • Built-in support for pino-pretty for development.
  • Works with streams for integration with other tools.
  • Automatic object serialization without performance loss.

When to choose: for high-load applications (APIs, microservices) where every millisecond counts.



3. Bunyan — Structured Logs from Joyent's Creators

Bunyan from Joyent (the creators of Node.js) focuses on a strict log structure. Each message is a JSON object with mandatory fields (hostname, pid, time).

Installation:

npm install bunyan


Example:

const bunyan = require('bunyan');

const logger = bunyan.createLogger({ name: 'myapp', streams: [ { level: 'info', stream: process.stdout }, { level: 'error', path: 'error.

Recommendations