How to Configure spdlog Using Environment Variables at Runtime
Call spdlog::cfg::load_env_levels() early in your main() function to read the SPDLOG_LEVEL environment variable and apply log levels globally or per-logger without recompiling.
The gabime/spdlog library supports runtime configuration through environment variables, allowing you to adjust logging verbosity across your application without modifying source code or rebuilding. This feature, implemented in the spdlog/cfg module, parses comma-separated level specifications and applies them to the global default logger and named logger instances.
How Runtime Configuration Works in spdlog
When you invoke the configuration loader, spdlog queries the environment using spdlog::details::os::getenv and passes the result to spdlog::cfg::helpers::load_levels. This parser accepts a string in the format:
[level],[logger_name]=[level],...
The first optional token sets the global default level (e.g., debug, info, warn, error, critical, or off). Subsequent tokens use name=level syntax to override specific loggers. This design mirrors Rust’s env_logger crate and functions identically across all platforms spdlog supports.
Enabling Environment Variable Configuration
To activate this behavior, include the header spdlog/cfg/env.h and call spdlog::cfg::load_env_levels() before creating or using any loggers.
#include "spdlog/spdlog.h"
#include "spdlog/cfg/env.h" // Required for load_env_levels()
int main(int argc, char* argv[])
{
// Load configuration from SPDLOG_LEVEL environment variable
spdlog::cfg::load_env_levels();
// Create loggers after loading configuration
auto logger = spdlog::stdout_color_mt("my_logger");
logger->debug("This respects the environment level setting");
logger->info("Application started");
}
Place this call at the entry point of your application to ensure all loggers, including the default logger, inherit the specified levels.
SPDLOG_LEVEL Syntax and Format
The parser in src/cfg.cpp expects comma-separated values without spaces. Valid level strings are trace, debug, info, warn, error, critical, and off.
# Set global level to debug (shows all messages)
export SPDLOG_LEVEL=debug
./my_app
# Disable everything except trace messages from "network_logger"
export SPDLOG_LEVEL="off,network_logger=trace"
./my_app
# Multiple logger overrides
export SPDLOG_LEVEL="warn,db=debug,ui=error"
./my_app
If the environment variable is unset or empty, load_env_levels() makes no changes, preserving compiled-in defaults.
Using Custom Environment Variable Names
You can specify a custom variable name by passing it as an argument to load_env_levels():
// Reads from MYAPP_LOG instead of SPDLOG_LEVEL
spdlog::cfg::load_env_levels("MYAPP_LOG");
This is useful when integrating spdlog into larger applications that follow specific environment naming conventions or when avoiding conflicts with other spdlog-based components.
Implementation Details
The environment variable integration relies on three key components in the spdlog source:
- Entry Point:
include/spdlog/cfg/env.h(lines 29-31) declaresload_env_levels()and callsdetails::os::getenvto retrieve the string value. - Parser:
src/cfg.cppimplementshelpers::load_levels(), which splits the string on commas, validates level names, and updates the internal registry. - Registry Updates: The
details::registrysingleton applies levels viaset_level(), affecting the runtime filter of each logger instance.
According to the spdlog source code, the load_env_levels() function checks if the returned string is non-empty before forwarding it to the parser, ensuring that unset variables do not trigger parsing errors.
Summary
- Include
spdlog/cfg/env.hto access runtime configuration functions. - Call
spdlog::cfg::load_env_levels()early inmain()to readSPDLOG_LEVEL. - Use comma-separated syntax: optional global level followed by
logger=levelpairs. - Pass a custom string to
load_env_levels()to use a different environment variable name. - The implementation resides in
include/spdlog/cfg/env.handsrc/cfg.cpp, usingdetails::os::getenvfor cross-platform compatibility.
Frequently Asked Questions
What is the default environment variable name for spdlog configuration?
The default variable is SPDLOG_LEVEL. When you call spdlog::cfg::load_env_levels() without arguments, the function queries this specific variable. If you need to use a different name, pass it as a string parameter to the same function.
Can I configure individual logger levels separately using environment variables?
Yes. After setting a global default level, append comma-separated name=level pairs to target specific loggers. For example, SPDLOG_LEVEL="warn,database=debug,gui=off" sets the global threshold to warning, enables debug for the "database" logger, and disables the "gui" logger entirely.
Where should I call load_env_levels() in my application?
Call it immediately at the start of main(), before any logger creation or usage. Loggers instantiated after this call automatically adopt the configured levels. Loggers created before the call retain their original levels unless you manually refresh them.
Does spdlog environment variable configuration work on Windows?
Yes. The implementation uses spdlog::details::os::getenv, which abstracts platform differences. This mechanism works on Windows, Linux, macOS, and other supported platforms, making it suitable for cross-platform applications that need consistent runtime logging control.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →