Logger System 0.1.3
High-performance C++20 thread-safe logging system with asynchronous capabilities
Loading...
Searching...
No Matches
MIGRATION_GUIDE

autotoc_md2068

doc_id: "LOG-MIGR-004" doc_title: "Logger System Migration Guide" doc_version: "1.0.0" doc_date: "2026-04-04" doc_status: "Released" project: "logger_system"

category: "MIGR"

Language: English | 한국어

Logger System Migration Guide

SSOT: This document is the single source of truth for Logger System Migration Guide.

Version: 0.4.0.0 Last Updated: 2026-01-23

Table of Contents

  1. Overview
  2. CMake Configuration Changes
  3. Version Migration
    • From v3.x to v4.0
    • From v2.x to v3.0
    • From v1.x to v2.x
  4. API Changes
    • Unified Context API
  5. Configuration Migration
  6. Migration from Other Libraries
  7. Compatibility Wrappers
  8. Step-by-Step Migration
  9. Common Issues and Solutions

Overview

This guide helps you migrate to Logger System from:

  • Earlier versions of Logger System (v3.x to v4.0, v2.x to v3.0, v1.x to v2.x)
  • Other popular logging libraries (spdlog, Boost.Log, glog, log4cpp)
  • Custom logging solutions

Breaking Changes Summary

Version Component Change Impact
v4.0 Writers Decorator pattern architecture High for custom writers
v4.0 Context IDs Convenience methods removed Medium
v4.0 Context API Unified context() method replaces 3 separate APIs Medium
v3.0 Namespace logger_modulekcenon::logger High
v3.0 Interface Implements common::interfaces::ILogger High
v3.0 Dependencies thread_system now optional Medium
v3.0 C++ Standard Requires C++20 Medium
v3.0 Result Types Uses common::VoidResult Medium
v2.0 Error Handling Exceptions → Result types High
v2.0 Memory Management Raw pointers → Smart pointers High
v2.0 Configuration Direct setters → Builder pattern Medium

From v3.x to v4.0

Version 4.0 introduces a decorator pattern-based writer architecture. This primarily affects users with custom writer implementations.

What Changed

  1. Decorator Pattern Writers: Cross-cutting concerns (filtering, buffering, formatting) are now separate decorator classes
  2. Context ID API Simplification: Specialized context ID methods removed in favor of generic API
  3. New Writer Components: decorator_writer_base, filtered_writer, buffered_writer, formatted_writer

Migration for Standard Users

No changes required if you only use built-in writers via logger_builder:

// This code works unchanged in v4.0
auto logger = logger_builder()
.add_writer("console", std::make_unique<console_writer>())
.add_writer("file", std::make_unique<file_writer>("app.log"))
.with_min_level(log_level::info)
.build();

Migration for Custom Writer Authors

If you have custom writer implementations, see the detailed Decorator Migration Guide.

Quick summary:

// v3.x: Monolithic custom writer
class my_writer : public base_writer {
common::VoidResult write(const log_entry& entry) override {
if (!should_log(entry)) return {}; // Filtering (remove this)
auto formatted = format(entry); // Formatting (remove this)
buffer_.push(formatted); // Buffering (remove this)
return do_output(formatted);
}
};
// v4.0: Focused leaf writer + decorators
class my_writer : public thread_safe_writer {
protected:
common::VoidResult write_entry_impl(const log_entry& entry) override {
return do_output(entry); // Only destination logic
}
};
// Compose with decorators
auto writer = std::make_unique<formatted_writer>(
std::make_unique<buffered_writer>(
std::make_unique<filtered_writer>(
std::make_unique<my_writer>(),
std::make_unique<level_filter>(log_level::info)
),
buffered_writer::config{}
),
std::make_unique<json_formatter>()
);

Context ID API Changes

