DEV Community

Cover image for Engineering in the Wild - EP4 -Logging vs. Console.log: The Production Reality Check
Hrishikesh Dalal
Hrishikesh Dalal

Posted on

Engineering in the Wild - EP4 -Logging vs. Console.log: The Production Reality Check

When you're first learning to code, console.log("Here 1") is your best friend. But once your app leaves your laptop and enters a production environment like AWS or DigitalOcean, your "best friend" becomes a silent killer.

In production, you aren't there to watch the terminal. You need Observability—the ability to understand exactly what happened in the past based on the data your app left behind.


Why console.log Fails in Production

  1. It’s Synchronous (mostly): In Node.js, console.log can block the event loop if you’re writing a massive amount of data, slowing down every single user on your site.
  2. No Context: A log that says "User saved" is useless if you don't know which user, when it happened, or which request ID it belongs to.
  3. No Severity Levels: You can't easily filter out "info" messages to only see "errors" when your server is crashing.
  4. Machine Unfriendly: console.log outputs plain text. If you have 1 million log lines, searching for an error with grep is slow and painful.

The Solution: Structured Logging (Winston & Pino)

Professional loggers like Winston or Pino output logs as JSON. This transforms your logs from "sentences" into "data" that machines (like Datadog, ELK Stack, or CloudWatch) can index and search instantly.

Winston: The Customization King

Winston is perfect for complex apps. Its power lies in Transports. You can send the same log to:

  • The Console (formatted and colorful for dev).
  • A File (stored locally for quick checks).
  • An External Service (like Logtail or Sentry) for long-term storage.

Pino: The Speed Demon

Pino is designed for high-performance apps (like the engine behind VerdictAI). It is up to 5x faster than Winston because it uses a "no-compromise" approach to performance and outputs JSON by default.


How to Implement Production-Level Observability

1. Use Log Levels

Stop treating all logs as equal. Use the hierarchy:

  • logger.error(): Immediate action needed (DB is down).
  • logger.warn(): Something is weird, but the app is still running.
  • logger.info(): Standard milestones (User logged in).
  • logger.debug(): Verbose info only needed during development.

2. Attach Metadata (Context)

Instead of logger.info("Order processed"), use:

logger.info({ orderId: "12345", userId: "user_99", latencyMs: 150 }, "Order processed");

Enter fullscreen mode Exit fullscreen mode

Now, you can instantly query: "Show me all orders for user_99 that took longer than 100ms."

3. Redact Sensitive Info

In a production environment (especially in legal tech or fintech), logging a user's password or API key is a security breach. Professional loggers allow you to auto-redact specific fields so they never touch your disk.


Scenario: The 3 AM Debug

Your server crashed. If you used console.log, you’re scrolling through 10,000 lines of text.

If you used Structured Logging, you go to your dashboard, filter for level: "error", and see the exact requestId and errorMessage in 2 seconds. That is the difference between a 10-minute fix and a 4-hour nightmare.


The Takeaway: console.log is for your eyes; Winston and Pino are for your future self who has to fix the app at 3:00 AM. Structure your logs, or get lost in the noise.

Top comments (0)