autotoc_md616
doc_id: "LOG-MIGR-001" doc_title: "Migration Guide - Logger System" doc_version: "1.0.0" doc_date: "2026-04-04" doc_status: "Released" project: "logger_system"
category: "MIGR"
Migration Guide - Logger System
SSOT: This document is the single source of truth for Migration Guide - Logger System.
Language: English | 한국어
Overview
This guide helps you migrate to the standalone logger_system from previous integrated implementations or other logging frameworks.
Migration Paths Available:
- From integrated thread_system logger → standalone logger_system
- From spdlog or other frameworks → logger_system
- From custom logging implementations → logger_system
Estimated Time: 1-3 hours for typical applications Breaking Changes: Yes (API, namespace, build configuration)
Table of Contents
- Quick Migration Checklist
- Migration Path 1: From Integrated thread_system
- Migration Path 2: From spdlog
- Migration Path 3: From Custom Logger
- Common Migration Issues
- Testing Your Migration
- Rollback Plan
Quick Migration Checklist
- Update CMakeLists.txt dependencies
- Update namespace references
- Migrate logger initialization code
- Update log call sites (if needed)
- Update integration points
Migration Path 1: From Integrated thread_system
Background
In earlier versions, logging functionality was integrated into thread_system. The logger has been extracted into a standalone logger_system module for better modularity and independent development.
Step 1: Update CMakeLists.txt
Before (integrated thread_system):
find_package(thread_system CONFIG REQUIRED)
target_link_libraries(your_target PRIVATE kcenon::thread_system)
After (standalone logger_system):
find_package(logger_system CONFIG REQUIRED)
find_package(thread_system CONFIG REQUIRED) # Still needed if using thread pool
target_link_libraries(your_target PRIVATE
kcenon::logger_system
kcenon::thread_system # Optional, only if using threads
)
Step 2: Update Header Includes
Before:
#include <thread_system/logger/logger.h>
#include <thread_system/logger/console_writer.h>
#include <thread_system/logger/file_writer.h>
After:
Console writer for logging to stdout/stderr.
File writer for logging to files with optional buffering.
High-performance, thread-safe logging system with asynchronous capabilities.
Step 3: Update Namespace
Before:
auto logger_instance = thread_system::create_logger();
logger_instance->info("Message");
After:
.with_console_output()
.value();
logger_instance->info("Message");
Builder pattern for logger construction with validation.
result< std::unique_ptr< logger > > build()
Step 4: Migrate Logger Creation
Before (old integrated API):
#include <thread_system/logger/logger.h>
auto logger_instance = std::make_shared<thread_system::logger>();
logger_instance->add_writer(std::make_shared<console_writer>());
logger_instance->set_level(log_level::info);
After (new builder pattern):
.with_console_output()
.with_level(log_level::info)
logger_instance->info("Logger created successfully");
} else {
std::cerr <<
"Logger creation failed: " <<
result.error().message << std::endl;
}
Builder pattern implementation for flexible logger configuration kcenon.
Step 5: Update Thread System Integration (Optional)
If you're using thread_system with logger integration:
Before (integrated):
auto pool = thread_system::create_thread_pool();
pool->set_logger(logger_instance);
After (adapter pattern):
.with_console_output()
.value();
auto adapter = std::make_shared<logger_adapter>(logger_instance);
pool->set_logger(adapter);
Standalone logger adapter for use without common_system DI.
Migration Path 2: From spdlog
Overview
Migrating from spdlog to logger_system provides better ecosystem integration, Result<T> error handling, and performance improvements in multi-threaded scenarios.
API Mapping
| spdlog API | logger_system API | Notes |
spdlog::info() | logger->info() | Instance method instead of static |
spdlog::get("name") | logger_builder().build() | Builder pattern |
spdlog::rotating_logger_mt() | .with_rotating_file() | Builder method |
spdlog::set_level() | .with_level() | Builder method |
spdlog::flush_on() | .with_flush_policy() | Builder method |
Example Migration
Before (spdlog):
#include <spdlog/spdlog.h>
#include <spdlog/sinks/rotating_file_sink.h>
auto logger = spdlog::rotating_logger_mt(
"app_logger",
"logs/app.log",
1024 * 1024 * 10,
3
);
spdlog::set_level(spdlog::level::info);
logger->info(
"Application started");
After (logger_system):
.with_rotating_file("logs/app.log", 10 * 1024 * 1024)
.with_level(log_level::info)
logger->info(
"Application started");
}
Pattern Support
spdlog:
logger->info(
"User {} logged in from {}", username, ip);
logger_system (C++20 std::format):
logger->info(std::format(
"User {} logged in from {}", username, ip));
Or use direct string:
logger->info(
"User " + username +
" logged in from " + ip);
Migration Path 3: From Custom Logger
Common Custom Logger Patterns
Pattern 1: Direct File Writing
Before (custom):
class MyLogger {
std::ofstream file;
public:
void log(const std::string& message) {
file << message << std::endl;
}
};
After (logger_system):
.with_level(log_level::info)
.value();
logger_builder & with_file_output(const std::string &directory, const std::string &prefix="app", std::size_t max_size=100 *1024 *1024, std::size_t max_count=5)
Configure file output.
Benefits:
- Asynchronous I/O (non-blocking)
- Thread-safe by default
- Automatic rotation
- Error handling with Result<T>
Pattern 2: Multiple Output Targets
Before (custom):
class MyLogger {
std::ofstream file;
bool use_console;
public:
void log(const std::string& message) {
if (use_console) std::cout << message << std::endl;
file << message << std::endl;
}
};
After (logger_system):
.with_console_output()
.with_level(log_level::info)
.value();
Benefits:
- Multiple writers without manual branching
- Each writer independently configurable
- Filters per writer
Pattern 3: Thread-Safe Singleton
Before (custom):
class Logger {
static std::mutex mutex;
static std::shared_ptr<Logger> instance;
public:
static std::shared_ptr<Logger> get_instance() {
std::lock_guard<std::mutex> lock(mutex);
if (!instance) {
instance = std::make_shared<Logger>();
}
return instance;
}
void log(const std::string& message) {
std::lock_guard<std::mutex> lock(mutex);
}
};
After (logger_system):
class LoggerRegistry {
static std::shared_ptr<kcenon::logger::logger> instance;
public:
static std::shared_ptr<kcenon::logger::logger> get() {
static std::once_flag flag;
std::call_once(flag, [] {
.with_console_output()
.value();
});
return instance;
}
};
LoggerRegistry::get()->info("Message");
Benefits:
- Thread-safe by design (no locks in application code)
- Lock-free enqueue on hot path
- Batched background processing
Common Migration Issues
Issue 1: Namespace Conflicts
Problem: Both old and new logger in same file
Solution: Use explicit namespaces during transition
namespace old_logger = thread_system::logger;
auto old_log = old_logger::create_logger();
auto new_log = new_logger::logger_builder().build().value();
Issue 2: CMake Cache Issues
Problem: CMake still finds old thread_system with integrated logger
Solution: Clear CMake cache
rm -rf build
mkdir build && cd build
cmake ..
Issue 3: Header Not Found
Problem:
fatal error: kcenon/logger/core/logger.h: No such file or directory
Solution: Ensure logger_system is properly installed
# Build and install logger_system
cd /path/to/logger_system
mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local
make
sudo make install
Or use FetchContent in CMakeLists.txt:
include(FetchContent)
FetchContent_Declare(
logger_system
GIT_REPOSITORY https://github.com/kcenon/logger_system.git
GIT_TAG v0.1.0 # Pin to a specific release tag; do NOT use main
)
FetchContent_MakeAvailable(logger_system)
Issue 4: Result<T> Pattern Unfamiliar
Problem: Don't know how to handle Result<T> from build()
Solution: Use .is_ok() and .value()
.with_console_output()
} else {
std::cerr << "Error: " << error.message << std::endl;
}
Or use monadic operations:
.with_console_output()
logger->info(
"Logger initialized");
})
.or_else([](const auto& error) {
std::cerr << "Failed: " << error.message << std::endl;
return create_default_logger();
})
.value();
Issue 5: Performance Regression
Problem: Slower than previous custom logger
Solution: Use high-performance template
.with_template(config_template::high_performance)
.value();
Or disable unnecessary features:
# CMakeLists.txt
set(ENABLE_SMALL_STRING_OPTIMIZATION ON)
set(USE_LOCKFREE ON) # If available
Testing Your Migration
1. Compile Test
mkdir build && cd build
cmake ..
make
Expected: Clean build with no errors
2. Unit Tests
# Run your existing tests
ctest
# Or manually
./build/tests/your_tests
Expected: All tests pass
3. Integration Tests
# Test with actual application
./build/your_app --log-level debug
# Check log output
cat logs/app.log
Expected: Logs appear correctly formatted
4. Performance Benchmark
# Run benchmarks
./build/benchmarks/logger_benchmark
# Compare with baseline
# Expected: Similar or better performance
Rollback Plan
If migration fails, you can rollback:
Option 1: Revert Changes
# Revert git changes
git checkout -- .
# Or restore from backup
cp -r backup_before_migration/* .
# Rebuild with old version
mkdir build && cd build
cmake ..
make
Option 2: Gradual Migration
Keep both old and new logger during transition:
# CMakeLists.txt
find_package(thread_system CONFIG REQUIRED) # Old logger
find_package(logger_system CONFIG REQUIRED) # New logger
target_link_libraries(your_target PRIVATE
kcenon::thread_system # Old logger still available
kcenon::logger_system # New logger available
)
#ifdef USE_NEW_LOGGER
#else
#include <thread_system/logger/logger.h>
namespace logger = thread_system::logger;
#endif
Migration Assistance
Automated Migration Script
We provide a migration script to automate common changes:
# Download migration script
curl -O https://raw.githubusercontent.com/kcenon/logger_system/main/scripts/migrate_from_thread_system.sh
chmod +x migrate_from_thread_system.sh
# Run migration on your source directory
./migrate_from_thread_system.sh /path/to/your/source
# Review changes
git diff
# Rebuild
mkdir build && cd build
cmake ..
make
The script performs:
- Header include updates
- Namespace replacements
- CMakeLists.txt modifications
- Basic API pattern updates
Note: Manual review is still required for complex logic.
Support
Need help with migration?
Next Steps After Migration
- Read Documentation:
- Optimize Configuration:
- Review log levels
- Configure rotation policies
- Set up monitoring integration
- Enable Advanced Features:
- Structured logging (JSON)
- Network logging
- Monitoring integration
Last Updated: 2025-10-22 Migration Script Version: 1.0.0