This example shows how to configure the logger system to prevent loss of critical log messages during crashes or abnormal termination.
#include <kcenon/common/interfaces/logger_interface.h>
#include <iostream>
namespace ci = kcenon::common::interfaces;
std::cout << "\n=== Example 1: Basic Critical Writer ===\n";
auto file = std::make_unique<file_writer>("logs/critical_basic.log");
auto critical = std::make_unique<critical_writer>(
std::move(file),
.force_flush_on_critical = true,
.force_flush_on_error = false,
.write_ahead_log = false,
.sync_on_critical = true
}
);
log.
log(ci::log_level::info, std::string(
"Application started"));
log.
log(ci::log_level::debug, std::string(
"Debug information"));
log.
log(ci::log_level::critical, std::string(
"Critical error occurred - guaranteed on disk"));
std::cout << "Critical log written and flushed immediately\n";
}
std::cout << "\n=== Example 2: Write-Ahead Logging ===\n";
auto file = std::make_unique<rotating_file_writer>(
"logs/wal_main.log",
1024 * 1024,
5
);
auto critical = std::make_unique<critical_writer>(
std::move(file),
.force_flush_on_critical = true,
.write_ahead_log = true,
.wal_path = "logs/.critical.wal",
.sync_on_critical = true
}
);
log.add_writer(std::move(critical));
log.log(ci::log_level::info, std::string("Normal log"));
log.log(ci::log_level::critical, std::string("Critical log - written to WAL first"));
std::cout << "Check logs/.critical.wal for write-ahead log entries\n";
}
std::cout << "\n=== Example 3: Hybrid Writer (Async + Critical) ===\n";
auto hybrid = std::make_unique<hybrid_writer>(
std::make_unique<file_writer>("logs/hybrid.log"),
.force_flush_on_critical = true,
.force_flush_on_error = true
},
10000
);
log.add_writer(std::move(hybrid));
for (int i = 0; i < 100; ++i) {
log.log(ci::log_level::info, "High-frequency log " + std::to_string(i));
}
log.log(ci::log_level::critical, std::string("Critical error - no loss guaranteed"));
std::cout << "Hybrid writer provides both performance and safety\n";
}
std::cout << "\n=== Example 4: Production Configuration ===\n";
std::make_unique<hybrid_writer>(
std::make_unique<rotating_file_writer>(
"logs/production.log",
100 * 1024 * 1024,
10
),
.force_flush_on_critical = true,
.force_flush_on_error = true,
.write_ahead_log = true,
.wal_path = "logs/.production.wal",
.sync_on_critical = true,
.critical_write_timeout_ms = 5000
},
50000
)
)
.build();
return;
}
log->start();
log->log(ci::log_level::info, std::string("Service started"));
log->log(ci::log_level::warning, std::string("Cache miss rate high"));
log->log(ci::log_level::error, std::string("Database connection timeout"));
log->log(ci::log_level::critical, std::string("Out of memory - terminating"));
log->flush();
log->stop();
std::cout << "Production setup complete\n";
std::cout << "Configuration:\n";
std::cout << " - Async logging for normal messages (performance)\n";
std::cout << " - Immediate flush for errors and critical (safety)\n";
std::cout << " - Write-ahead logging for crash recovery\n";
std::cout << " - File rotation to manage disk space\n";
}
std::cout << "\n=== Example 5: Error Handling & Statistics ===\n";
auto critical = std::make_unique<critical_writer>(
std::make_unique<file_writer>("logs/stats.log"),
.force_flush_on_critical = true,
.write_ahead_log = true,
.wal_path = "logs/.stats.wal"
}
);
const auto& config =
critical->get_config();
const auto& stats =
critical->get_stats();
log.add_writer(std::move(critical));
log.log(ci::log_level::info, std::string("Info message"));
log.log(ci::log_level::warning, std::string("Warning message"));
log.log(ci::log_level::error, std::string("Error message"));
log.log(ci::log_level::critical, std::string("Critical message 1"));
log.log(ci::log_level::critical, std::string("Critical message 2"));
log.log(ci::log_level::critical, std::string("Fatal message"));
std::cout << "\nConfiguration:\n";
std::cout << " Force flush on critical: " << config.force_flush_on_critical << "\n";
std::cout << " Force flush on error: " << config.force_flush_on_error << "\n";
std::cout << " WAL enabled: " << config.write_ahead_log << "\n";
std::cout << " Sync on critical: " << config.sync_on_critical << "\n";
std::cout << "\nStatistics:\n";
std::cout << " Total critical writes: " << stats.total_critical_writes.load() << "\n";
std::cout << " Total flushes: " << stats.total_flushes.load() << "\n";
std::cout << " WAL writes: " << stats.wal_writes.load() << "\n";
std::cout << " Sync calls: " << stats.sync_calls.load() << "\n";
std::cout << "\nChanging configuration at runtime...\n";
}
std::cout << "Critical Logging Examples\n";
std::cout << "=========================\n";
try {
std::cout << "\n=== All Examples Completed Successfully ===\n";
std::cout << "\nCheck the logs/ directory for output files:\n";
std::cout << " - *.log: Main log files\n";
std::cout << " - .*.wal: Write-ahead log files\n";
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << "\n";
return 1;
}
return 0;
}
Asynchronous wrapper for log writers.
Builder pattern for logger construction with validation.
logger_builder & with_min_level(log_level level)
logger_builder & with_async(bool async=true)
logger_builder & add_writer(const std::string &name, log_writer_ptr writer)
Add a writer to the logger.
logger_builder & with_buffer_size(std::size_t size)
Set buffer size.
common::VoidResult add_writer(log_writer_ptr writer)
common::VoidResult log(common::interfaces::log_level level, const std::string &message) override
Log a message with specified level (ILogger interface)
const std::string & error_message() const
void example_write_ahead_logging()
void example_basic_critical_writer()
void example_hybrid_writer()
void example_error_handling()
void example_production_setup()
Synchronous wrapper for critical log messages to prevent loss.
File writer for logging to files with optional buffering.
High-performance, thread-safe logging system with asynchronous capabilities.
Builder pattern implementation for flexible logger configuration kcenon.
Rotating file writer with size and time-based rotation.
Configuration for critical log writer.