6.3 KiB
Spdlog Logger Integration Summary
Overview
Integrated spdlog (high-performance C++ logging library) into the imgui-node-editor blueprints-example for Win32/ImGui. The system uses LOG_* macros that can be disabled via DISABLE_LOGGING compile flag.
Files Created/Modified
Core Logger Files
Logging.h- Simple wrapper with LOG_* macros for spdlogLogging.cpp- Initialization/shutdown using spdlogexternal/spdlog/- Copied locally (header-only mode)
Modified Files
examples/CMakeLists.txt- Added spdlog INTERFACE libraryexamples/blueprints-example/CMakeLists.txt- Added include path and/utf-8compiler flagapp.cpp- Initialize/cleanup logger withInitLogger()andShutdownLogger()app-render.cpp- Replaced key printf() calls with LOG_* macros
Features
Log Levels (spdlog)
LOG_TRACE(...) // Most verbose (detailed trace info)
LOG_DEBUG(...) // Debug information
LOG_INFO(...) // Informational messages
LOG_WARN(...) // Warnings
LOG_ERROR(...) // Errors
LOG_CRITICAL(...) // Critical errors (renamed from FATAL)
// Legacy compatibility
LOG_FATAL(...) -> LOG_CRITICAL(...)
LOG_VERBOSE(...) -> LOG_TRACE(...)
Sinks (Output Targets)
- Console Sink - Color-coded output to stdout (Windows console colors via spdlog)
- File Sink - Persistent logging to
blueprints.log
Usage
Initialization (in app.cpp::OnStart)
// Initialize spdlog logger system
InitLogger("blueprints", true, true, "blueprints.log");
// ^app name ^console ^file ^filename
Logging Examples
// Info level
LOG_INFO("[DELETE] DeleteNodeAndInstances: Starting deletion of node {} (ptr={})",
nodeId, (void *)&node);
// Error level
LOG_ERROR("[ERROR] RenderNodes: Node pointer corrupted: 0x{:x}", nodePtrValue);
// Warning level
LOG_WARN("[WARNING] RenderNodes: null node pointer in container!");
Shutdown (in app.cpp::OnStop)
// Shutdown spdlog logger
ShutdownLogger();
Architecture
Header-Only Mode
- Spdlog compiled in header-only mode (
SPDLOG_HEADER_ONLY) - No separate library linking required
- All template code included at compile time
Multi-Sink Support
- Console sink:
[HH:MM:SS] [LEVEL] message - File sink:
[YYYY-MM-DD HH:MM:SS.mmm] [LEVEL] message
Thread Safety
- Spdlog provides thread-safe logging via
_mt(multi-threaded) sinks stdout_color_sink_mtandbasic_file_sink_mtare thread-safe
Log Format
Console Output
[14:32:15] [info] === Logger System Initialized (spdlog) ===
[14:32:16] [error] Node pointer itself is corrupted: 0xDDDDDDDDDDDDDDDD
[14:32:17] [warn] null node pointer in container!
File Output (blueprints.log)
[2025-11-07 14:32:15.123] [info] === Logger System Initialized (spdlog) ===
[2025-11-07 14:32:16.456] [error] Node pointer itself is corrupted: 0xDDDDDDDDDDDDDDDD
[2025-11-07 14:32:17.789] [warn] null node pointer in container!
Advantages Over Custom Logger
Why Spdlog?
✅ Performance - Extremely fast, async logging support
✅ Feature-Rich - Rotating files, daily files, custom sinks
✅ Mature - Battle-tested library used in production
✅ Cross-Platform - Works on Windows, Linux, macOS
✅ Modern C++ - Uses C++11/14/17 features properly
✅ No Dependencies - Header-only mode, no external libs
Performance
- Zero-cost abstractions when logging is disabled
- Minimal overhead in release builds
- Optional async logging for high-throughput scenarios
Build Configuration
Required CMake Changes
-
examples/CMakeLists.txt:- Added spdlog INTERFACE library
-
examples/blueprints-example/CMakeLists.txt:# Add local spdlog include directory target_include_directories(blueprints-example PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/external") # Add /utf-8 compiler flag for spdlog on MSVC if (MSVC) target_compile_options(blueprints-example PRIVATE /utf-8) endif()
Build Verification
✅ Build successful with sh scripts/build.sh
- Spdlog compiles cleanly in header-only mode
/utf-8flag required for MSVC (Unicode support)- All LOG_* macros expand correctly
Output Files
Console
- Color-coded log messages (via spdlog wincolor_sink)
- Real-time feedback during execution
blueprints.log
- Persistent log history with millisecond precision
- Appends to existing file (doesn't overwrite)
- Full timestamp format
Configuration
Disable Logging Completely
Define DISABLE_LOGGING before including Logging.h:
#define DISABLE_LOGGING
#include "Logging.h"
All LOG_* macros become (void)0 - zero runtime cost!
Change Log Level at Runtime
// Set global level (only works if you access spdlog directly)
g_logger->set_level(spdlog::level::err); // Only errors and critical
Add Custom Sinks
// You can extend InitLogger() to add more sinks:
auto rotating_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(
"app.log", 1024*1024*5, 3); // 5MB, 3 files
g_logger->sinks().push_back(rotating_sink);
Testing
Run the application:
./build/bin/blueprints-example_d.exe
Check:
- Console - Colored log messages with timestamps
build/bin/blueprints.log- Persistent log file
Future Enhancements
Possible additions:
- Async logging - For high-throughput scenarios
- Rotating files - Size/time based rotation
- Remote logging - Network sinks (UDP/TCP)
- Custom formatters - Different log formats per sink
- Log filtering - By component/category
- ImGui log viewer - In-app log window
Example Advanced Usage
Multiple Loggers
// Create separate loggers for different subsystems
auto render_logger = spdlog::stdout_color_mt("render");
auto physics_logger = spdlog::basic_logger_mt("physics", "physics.log");
Structured Logging
LOG_INFO("User {} performed action {}", username, action);
LOG_ERROR("Failed to load file: {} (error: {})", filename, err_code);
Conditional Compilation
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_DEBUG
LOG_DEBUG("Expensive debug info: {}", compute_debug_info());
#endif
Integration Date: November 7, 2025
Spdlog Version: Header-only (bundled)
Status: ✅ Complete and verified
Build: ✅ Successful with /utf-8 flag