// v3.x (removed):
logger->set_trace_id("abc123");
logger->set_span_id("def456");
logger->clear_trace_id();
// v4.0:
logger->set_context_id("trace_id", "abc123");
logger->set_context_id("span_id", "def456");
logger->clear_context_id("trace_id");
// Or clear all: logger->clear_all_context_ids();

Unified Context API (New in v4.0)

Version 4.0 introduces the unified_log_context class that consolidates all context management into a single, type-safe API. The previous three overlapping APIs (set_context(), set_context_id(), set_otel_context()) are now deprecated in favor of the new context() method.

Why This Change?

Issue Impact
Confusion: When to use which API? Developer friction
Duplication: trace_id settable via all 3 APIs Inconsistent state
Maintenance: 3 storage mechanisms Code complexity
Testing: Must test all 3 paths Test burden

Migration Table

Deprecated API New API Notes
set_context(key, value) context().set(key, value) For custom fields
remove_context(key) context().remove(key)
clear_context() context().clear() Clears all categories
has_context() !context().empty()
get_context() context().to_fields() Returns log_fields
set_context_id(key, value) context().set(key, value, context_category::trace) For trace/request IDs
get_context_id(key) context().get_string(key)
clear_context_id(key) context().remove(key)
has_context_id(key) context().has(key)
clear_all_context_ids() context().clear(context_category::trace) Clears only trace category
set_otel_context(ctx) context().set_otel(ctx) OpenTelemetry context
get_otel_context() Query individual fields via context().get_string()
clear_otel_context() context().clear(context_category::otel)
has_otel_context() context().has("otel_trace_id")

Context Categories

The unified API organizes context into categories:

enum class context_category {
custom, // User-defined fields (default)
trace, // Distributed tracing (trace_id, span_id, parent_span_id)
request, // Request metadata (request_id, correlation_id)
otel // OpenTelemetry specific (otel_trace_id, otel_span_id, etc.)
};

Code Examples

Setting Custom Context:

// OLD (deprecated)
logger->set_context("user_id", int64_t{12345});
logger->set_context("session_active", true);
// NEW
logger->context().set("user_id", int64_t{12345});
logger->context().set("session_active", true);

Setting Trace Context:

// OLD (deprecated)
logger->set_context_id("trace_id", "0af7651916cd43dd8448eb211c80319c");
logger->set_context_id("span_id", "b7ad6b7169203331");
// NEW (recommended)
logger->context().set_trace("0af7651916cd43dd8448eb211c80319c", "b7ad6b7169203331");
// Or with parent span
logger->context().set_trace("trace_id", "span_id", "parent_span_id");

Setting Request Context:

// OLD (deprecated)
logger->set_context_id("request_id", "req-123");
logger->set_context_id("correlation_id", "corr-456");
// NEW (recommended)
logger->context().set_request("req-123", "corr-456");

Setting OpenTelemetry Context:

// OLD (deprecated)
otlp::otel_context otel_ctx{
.trace_id = "0af7651916cd43dd8448eb211c80319c",
.span_id = "b7ad6b7169203331",
.trace_flags = "01"
};
logger->set_otel_context(otel_ctx);
// NEW (recommended)
logger->context().set_otel(otel_ctx);

Clearing Context:

// OLD (deprecated)
logger->clear_context(); // Clear all custom fields
logger->clear_all_context_ids(); // Clear all trace IDs
logger->clear_otel_context(); // Clear OTEL context
// NEW (recommended)
logger->context().clear(); // Clear everything
logger->context().clear(context_category::custom); // Clear only custom fields
logger->context().clear(context_category::trace); // Clear only trace context
logger->context().clear(context_category::otel); // Clear only OTEL context

Querying Context:

// OLD (deprecated)
std::string trace_id = logger->get_context_id("trace_id");
bool has_trace = logger->has_context_id("trace_id");
// NEW (recommended)
std::string trace_id = logger->context().get_string("trace_id");
bool has_trace = logger->context().has("trace_id");
// Type-safe access
auto user_id = logger->context().get_as<int64_t>("user_id");
if (user_id) {
// Use *user_id
}

Method Chaining:

// The new API supports fluent chaining
logger->context()
.set("user_id", int64_t{12345})
.set_trace("trace-abc", "span-123")
.set_request("req-456", "corr-789");
// All subsequent logs include the context
logger->log_structured(log_level::info)
.message("Processing request")
.emit();

Thread Safety

The unified_log_context class is thread-safe internally:

  • Read operations use shared locks
  • Write operations use exclusive locks
  • No external synchronization required

Migration Script

#!/bin/bash
# migrate_context_api.sh
# Migrate set_context to context().set
find . -name "*.cpp" -o -name "*.h" | xargs sed -i '' \
-e 's/->set_context(\‍([^,]*\‍), /->context().set(\1, /g' \
-e 's/->remove_context(/->context().remove(/g' \
-e 's/->clear_context()/->context().clear()/g' \
-e 's/->has_context()/!context().empty()/g' \
-e 's/->get_context()/->context().to_fields()/g'
# Migrate set_context_id to context().set with category
find . -name "*.cpp" -o -name "*.h" | xargs sed -i '' \
-e 's/->set_context_id(\‍([^,]*\‍), \‍([^)]*\‍))/->context().set(\1, \2, context_category::trace)/g' \
-e 's/->get_context_id(/->context().get_string(/g' \
-e 's/->clear_context_id(/->context().remove(/g' \
-e 's/->has_context_id(/->context().has(/g' \
-e 's/->clear_all_context_ids()/->context().clear(context_category::trace)/g'
# Migrate OTEL context
find . -name "*.cpp" -o -name "*.h" | xargs sed -i '' \
-e 's/->set_otel_context(/->context().set_otel(/g' \
-e 's/->clear_otel_context()/->context().clear(context_category::otel)/g' \
-e 's/->has_otel_context()/->context().has("otel_trace_id")/g'

Deprecation Timeline

  • v4.0 (Current): Old APIs marked with [[deprecated]] - compiler warnings generated
  • v5.0 (Future): Deprecated APIs will be removed

CMake Configuration Changes

v2.x (Previous)

# CMakeLists.txt for v2.x
find_package(thread_system REQUIRED) # Was required
find_package(logger_system REQUIRED)
target_link_libraries(your_app PRIVATE
thread_system::thread_system
logger_system::logger_system
)
# Build flags for v2.x
cmake -DUSE_THREAD_SYSTEM=ON .. # Old flag name

v3.0 (Current)

# CMakeLists.txt for v3.0
find_package(common_system REQUIRED) # New required dependency
find_package(logger_system REQUIRED)
# find_package(thread_system) # Optional now
target_link_libraries(your_app PRIVATE
kcenon::common
kcenon::logger
# kcenon::thread # Optional
)
# Build flags for v3.0
cmake -DLOGGER_USE_THREAD_SYSTEM=ON .. # New flag name (optional)
cmake -DLOGGER_STANDALONE_MODE=ON .. # Standalone mode (default)

CMake Flag Changes Summary

v2.x Flag v3.0 Flag Default Description
USE_THREAD_SYSTEM=ON LOGGER_USE_THREAD_SYSTEM=ON OFF Enable thread_system integration
N/A LOGGER_STANDALONE_MODE=ON ON Use standalone std::jthread worker
BUILD_TESTS=ON BUILD_TESTS=ON ON Build test suite
BUILD_EXAMPLES=ON BUILD_EXAMPLES=ON ON Build examples

Target Name Changes

v2.x Target v3.0 Target
logger_system::logger_system kcenon::logger
thread_system::thread_system kcenon::thread (optional)
N/A kcenon::common (required)

Dependency Changes

v2.x Dependency Tree:

logger_system
└── thread_system (required)

v3.0 Dependency Tree:

logger_system
├── common_system (required)
└── thread_system (optional, for async logging with thread pool)
└── common_system (required)

Version Migration

From v2.x to v3.0

