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_LEVELasSPDLOG_LEVEL_OFFbefore 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.hthat filter macros against levels defined ininclude/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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →