# How to Get the Current Log Level in spdlog: Instance vs Global APIs

> Learn how to get the current log level in spdlog using instance or global APIs. Retrieve logger level with logger->level() or global level using spdlog::get_level().

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

---

**Call `logger->level()` on any logger instance to retrieve its current `spdlog::level::level_enum`, or use `spdlog::get_level()` to read the global default logger's level.**

The spdlog library stores each logger's severity threshold in an atomic variable to enable lock-free runtime inspection. Whether you are debugging configuration issues or conditionally executing diagnostic code, retrieving the current log level requires a single accessor call. This guide demonstrates both instance-level and global methods using the actual implementation from the gabime/spdlog repository.

## Retrieving the Current Log Level from a Logger Instance

Every `spdlog::logger` object exposes the member function `level()` to query its active severity threshold. The method returns a `spdlog::level::level_enum` value (`trace`, `debug`, `info`, `warn`, `err`, `critical`, or `off`) indicating which messages will actually be emitted.

According to the source in [`include/spdlog/logger-inl.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/logger-inl.h), the implementation reads an atomic internal field:

```cpp
SPDLOG_INLINE level::level_enum logger::level() const {
    return static_cast<level::level_enum>(level_.load(std::memory_order_relaxed));
}

```

This design allows you to inspect the logger's state without blocking other threads that might be concurrently logging or adjusting the level.

## Checking the Global Default Logger Level

When using the shorthand API (`spdlog::info()`, `spdlog::debug()`, etc.), you are writing to a global default logger. To retrieve its current log level, use the free function `spdlog::get_level()`.

As implemented in [`include/spdlog/spdlog-inl.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/spdlog-inl.h) (lines 40–41), this helper simply forwards the call:

```cpp
SPDLOG_INLINE level::level_enum get_level() { return default_logger_raw()->level(); }

```

This returns the same `level_enum` type, ensuring consistent comparisons whether you are working with named loggers or the global instance.

## Thread-Safety and Implementation Details

The spdlog architecture stores the log level in an `std::atomic<level_t>` member named `level_`, declared in [`include/spdlog/logger.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/logger.h) (lines 318–319). Using relaxed memory ordering for reads provides optimal performance when checking the current log level frequently.

The internal filtering mechanism uses this same atomic read. In [`include/spdlog/logger.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/logger.h) (lines 270–271), the `should_log(level msg_level)` method performs the comparison:

```cpp
should_log(level msg_level) { return msg_level >= level_.load(std::memory_order_relaxed); }

```

Because the accessor `level()` uses an identical atomic load, you can trust that the value returned matches the threshold currently used for filtering messages.

## Complete Working Example

The following example demonstrates retrieving levels from both named loggers and the global default:

```cpp
#include "spdlog/spdlog.h"
#include "spdlog/sinks/stdout_color_sinks.h"

int main()
{
    // 1️⃣ Create and configure a named logger
    auto logger = spdlog::stdout_color_mt("my_logger");
    logger->set_level(spdlog::level::warn);

    // Retrieve the current log level
    spdlog::level::level_enum current = logger->level();
    spdlog::info("Named logger level: {}", static_cast<int>(current));

    // 2️⃣ Check the global default logger
    spdlog::set_level(spdlog::level::debug);
    spdlog::level::level_enum global_level = spdlog::get_level();
    spdlog::info("Global logger level: {}", static_cast<int>(global_level));

    // 3️⃣ Conditionally execute verbose diagnostics
    if (logger->level() <= spdlog::level::info) {
        logger->info("Logger is configured for info or more verbose");
    }
}

```

**Key Implementation Files**

- [`include/spdlog/logger.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/logger.h) – Declares the `level()` accessor and the atomic `level_` member ([source](https://github.com/gabime/spdlog/blob/v1.x/include/spdlog/logger.h))
- [`include/spdlog/logger-inl.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/logger-inl.h) – Implements `logger::level()` with atomic load operations ([source](https://github.com/gabime/spdlog/blob/v1.x/include/spdlog/logger-inl.h))
- [`include/spdlog/spdlog-inl.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/spdlog-inl.h) – Implements the global `get_level()` helper that delegates to the default logger ([source](https://github.com/gabime/spdlog/blob/v1.x/include/spdlog/spdlog-inl.h))

## Summary

- **Instance method**: Use `logger->level()` to get the `level_enum` of any specific logger; implemented via atomic read in [`logger-inl.h`](https://github.com/gabime/spdlog/blob/main/logger-inl.h).
- **Global function**: Use `spdlog::get_level()` to query the default logger's threshold; defined in [`spdlog-inl.h`](https://github.com/gabime/spdlog/blob/main/spdlog-inl.h).
- **Return type**: Both APIs return `spdlog::level::level_enum`, which you can compare against constants like `spdlog::level::debug` or cast to `int` for display.
- **Thread-safety**: The underlying `std::atomic` storage ensures safe concurrent reads without locks.

## Frequently Asked Questions

### How do I check if a specific log level is enabled before logging?

Use the `should_log(level)` method, which performs the same atomic comparison used internally by the logger. For example: `if (logger->should_log(spdlog::level::debug)) { ... }`. This avoids preparing expensive log messages that would be filtered anyway.

### Is the level() method thread-safe for concurrent access?

Yes. The method reads from an `std::atomic<level_t>` using relaxed memory ordering, making it safe to call from multiple threads simultaneously without synchronization overhead. However, remember that the value represents a snapshot in time; another thread may change the level immediately after your read.

### What is the default log level when creating a new logger?

New loggers inherit the global level setting at creation time, but the default global level is typically `spdlog::level::info` unless you explicitly change it with `spdlog::set_level()`.

### Can I retrieve the log level as a string instead of an enum?

The standard `level()` accessor returns the enum. To convert it to a human-readable string, use `spdlog::level::to_short_c_str(level)` or `to_string_view(level)`, which map the enum to text representations like "debug" or "warning".