Summary of Changes

Aspect v2.x v3.0
Namespace logger_module kcenon::logger
Interface thread_module::logger_interface common::interfaces::ILogger
Header Path <logger_system/...> <kcenon/logger/...>
Result Type result_void common::VoidResult
thread_system Required Optional
C++ Standard C++17 C++20

1. Namespace Migration

Old (v2.x):

#include <logger_system/logger.h>
#include <logger_system/logger_builder.h>
#include <logger_system/writers/console_writer.h>
using namespace logger_module;
auto logger = logger_builder()
.use_template("production")
.build();

New (v3.0):

using namespace kcenon::logger;
.use_template("production")
.build();
Builder pattern for logger construction with validation.
logger_builder & use_template(const std::string &name)
result< std::unique_ptr< logger > > build()
Console writer for logging to stdout/stderr.
High-performance, thread-safe logging system with asynchronous capabilities.
Builder pattern implementation for flexible logger configuration kcenon.

2. Interface Migration

Old (v2.x):

class logger : public thread_module::logger_interface {
// Deprecated: result_void is replaced by common::VoidResult
result_void log(thread_module::log_level level,
const std::string& message) override;
};
// Usage
logger->log(thread_module::log_level::info, "Message");

New (v3.0):

class logger : public common::interfaces::ILogger {
common::VoidResult log(common::interfaces::log_level level,
const std::string& message) override;
};
// Usage with ILogger interface (recommended)
logger->log(common::interfaces::log_level::info, "Message");
// Or with native API (backward compatible)
logger->log(log_level::info, "Message");

3. Dual API Support

v3.0 provides both ILogger interface and native API:

using namespace kcenon::logger;
.use_template("production")
.add_writer("console", std::make_unique<console_writer>())
.build()
.value();
// ILogger interface (standardized, recommended for new code)
logger->log(common::interfaces::log_level::info, "Using ILogger interface");
// With C++20 source_location (automatic)
logger->log(common::interfaces::log_level::debug, "Source location captured automatically");
// Native API (backward compatible)
logger->log(log_level::info, "Using native API");
// Note: Manual source location (__FILE__, __LINE__, __func__) is deprecated.
// Source location is now auto-captured. This API will be removed in v3.0.0.
logger->log(log_level::error, "Error message");
logger_builder & add_writer(const std::string &name, log_writer_ptr writer)
Add a writer to the logger.

4. Result Type Migration

Old (v2.x):

result_void result = logger->log(level, message);
if (!result) { // boolean conversion
std::cerr << result.error().message() << "\n";
}

New (v3.0):

common::VoidResult result = logger->log(level, message);
if (result.is_err()) { // Use is_err() instead of boolean conversion
std::cerr << result.error().message << "\n"; // Note: .message not .message()
}
// Or check for success
if (result.is_ok()) {
// Operation succeeded
}
// Creating results:
// Old: return result_void(); or return {};
// New: return common::ok();
// Old: return result_void(code, msg); or return make_logger_error(code, msg);
// New: return make_logger_void_result(code, msg);

5. thread_system Dependency Changes

Old (v2.x):

// thread_system was required
// CMakeLists.txt
find_package(thread_system REQUIRED)
target_link_libraries(your_app PRIVATE thread_system::thread_system)

New (v3.0):

// thread_system is now optional
// CMakeLists.txt
find_package(common_system REQUIRED) # Required
find_package(logger_system REQUIRED)
# find_package(thread_system OPTIONAL) # Only if needed
target_link_libraries(your_app PRIVATE
)

6. Backend Selection (New in v3.0)

using namespace kcenon::logger;
// Standalone mode (default, no thread_system needed)
.with_standalone_backend() // Uses std::jthread
.build();
// Custom backend
.with_backend(std::make_unique<my_custom_backend>())
.build();
logger_builder & with_standalone_backend()
Use standalone backend explicitly.
logger_builder & with_backend(std::unique_ptr< backends::integration_backend > backend)
Set integration backend explicitly.

