#include <kcenon/common/interfaces/logger_interface.h>
#include <iostream>
#include <thread>
#include <chrono>
#include <filesystem>
namespace ci = kcenon::common::interfaces;
std::cout << "=== Logger Advanced Features Demo ===" << std::endl;
std::filesystem::create_directories("logs");
auto logger = std::make_unique<kcenon::logger::logger>(
true, 1024);
logger->add_writer(
"console", std::make_unique<console_writer>());
logger->add_writer(
"error_file", std::make_unique<file_writer>(
"logs/errors.log"));
logger->add_writer(
"debug_file", std::make_unique<file_writer>(
"logs/debug.log"));
logger->add_writer(
"rotating", std::make_unique<rotating_file_writer>(
"logs/app.log",
1024 * 1024,
5
));
std::cout << "\n1. Testing Basic Filtering (level >= warning):" << std::endl;
logger->set_filter(std::make_unique<level_filter>(log_level::warning));
logger->log(ci::log_level::trace, std::string(
"This trace message should be filtered out"));
logger->log(ci::log_level::debug, std::string(
"This debug message should be filtered out"));
logger->log(ci::log_level::info, std::string(
"This info message should be filtered out"));
logger->log(ci::log_level::warning, std::string(
"This warning should be logged"));
logger->log(ci::log_level::error, std::string(
"This error should be logged"));
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << "\n2. Testing Regex Filtering (exclude 'sensitive'):" << std::endl;
logger->set_filter(std::make_unique<regex_filter>(
"sensitive",
false));
logger->log(ci::log_level::error, std::string(
"This contains sensitive data - should be filtered"));
logger->log(ci::log_level::error, std::string(
"This is a normal error message - should be logged"));
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << "\n3. Testing Composite Filtering:" << std::endl;
std::cout << " (level >= warning) AND (not contains 'ignore')" << std::endl;
auto composite = std::make_unique<composite_filter>(composite_filter::logic_type::AND);
composite->add_filter(std::make_unique<level_filter>(log_level::warning));
composite->add_filter(std::make_unique<regex_filter>("ignore", false));
logger->set_filter(std::move(composite));
logger->log(ci::log_level::info, std::string(
"Info: Should be filtered by level"));
logger->log(ci::log_level::warning, std::string(
"Warning: Should be logged"));
logger->log(ci::log_level::error, std::string(
"Error: Please ignore this - filtered by regex"));
logger->log(ci::log_level::error, std::string(
"Error: Real error message - should be logged"));
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << "\n4. Testing Rotating File Writer:" << std::endl;
std::cout << " Writing 1000 log entries to trigger file rotation..." << std::endl;
for (int i = 0; i < 1000; ++i) {
std::string msg = "Log entry " + std::to_string(i) +
" - This is a longer message to fill up the file size quickly. "
"Adding more text to reach the rotation threshold faster.";
logger->log(ci::log_level::info, msg);
}
std::cout << "\n5. Testing Custom Function Filter:" << std::endl;
std::cout << " (only log messages from main thread)" << std::endl;
auto main_thread_id = std::this_thread::get_id();
auto thread_filter = std::make_unique<function_filter>(
(void)entry;
return std::this_thread::get_id() == main_thread_id;
}
);
logger->set_filter(std::move(thread_filter));
logger->log(ci::log_level::info, std::string(
"Message from main thread - should be logged"));
std::thread other_thread([&
logger]() {
logger->log(ci::log_level::info, std::string(
"Message from other thread - should be filtered"));
});
other_thread.join();
std::cout << "\n=== Demo Complete ===" << std::endl;
std::cout << "Check the logs/ directory for output files:" << std::endl;
std::cout << "- errors.log: Contains error messages" << std::endl;
std::cout << "- debug.log: Contains debug level messages" << std::endl;
std::cout << "- app.log*: Rotating log files" << std::endl;
return 0;
}
Console writer for logging to stdout/stderr.
File writer for logging to files with optional buffering.
Log filtering functionality.
Data structures for representing log entries and source locations kcenon.
High-performance, thread-safe logging system with asynchronous capabilities.
Rotating file writer with size and time-based rotation.
Represents a single log entry with all associated metadata.