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

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, the implementation reads an atomic internal field:

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 (lines 40–41), this helper simply forwards the call:

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 (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 (lines 270–271), the should_log(level msg_level) method performs the comparison:

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:

#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

Summary

  • Instance method: Use logger->level() to get the level_enum of any specific logger; implemented via atomic read in logger-inl.h.
  • Global function: Use spdlog::get_level() to query the default logger's threshold; defined in 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".

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 →