7. C++20 Source Location

New in v3.0:

// Source location is automatically captured
logger->log(common::interfaces::log_level::info, "Debug message");
// Output: [INFO] [main.cpp:42] [main()] Debug message
// Explicit source location
logger->log(common::interfaces::log_level::info, "Message",
common::source_location::current());

8. Configuration Strategies (Enhanced in v3.0)

using namespace kcenon::logger;
// Deployment strategy
.for_environment(deployment_env::production) // New in v3.0
.build();
// Performance strategy
.with_performance_tuning(performance_level::high_throughput) // New in v3.0
.build();
// Environment variable configuration
.auto_configure() // Reads LOG_* environment variables
.build();
logger_builder & auto_configure()
Auto-configure from environment variables.
logger_builder & with_performance_tuning(performance_level level)
Apply performance tuning.
logger_builder & for_environment(deployment_env env)
Configure for a specific deployment environment.

9. Monitoring Integration (New in v3.0)

#include <kcenon/monitoring/monitoring.h>
auto monitor = std::make_shared<kcenon::monitoring::monitoring>();
.with_monitoring(monitor) // New in v3.0
.with_health_check_interval(std::chrono::seconds(30))
.build();
logger_builder & with_monitoring(std::shared_ptr< common::interfaces::IMonitor > monitor)
Set monitoring interface (Phase 2.2.4)
logger_builder & with_health_check_interval(std::chrono::milliseconds interval)
Set health check interval.

Migration Script

For automated migration, use this script pattern:

#!/bin/bash
# migrate_v2_to_v3.sh
# Update includes
find . -name "*.cpp" -o -name "*.h" | xargs sed -i '' \
-e 's|#include <logger_system/|#include <kcenon/logger/|g' \
-e 's|#include "logger_system/|#include "kcenon/logger/|g'
# Update namespaces
find . -name "*.cpp" -o -name "*.h" | xargs sed -i '' \
-e 's|logger_module::|kcenon::logger::|g' \
-e 's|namespace logger_module|namespace kcenon::logger|g' \
-e 's|using namespace logger_module|using namespace kcenon::logger|g'
# Update interface references
find . -name "*.cpp" -o -name "*.h" | xargs sed -i '' \
-e 's|thread_module::logger_interface|common::interfaces::ILogger|g' \
-e 's|thread_module::log_level|common::interfaces::log_level|g'
# Update result types
find . -name "*.cpp" -o -name "*.h" | xargs sed -i '' \
-e 's|result_void|common::VoidResult|g'

From v1.x to v2.x

1. Error Handling Migration

Old (v1.x):

try {
logger->add_writer(new file_writer("app.log"));
} catch (const std::exception& e) {
std::cerr << "Failed: " << e.what() << std::endl;
}
Core file writer for logging to files.
Definition file_writer.h:44

New (v2.x):

auto result = logger->add_writer(std::make_unique<file_writer>("app.log"));
if (!result) {
std::cerr << "Failed: " << result.error().message() << std::endl;
}

2. Memory Management Migration

Old (v1.x):

// Manual memory management
base_writer* writer = new file_writer("app.log");
logger->add_writer(writer); // Logger takes ownership
// Don't delete writer - logger owns it
Abstract base class for all log output writers.
Definition base_writer.h:95

New (v2.x):

// RAII with unique_ptr
auto writer = std::make_unique<file_writer>("app.log");
logger->add_writer(std::move(writer)); // Explicit ownership transfer

3. Configuration Migration

Old (v1.x):

logger* log = new logger();
log->set_min_level(log_level::info);
log->set_async(true);
log->set_buffer_size(10000);
log->add_console_writer();
log->add_file_writer("app.log");

New (v2.x):

auto log = logger_builder()
.with_min_level(log_level::info)
.with_async_mode(true)
.with_console_writer()
.with_file_writer("app.log")
.build();
logger_builder & with_min_level(log_level level)
logger_builder & with_buffer_size(std::size_t size)
Set buffer size.

