How to Disable Logging in spdlog for Release Builds

Define SPDLOG_ACTIVE_LEVEL as SPDLOG_LEVEL_OFF before including any spdlog headers to completely compile out logging macros, eliminating both execution overhead and binary bloat in release builds.

The spdlog library provides compile-time log level filtering that strips logging code entirely from release binaries. By configuring the SPDLOG_ACTIVE_LEVEL macro appropriately, you can disable logging in spdlog for release builds with zero runtime cost. This approach leverages preprocessor guards in the gabime/spdlog source code to remove logging statements before compilation.

Understanding Compile-Time Log Level Filtering

spdlog implements log level filtering through preprocessor directives rather than runtime checks. In include/spdlog/common.h (lines 239-247), the library defines severity constants including SPDLOG_LEVEL_OFF, SPDLOG_LEVEL_INFO, and others. The default active level is set to SPDLOG_LEVEL_INFO (lines 241-242), which preserves info-level logging and above while compiling out debug and trace statements.

The logging macros in include/spdlog/spdlog.h (lines 281-341) check against SPDLOG_ACTIVE_LEVEL using conditional compilation. When you define this macro as SPDLOG_LEVEL_OFF, the preprocessor removes all logging calls—including spdlog::info, spdlog::warn, and spdlog::error—before the compiler generates machine code.

Setting SPDLOG_ACTIVE_LEVEL to SPDLOG_LEVEL_OFF

To completely disable logging, define SPDLOG_ACTIVE_LEVEL as SPDLOG_LEVEL_OFF prior to any spdlog header inclusion. The following pattern uses the NDEBUG macro commonly defined in release builds to conditionally disable logging:

// logging_config.h - Must be included before any spdlog header
#pragma once

#ifdef NDEBUG
    #define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_OFF
#endif
// main.cpp
#include "logging_config.h"
#include <spdlog/spdlog.h>

int main() {
    // These calls compile to nothing when NDEBUG is defined
    spdlog::info("This statement is removed in release builds");
    spdlog::warn("This warning code does not exist in the binary");
    return 0;
}

Configuration Methods

You can inject the macro definition through several build system approaches without modifying source files.

Compiler Command Line Flags

Pass the definition directly to your compiler to apply it across an entire translation unit:

GCC and Clang:

g++ -DSPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_OFF -o application main.cpp

Microsoft Visual C++:

cl /DSPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_OFF main.cpp

CMake Target Definitions

For CMake-based projects, use target_compile_definitions to set the level per target:

target_compile_definitions(your_target PRIVATE 
    SPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_OFF
)

Precompiled Headers

If your project uses precompiled headers, add the macro definition to ensure it is visible before spdlog headers are processed:

// pch.h or stdafx.h
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_OFF
#include <spdlog/spdlog.h>

Key Implementation Files

Understanding the source structure helps verify how compile-time filtering eliminates logging code:

File Purpose
include/spdlog/common.h Defines log level constants (SPDLOG_LEVEL_*) and sets the default SPDLOG_ACTIVE_LEVEL to SPDLOG_LEVEL_INFO (lines 239-247).
include/spdlog/spdlog.h Implements conditional compilation guards that enable or suppress each logging macro based on SPDLOG_ACTIVE_LEVEL (lines 281-341).
include/spdlog/tweakme.h Contains optional compile-time customization points, including examples of disabling the default logger.

Summary

  • Define SPDLOG_ACTIVE_LEVEL as SPDLOG_LEVEL_OFF before including any spdlog headers to disable logging in spdlog for release builds.
  • This compile-time approach removes logging code entirely, eliminating runtime overhead and reducing binary size compared to runtime filtering.
  • The implementation relies on preprocessor checks in include/spdlog/spdlog.h that filter macros against levels defined in include/spdlog/common.h.
  • Configure this via compiler flags, CMake definitions, or a dedicated configuration header to maintain clean separation between debug and release configurations.

Frequently Asked Questions

What is the default log level in spdlog?

According to include/spdlog/common.h, SPDLOG_ACTIVE_LEVEL defaults to SPDLOG_LEVEL_INFO if not explicitly defined by the user. This default preserves info, warning, error, and critical logging while compiling out trace and debug level statements at build time.

Does setting SPDLOG_LEVEL_OFF remove all logging overhead?

Yes. When SPDLOG_ACTIVE_LEVEL is set to SPDLOG_LEVEL_OFF, the preprocessor removes all logging macro invocations before compilation, including the formatting code and function call overhead. This creates zero runtime cost and reduces executable size compared to approaches that check log levels at runtime.

Can I disable logging at runtime instead of compile time?

While spdlog supports runtime level changes via logger::set_level(), this method retains the logging code and checks the level during execution. For release builds where logging should be completely eliminated, compile-time filtering via SPDLOG_ACTIVE_LEVEL is the recommended approach to avoid any performance penalty.

Where should I define SPDLOG_ACTIVE_LEVEL?

You must define SPDLOG_ACTIVE_LEVEL before any spdlog header is included in a translation unit. The most reliable method is to create a configuration header that you include first in every source file, or to set the definition globally via your compiler or build system flags. If defined after spdlog headers are included, the setting will not affect previously processed code.

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 →