# spdlog Log Levels Explained: A Complete Guide to Severity Configuration

> Understand spdlog log levels like trace, debug, info, warn, err, critical, and off. Configure severity precisely for better control over your application logs with this complete guide.

- Repository: [Gabi Melman/spdlog](https://github.com/gabime/spdlog)
- Tags: deep-dive
- Published: 2026-07-27

---

**spdlog supports seven distinct severity levels—trace, debug, info, warn, err, critical, and off—defined in the `level::level_enum` enumeration in [`include/spdlog/common.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/common.h), enabling precise control over logging verbosity at both logger and sink granularity.**

The **gabime/spdlog** library provides a fast, header-only C++ logging framework built around a clear hierarchy of severity levels. Understanding these spdlog log levels is essential for configuring which messages are emitted during development, testing, and production environments.

## The Seven spdlog Log Levels

The `level::level_enum` enumeration declared at lines 47-55 of [`include/spdlog/common.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/common.h) defines the complete set of supported severities:

- **trace** – Very detailed debugging information; the lowest severity level available.
- **debug** – General debugging messages useful during development.
- **info** – Normal operational messages indicating successful operations.
- **warn** – Warning conditions that do not prevent execution but may require attention.
- **err** – Error conditions indicating specific failures that need handling.
- **critical** – Critical errors that may cause the program to terminate or require immediate intervention.
- **off** – Disables all logging output entirely.

The enumeration also includes an internal sentinel value `n_levels` used for bounds checking within the library's filtering logic.

## Where Log Levels Are Defined

According to the spdlog source code, the core level definitions reside in **[`include/spdlog/common.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/common.h)**. This header declares the `level::level_enum` type alongside compile-time constants (e.g., `SPDLOG_LEVEL_TRACE`) and string conversion utilities.

Each level maps to a human-readable name via `spdlog::level::to_string_view()` and a one-character short code (e.g., `"T"` for trace, `"D"` for debug) defined in the same file around lines 58-79. These string representations power the library's formatted output patterns.

## How to Configure spdlog Log Levels

You can control spdlog log levels at two granularities: the **logger** (which aggregates messages) and individual **sinks** (which write to specific destinations).

### Setting the Logger Level

Use `spdlog::logger::set_level()` to establish a minimum threshold for the entire logger. Messages below this level are filtered out before reaching any sinks.

```cpp
#include <spdlog/spdlog.h>

int main() {
    auto console = spdlog::stdout_color_mt("console");
    
    // Only emit warnings and above
    console->set_level(spdlog::level::warn);
    
    // Filtered out (below threshold)
    console->trace("trace message");
    console->debug("debug message");
    console->info("info message");
    
    // These appear in output
    console->warn("warning message");
    console->error("error message");
    console->critical("critical failure");
    
    // Disable logging completely
    console->set_level(spdlog::level::off);
}

```

### Setting Per-Sink Levels

Individual sinks can override the logger's level using `spdlog::sinks::sink::set_level()`, as implemented in [`include/spdlog/sinks/sink.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/sinks/sink.h). This enables fine-grained routing—for example, sending all debug messages to a file while only showing warnings on the console.

```cpp
#include <spdlog/spdlog.h>
#include <spdlog/sinks/basic_file_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>

int main() {
    auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("app.log");
    auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
    
    // File receives everything from trace up
    file_sink->set_level(spdlog::level::trace);
    
    // Console only shows warnings and above
    console_sink->set_level(spdlog::level::warn);
    
    spdlog::logger logger("multi", {file_sink, console_sink});
    logger.info("info goes to file only");
    logger.warn("warning appears in both file and console");
}

```

## Compile-Time Level Constants

Each spdlog log level has an associated compile-time constant defined alongside the enum, such as `SPDLOG_LEVEL_TRACE`, `SPDLOG_LEVEL_DEBUG`, and `SPDLOG_LEVEL_INFO`. These constants enable conditional compilation and macro-based filtering to eliminate logging overhead entirely at build time for specific severity levels.

## Summary

- **spdlog** defines seven severity levels in [`include/spdlog/common.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/common.h): **trace**, **debug**, **info**, **warn**, **err**, **critical**, and **off**.
- The `level::level_enum` type (lines 47-55) provides the foundation for all level-based filtering.
- Configure thresholds via `logger::set_level()` for global control or `sink::set_level()` for destination-specific filtering.
- Level names and short codes are accessible via `spdlog::level::to_string_view()` for custom formatting.
- Compile-time constants like `SPDLOG_LEVEL_TRACE` support build-time optimization.

## Frequently Asked Questions

### What is the default log level in spdlog?

By default, spdlog loggers initialize to the **info** level, meaning trace and debug messages are suppressed unless explicitly enabled via `set_level()`. This default strikes a balance between operational visibility and performance in production builds.

### How do I disable all logging in spdlog?

Set the level to `spdlog::level::off` using `logger->set_level(spdlog::level::off)`. This is the highest severity value in the enumeration and filters out every message, including critical errors. You can also apply this to individual sinks to suppress output to specific destinations while preserving logging elsewhere.

### Can I use custom log levels beyond the seven standard ones?

No, spdlog uses a fixed enumeration (`level::level_enum`) with exactly seven user-facing levels plus the `off` sentinel. While you cannot add custom severities to the enum, you can achieve similar functionality by using the **info** or **debug** levels with contextual formatting or by implementing custom sink filters that inspect message content for additional routing logic.

### What is the difference between logger level and sink level?

The **logger level** acts as a global gate; messages below this threshold are discarded before reaching any sinks. The **sink level** provides secondary filtering per output destination. A message must pass both the logger's level check and the specific sink's level check to be written to that destination, enabling sophisticated routing like debug logs to files while the console shows only warnings.