Course contentsShow
← Node.js
Lesson 1442 of 1,98013. Error Handling and Resilient SystemsFree lesson

Dynamic Log Level Adjustment

You will implement hot-swappable log configurations to increase detail during an incident without restarting the process.

In this lesson, you will learn how to shift your application's verbosity on the fly, allowing you to debug production incidents in real-time without the overhead of a process restart.

The Problem: Verbosity vs. Performance

In production, we usually keep log levels set to info or warn to save disk space and reduce CPU overhead. However, when an intermittent bug strikes, those high-level logs often lack the granular details (like debug or trace statements) needed to identify the root cause. Restarting your service to change a configuration file is often impossible or slow, and it might even clear the local memory state where the bug is currently hiding.

The Solution: Hot-Swappable Configuration

To implement dynamic adjustment, we decouple the log level from the static configuration file and store it in a mutable variable that the logging utility checks before writing a message. By exposing a simple HTTP endpoint or a signal listener, you can update this variable at runtime.

Consider this lightweight implementation:

let currentLogLevel = 'info';

const logger = {
  debug: (msg) => {
    if (currentLogLevel === 'debug') console.log(`[DEBUG] ${msg}`);
  },
  info: (msg) => {
    if (['debug', 'info'].includes(currentLogLevel)) console.log(`[INFO] ${msg}`);
  },
  // Update function
  setLevel: (newLevel) => {
    currentLogLevel = newLevel;
    console.log(`Log level updated to: ${newLevel}`);
  }
};

// Expose via an internal admin route
app.post('/admin/log-level', (req, res) => {
  const { level } = req.body;
  logger.setLevel(level);
  res.sendStatus(200);
});

Safety Considerations

When implementing this, ensure your setLevel endpoint is protected by strict authentication or resides on a private, internal management port. Because you are modifying global state, ensure your logging library (like pino or winston) supports dynamic level changes; most professional libraries provide built-in methods like logger.level = 'debug' that handle these state transitions safely without leaking memory or crashing the event loop.

Key Takeaway: By decoupling your log level from static config files and exposing a controlled interface to update it in memory, you gain the ability to "zoom in" on production issues instantly without disrupting your service uptime.