4. Logging API Migration

Old (v1.x):

LOG_INFO(logger, "Message with %s", param);
LOG_DEBUG_F(logger, "Formatted: {}", value);

New (v2.x):

logger->info("Message with param", {{"param", param}});
logger->debug("Message", {{"value", value}});

API Changes

v3.0 API Changes Summary

v2.x v3.0 Notes
logger_module::logger kcenon::logger::logger Namespace change
thread_module::logger_interface common::interfaces::ILogger Interface change
thread_module::log_level common::interfaces::log_level Level type change
result_void common::VoidResult Result type change
set_min_level(level) set_level(level) Method rename (deprecated)
get_min_level() get_level() Method rename (deprecated)
N/A log(level, msg, source_location) New C++20 overload
N/A with_standalone_backend() New backend selection
N/A for_environment(env) New configuration strategy
N/A with_performance_tuning(level) New configuration strategy
N/A with_monitoring(monitor) New monitoring integration

Deprecated Native log_level API (Planned for Removal in v3.0.0)

The following native logger_system::log_level APIs are deprecated in favor of common::interfaces::log_level:

Deprecated API Recommended Alternative Status
logger_system::log_level enum common::interfaces::log_level Deprecated, will be removed in v3.0.0
log(log_level, const std::string&) log(common::interfaces::log_level, const std::string&) Deprecated
log(log_level, msg, file, line, func) log(common::interfaces::log_level, std::string_view, source_location) Deprecated
log(log_level, msg, log_context) log(common::interfaces::log_level, std::string_view, source_location) Deprecated
is_enabled(log_level) is_enabled(common::interfaces::log_level) Deprecated
set_min_level(log_level) set_level(common::interfaces::log_level) Deprecated
get_min_level() get_level() Deprecated
log_level_to_string() common::interfaces::log_level_to_string() Deprecated
string_to_log_level() common::interfaces::string_to_log_level() Deprecated
to_logger_system_level() Use common::interfaces::log_level directly Deprecated
to_common_level() Use common::interfaces::log_level directly Deprecated

Migration Example:

// OLD (deprecated)
using namespace kcenon::logger;
logger->log(log_level::info, "Message");
logger->set_min_level(log_level::debug);
if (logger->is_enabled(log_level::trace)) { ... }
// NEW (recommended)
#include <kcenon/common/interfaces/logger_interface.h>
using namespace kcenon::logger;
logger->log(common::interfaces::log_level::info, "Message");
logger->set_level(common::interfaces::log_level::debug);
if (logger->is_enabled(common::interfaces::log_level::trace)) { ... }
// Or with using directive for brevity
using common::interfaces::log_level;
logger->log(log_level::info, "Message");
Common types and enumerations for logger system.

Timeline:

  • Current: APIs marked with [[deprecated]] attribute - compiler warnings will be generated
  • v3.0.0: Deprecated APIs will be removed

Core Logger API

v1.x Method v2.x Equivalent v3.0 Equivalent
log(level, msg) log(level, msg, fields) log(level, msg) via ILogger
set_min_level(level) Builder: with_min_level(level) set_level(level) + Builder
add_writer(writer*) add_writer(unique_ptr<writer>) Same as v2.x
flush() flush() → result<void> flush() → VoidResult

Configuration Migration

From INI/XML Configuration

Old (config.ini):

[logger]
level = INFO
async = true
buffer_size = 10000
[console]
enabled = true
colored = true
[file]
enabled = true
path = app.log
rotation = 10485760
max_files = 5

New (code-based, v3.0):

using namespace kcenon::logger;
auto create_logger_from_config() {
return logger_builder()
.with_min_level(log_level::info)
.with_async(true)
.add_writer("console", std::make_unique<console_writer>(true))
.add_writer("file", std::make_unique<rotating_file_writer>(
"app.log", 10 * 1024 * 1024, 5))
.build();
}
logger_builder & with_async(bool async=true)
Rotating file writer with size and time-based rotation.

