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) declares load_env_levels() and calls details::os::getenv to retrieve the string value.
  • Parser: src/cfg.cpp implements helpers::load_levels(), which splits the string on commas, validates level names, and updates the internal registry.
  • Registry Updates: The details::registry singleton applies levels via set_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.h to access runtime configuration functions.
  • Call spdlog::cfg::load_env_levels() early in main() to read SPDLOG_LEVEL.
  • Use comma-separated syntax: optional global level followed by logger=level pairs.
  • Pass a custom string to load_env_levels() to use a different environment variable name.
  • The implementation resides in include/spdlog/cfg/env.h and src/cfg.cpp, using details::os::getenv for 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →