37 {
38 std::cout << "=== Logger Advanced Features Demo ===" << std::endl;
39
40
41 std::filesystem::create_directories("logs");
42
43
44 auto logger = std::make_unique<kcenon::logger::logger>(
true, 1024);
45
46
47 logger->add_writer(
"console", std::make_unique<console_writer>());
48 logger->add_writer(
"error_file", std::make_unique<file_writer>(
"logs/errors.log"));
49 logger->add_writer(
"debug_file", std::make_unique<file_writer>(
"logs/debug.log"));
50 logger->add_writer(
"rotating", std::make_unique<rotating_file_writer>(
51 "logs/app.log",
52 1024 * 1024,
53 5
54 ));
55
56
58
59 std::cout << "\n1. Testing Basic Filtering (level >= warning):" << std::endl;
60
61
62
63 logger->set_filter(std::make_unique<level_filter>(log_level::warning));
64
65 logger->log(ci::log_level::trace, std::string(
"This trace message should be filtered out"));
66 logger->log(ci::log_level::debug, std::string(
"This debug message should be filtered out"));
67 logger->log(ci::log_level::info, std::string(
"This info message should be filtered out"));
68 logger->log(ci::log_level::warning, std::string(
"This warning should be logged"));
69 logger->log(ci::log_level::error, std::string(
"This error should be logged"));
70
71 std::this_thread::sleep_for(std::chrono::milliseconds(100));
72
73 std::cout << "\n2. Testing Regex Filtering (exclude 'sensitive'):" << std::endl;
74
75
76 logger->set_filter(std::make_unique<regex_filter>(
"sensitive",
false));
77
78 logger->log(ci::log_level::error, std::string(
"This contains sensitive data - should be filtered"));
79 logger->log(ci::log_level::error, std::string(
"This is a normal error message - should be logged"));
80
81 std::this_thread::sleep_for(std::chrono::milliseconds(100));
82
83 std::cout << "\n3. Testing Composite Filtering:" << std::endl;
84 std::cout << " (level >= warning) AND (not contains 'ignore')" << std::endl;
85
86
87 auto composite = std::make_unique<composite_filter>(composite_filter::logic_type::AND);
88 composite->add_filter(std::make_unique<level_filter>(log_level::warning));
89 composite->add_filter(std::make_unique<regex_filter>(
"ignore",
false));
90
92
93 logger->log(ci::log_level::info, std::string(
"Info: Should be filtered by level"));
94 logger->log(ci::log_level::warning, std::string(
"Warning: Should be logged"));
95 logger->log(ci::log_level::error, std::string(
"Error: Please ignore this - filtered by regex"));
96 logger->log(ci::log_level::error, std::string(
"Error: Real error message - should be logged"));
97
98 std::this_thread::sleep_for(std::chrono::milliseconds(100));
99
100 std::cout << "\n4. Testing Rotating File Writer:" << std::endl;
101
102
103 logger->set_filter(
nullptr);
104
105
106 std::cout << " Writing 1000 log entries to trigger file rotation..." << std::endl;
107 for (int i = 0; i < 1000; ++i) {
108 std::string msg = "Log entry " + std::to_string(i) +
109 " - This is a longer message to fill up the file size quickly. "
110 "Adding more text to reach the rotation threshold faster.";
111 logger->log(ci::log_level::info, msg);
112 }
113
114 std::cout << "\n5. Testing Custom Function Filter:" << std::endl;
115 std::cout << " (only log messages from main thread)" << std::endl;
116
117
118 auto main_thread_id = std::this_thread::get_id();
119 auto thread_filter = std::make_unique<function_filter>(
120 [main_thread_id](
const log_entry& entry) {
121 (void)entry;
122 return std::this_thread::get_id() == main_thread_id;
123 }
124 );
125
126 logger->set_filter(std::move(thread_filter));
127
128
129 logger->log(ci::log_level::info, std::string(
"Message from main thread - should be logged"));
130
131
132 std::thread other_thread([&
logger]() {
133 logger->log(ci::log_level::info, std::string(
"Message from other thread - should be filtered"));
134 });
135 other_thread.join();
136
137
140
141 std::cout << "\n=== Demo Complete ===" << std::endl;
142 std::cout << "Check the logs/ directory for output files:" << std::endl;
143 std::cout << "- errors.log: Contains error messages" << std::endl;
144 std::cout << "- debug.log: Contains debug level messages" << std::endl;
145 std::cout << "- app.log*: Rotating log files" << std::endl;
146
147 return 0;
148}
Represents a single log entry with all associated metadata.