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.