Environment-based Configuration (v3.0)

using namespace kcenon::logger;
auto create_logger() {
return logger_builder()
.auto_configure() // Reads LOG_* environment variables
.build();
}
// Supported environment variables:
// LOG_LEVEL: trace, debug, info, warn, error, fatal
// LOG_ASYNC: true/false
// LOG_BUFFER_SIZE: buffer size in bytes
// LOG_BATCH_SIZE: batch size
// LOG_FLUSH_INTERVAL: flush interval in ms
// LOG_COLOR: true/false
// LOG_METRICS: true/false
// LOG_ENV: production/staging/development/testing

Migration from Other Libraries

From spdlog

// spdlog
#include "spdlog/spdlog.h"
#include "spdlog/sinks/basic_file_sink.h"
auto logger = spdlog::basic_logger_mt("my_logger", "logs/my_log.txt");
logger->set_level(spdlog::level::info);
logger->info("Hello {}", "World");
logger->error("Error code: {}", 404);
// Logger System v3.0 equivalent
using namespace kcenon::logger;
.with_min_level(log_level::info)
.add_writer("file", std::make_unique<file_writer>("logs/my_log.txt"))
.build()
.value();
// Using ILogger interface
logger->log(common::interfaces::log_level::info, "Hello World");
logger->log(common::interfaces::log_level::error, "Error code: 404");
// Or using native API
logger->log(log_level::info, "Hello World");
logger->log(log_level::error, "Error code: 404");
File writer for logging to files with optional buffering.

From Boost.Log

// Boost.Log
#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup/file.hpp>
namespace logging = boost::log;
logging::add_file_log("sample.log");
BOOST_LOG_TRIVIAL(info) << "An informational message";
BOOST_LOG_TRIVIAL(error) << "An error message";
// Logger System v3.0 equivalent
using namespace kcenon::logger;
.add_writer("file", std::make_unique<file_writer>("sample.log"))
.build()
.value();
logger->log(common::interfaces::log_level::info, "An informational message");
logger->log(common::interfaces::log_level::error, "An error message");

From Google glog

// glog
#include <glog/logging.h>
google::InitGoogleLogging(argv[0]);
LOG(INFO) << "Found " << num_cookies << " cookies";
LOG(ERROR) << "Error code: " << error_code;
CHECK(condition) << "Condition failed";
// Logger System v3.0 equivalent
using namespace kcenon::logger;
.use_template("production")
.build()
.value();
logger->log(common::interfaces::log_level::info,
"Found " + std::to_string(num_cookies) + " cookies");
logger->log(common::interfaces::log_level::error,
"Error code: " + std::to_string(error_code));
if (!condition) {
logger->log(common::interfaces::log_level::fatal, "Condition failed");
std::abort();
}
logger_error_code
Error codes specific to the logger system.

Compatibility Wrappers

v2.x to v3.0 Compatibility Header

// compatibility/logger_v2_compat.h
#pragma once
// Namespace alias for gradual migration
// Type aliases
using result_void = common::VoidResult;
template<typename T>
// Level mapping
namespace thread_module {
using log_level = common::interfaces::log_level;
}
// Usage:
// 1. Include this header
// 2. Existing v2.x code will compile with minimal changes
// 3. Gradually update to new namespaces
// 4. Remove this header when migration is complete

Legacy API Wrapper (v1.x compatibility)

