# How to Configure spdlog Using Environment Variables at Runtime

> Configure spdlog levels at runtime using environment variables. Call load_env_levels() early in main() to set log levels globally or per-logger without recompiling.

- Repository: [Gabi Melman/spdlog](https://github.com/gabime/spdlog)
- Tags: how-to-guide
- Published: 2026-07-20

---

**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`](https://github.com/gabime/spdlog/blob/main/spdlog/cfg/env.h) and call `spdlog::cfg::load_env_levels()` before creating or using any loggers.

```cpp
#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`](https://github.com/gabime/spdlog/blob/main/src/cfg.cpp) expects comma-separated values without spaces. Valid level strings are `trace`, `debug`, `info`, `warn`, `error`, `critical`, and `off`.

```bash

# 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()`:

```cpp
// 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`](https://github.com/gabime/spdlog/blob/main/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`](https://github.com/gabime/spdlog/blob/main/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`](https://github.com/gabime/spdlog/blob/main/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`](https://github.com/gabime/spdlog/blob/main/include/spdlog/cfg/env.h) and [`src/cfg.cpp`](https://github.com/gabime/spdlog/blob/main/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.