// compatibility/logger_v1_compat.h
#pragma once
// Legacy macros for backward compatibility
#define LOG_INFO(logger, msg, ...) \
logger->log(common::interfaces::log_level::info, format_string(msg, ##__VA_ARGS__))
#define LOG_ERROR(logger, msg, ...) \
logger->log(common::interfaces::log_level::error, format_string(msg, ##__VA_ARGS__))
#define LOG_DEBUG(logger, msg, ...) \
logger->log(common::interfaces::log_level::debug, format_string(msg, ##__VA_ARGS__))
// Legacy function signatures
namespace logger_v1_compat {
[[deprecated("Use kcenon::logger::logger_builder instead")]]
inline auto create_logger() {
}
}

Step-by-Step Migration

Phase 1: Preparation

  1. Check C++ Standard
    # Ensure C++20 is enabled
    set(CMAKE_CXX_STANDARD 20)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
  2. Update Dependencies
    # v3.0 requires common_system
    find_package(common_system REQUIRED)
    find_package(logger_system REQUIRED)
    # thread_system is now optional
    # find_package(thread_system OPTIONAL)
  3. Create Migration Branch
    git checkout -b migration/logger-v3.0

Phase 2: Namespace Migration

  1. Update Include Paths
    // OLD
    #include <logger_system/logger.h>
    // NEW
  2. Update Namespace Usage
    // OLD
    using namespace logger_module;
    // NEW
    using namespace kcenon::logger;

Phase 3: Interface Migration

  1. Update Interface References
    // OLD
    class MyLogger : public thread_module::logger_interface { ... };
    // NEW
    class MyLogger : public common::interfaces::ILogger { ... };
  2. Update Log Level Types
    // OLD
    thread_module::log_level::info
    // NEW
    common::interfaces::log_level::info
    // or (native API)
    kcenon::logger::log_level::info

Phase 4: Validation

  1. Run Tests
    mkdir build && cd build
    cmake .. -DCMAKE_CXX_STANDARD=20
    make -j$(nproc)
    ctest --output-on-failure
  2. Check Sanitizers
    cmake .. -DCMAKE_CXX_FLAGS="-fsanitize=address,undefined"
    make && ctest

Common Issues and Solutions

Issue 1: Namespace Not Found

Error:

error: 'logger_module' is not a namespace-name

Solution:

// Change from
using namespace logger_module;
// To
using namespace kcenon::logger;

Issue 2: Interface Type Mismatch

Error:

error: 'thread_module::logger_interface' is not a base of 'kcenon::logger::logger'

Solution:

// Change from
thread_module::logger_interface* logger = ...;
// To
common::interfaces::ILogger* logger = ...;

Issue 3: Result Type Mismatch

Error:

error: cannot convert 'common::VoidResult' to 'result_void'

Solution:

// Change from
result_void result = logger->log(...);
// To
// Or simply
auto result = logger->log(...);

Issue 4: Missing thread_system

Error:

error: 'thread_module' has not been declared

Solution:

// v3.0 doesn't require thread_system
// Change from
#include <thread_system/logger_interface.h>
// To
#include <common/interfaces/logger_interface.h>

Issue 5: C++20 Not Enabled

Error:

error: 'source_location' is not a member of 'std'

Solution:

# Ensure C++20 is enabled
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

Migration Checklist

v2.x to v3.0 Migration

  • Enable C++20 in build system
  • Update common_system dependency
  • Update include paths (logger_system/kcenon/logger/)
  • Update interface references (thread_module::logger_interfacecommon::interfaces::ILogger)
  • Update log level types (thread_module::log_levelcommon::interfaces::log_level)
  • Update result types (result_voidcommon::VoidResult)
  • Remove thread_system dependency if not needed
  • Update deprecated method calls (set_min_levelset_level)
  • Test with sanitizers
  • Performance benchmarks
  • Update documentation

v1.x to v2.x Migration

  • Backup current codebase
  • Create migration branch
  • Add compatibility headers
  • Update build system (CMake/Make)
  • Migrate logger creation to builder pattern
  • Update writer management to smart pointers
  • Convert logging calls
  • Update configuration
  • Migrate tests
  • Remove deprecated code
  • Run full test suite
  • Performance benchmarks
  • Update documentation
  • Code review
  • Merge to main branch

Support and Resources

For migration assistance, please file an issue with the migration label.


Last Updated: 2026-01-23