23#include <kcenon/logger/builders/writer_builder.h>
30#ifdef LOGGER_WITH_ENCRYPTION
31#include <kcenon/logger/security/secure_key.h>
42using log_level = common::interfaces::log_level;
56 return "level_filter";
72 return msg.find(
keyword_) != std::string::npos;
76 return "content_filter";
84 std::cout <<
"\n" << std::string(60,
'=') <<
"\n";
85 std::cout << title <<
"\n";
86 std::cout << std::string(60,
'=') <<
"\n";
98 std::cout <<
"\n1.1 File Writer:\n";
103 std::cout <<
" Use case: Direct file output, simplest form\n";
105 std::cout <<
"\n1.2 Console Writer:\n";
110 std::cout <<
" Use case: Development, debugging, immediate visual feedback\n";
112 std::cout <<
"\nKey Points:\n";
113 std::cout <<
" • Core writers provide the actual I/O functionality\n";
114 std::cout <<
" • No buffering, no async - synchronous and immediate\n";
115 std::cout <<
" • Best for: Simple use cases, testing, development\n";
126 std::cout <<
"\n2.1 Async Writer (Performance):\n";
127 auto async_log_writer = writer_builder()
131 std::cout <<
" Created: " << async_log_writer->get_name() <<
"\n";
132 std::cout <<
" Benefit: Non-blocking writes, background thread processing\n";
133 std::cout <<
" Trade-off: Slight delay in writing, memory for queue\n";
134 std::cout <<
" Best for: High-throughput applications\n";
137 if (
auto* async_w =
dynamic_cast<async_writer*
>(async_log_writer.get())) {
139 std::cout <<
" Status: Started background thread\n";
143 std::cout <<
"\n2.2 Buffered Writer (I/O Efficiency):\n";
145 .file(
"buffered.log")
149 std::cout <<
" Benefit: Reduces I/O operations by batching\n";
150 std::cout <<
" Trade-off: Logs may be delayed until buffer fills\n";
151 std::cout <<
" Best for: Moderate throughput, reducing disk I/O\n";
153 std::cout <<
"\n2.3 Filtered Writer (Selective Logging):\n";
154 auto filter = std::make_unique<level_filter>(log_level::warning);
156 .file(
"warnings.log")
157 .filtered(std::move(filter))
160 std::cout <<
" Benefit: Only writes logs meeting criteria (e.g., WARNING+)\n";
161 std::cout <<
" Trade-off: Filtering overhead (usually negligible)\n";
162 std::cout <<
" Best for: Separate error logs, compliance logging\n";
164#ifdef LOGGER_WITH_ENCRYPTION
165 std::cout <<
"\n2.4 Encrypted Writer (Security):\n";
167 auto key_result = secure_key_storage::generate_key(32);
168 if (key_result.is_ok()) {
170 .file(
"secure.log.enc")
171 .encrypted(std::move(key_result.value()))
174 std::cout <<
" Benefit: AES-256-GCM encryption for sensitive data\n";
175 std::cout <<
" Trade-off: CPU overhead for encryption\n";
176 std::cout <<
" Best for: Compliance (GDPR, PCI DSS), sensitive logs\n";
179 std::cout <<
"\n2.4 Encrypted Writer: Skipped (encryption not available)\n";
182 std::cout <<
"\nKey Points:\n";
183 std::cout <<
" • Each decorator adds specific functionality\n";
184 std::cout <<
" • Single decorators are easier to reason about\n";
185 std::cout <<
" • Combine multiple decorators for complex scenarios\n";
197 std::cout <<
"\n3.1 Buffered + Async (Common Pattern):\n";
198 auto buffered_async = writer_builder()
203 std::cout <<
" Created: " << buffered_async->get_name() <<
"\n";
204 std::cout <<
" Order: file → buffered(500) → async(20000)\n";
205 std::cout <<
" Rationale:\n";
206 std::cout <<
" 1. Buffering reduces I/O operations\n";
207 std::cout <<
" 2. Async provides non-blocking writes\n";
208 std::cout <<
" Best for: High-performance production applications\n";
210 if (
auto* async_w =
dynamic_cast<async_writer*
>(buffered_async.get())) {
215 std::cout <<
"\n3.2 Filtered + Buffered + Async (Error Log):\n";
216 auto error_filter = std::make_unique<level_filter>(log_level::error);
217 auto filtered_buffered_async = writer_builder()
219 .filtered(std::move(error_filter))
223 std::cout <<
" Created: " << filtered_buffered_async->get_name() <<
"\n";
224 std::cout <<
" Order: file → filtered → buffered(100) → async(5000)\n";
225 std::cout <<
" Rationale:\n";
226 std::cout <<
" 1. Filter early to reduce processing\n";
227 std::cout <<
" 2. Buffer to batch error logs\n";
228 std::cout <<
" 3. Async for non-blocking error logging\n";
229 std::cout <<
" Best for: Separate error logs with filtering\n";
231 if (
auto* async_w =
dynamic_cast<async_writer*
>(filtered_buffered_async.get())) {
236#ifdef LOGGER_WITH_ENCRYPTION
237 std::cout <<
"\n3.3 Buffered + Encrypted + Async (Secure High-Performance):\n";
239 auto key_result = secure_key_storage::generate_key(32);
240 if (key_result.is_ok()) {
241 auto secure_writer = writer_builder()
242 .file(
"secure.log.enc")
244 .encrypted(std::move(key_result.value()))
247 std::cout <<
" Created: " << secure_writer->get_name() <<
"\n";
248 std::cout <<
" Order: file → buffered(200) → encrypted → async(10000)\n";
249 std::cout <<
" Rationale:\n";
250 std::cout <<
" 1. Buffer to reduce encryption overhead\n";
251 std::cout <<
" 2. Encrypt for security (batches are encrypted together)\n";
252 std::cout <<
" 3. Async to prevent encryption from blocking\n";
253 std::cout <<
" Best for: Secure, high-performance logging\n";
255 if (
auto* async_w =
dynamic_cast<async_writer*
>(secure_writer.get())) {
261 std::cout <<
"\n3.3 Encrypted combination: Skipped (encryption not available)\n";
264 std::cout <<
"\nDecorator Order Principle:\n";
265 std::cout <<
" Core Writer → Filtering → Buffering → Encryption → Thread-Safety → Async\n";
266 std::cout <<
"\nWhy this order?\n";
267 std::cout <<
" 1. Filter early: Reduce work for downstream decorators\n";
268 std::cout <<
" 2. Buffer before encrypt: Amortize encryption cost\n";
269 std::cout <<
" 3. Thread-safe before async: Ensure consistency\n";
270 std::cout <<
" 4. Async outermost: Maximize non-blocking benefits\n";
281 std::cout <<
"\n4.1 High-Throughput Pattern:\n";
282 std::cout <<
" Configuration: file → buffered(1000) → async(50000)\n";
283 std::cout <<
" Throughput: ~4M messages/second (single thread)\n";
284 std::cout <<
" Latency: ~148ns average\n";
285 std::cout <<
" Use case: Logging-heavy applications, analytics\n";
287 std::cout <<
"\n4.2 Low-Latency Pattern:\n";
288 std::cout <<
" Configuration: file → async(small_queue)\n";
289 std::cout <<
" Throughput: Lower than buffered\n";
290 std::cout <<
" Latency: Minimal buffering delay\n";
291 std::cout <<
" Use case: Real-time systems, trading platforms\n";
293 std::cout <<
"\n4.3 Balanced Pattern:\n";
294 std::cout <<
" Configuration: file → buffered(500) → async(20000)\n";
295 std::cout <<
" Throughput: Good (millions of messages/second)\n";
296 std::cout <<
" Latency: Acceptable for most applications\n";
297 std::cout <<
" Use case: General production applications\n";
299 std::cout <<
"\n4.4 Security-First Pattern:\n";
300 std::cout <<
" Configuration: file → filtered → encrypted → buffered → async\n";
301 std::cout <<
" Throughput: Moderate (encryption overhead)\n";
302 std::cout <<
" Latency: Higher due to encryption\n";
303 std::cout <<
" Use case: Compliance-critical applications\n";
305 std::cout <<
"\nPerformance Tips:\n";
306 std::cout <<
" • Larger buffers = fewer I/O ops but more memory\n";
307 std::cout <<
" • Larger async queues = better burst handling\n";
308 std::cout <<
" • Encryption adds ~10-20% CPU overhead\n";
309 std::cout <<
" • Filtering early reduces downstream processing\n";
322 std::cout <<
"\n5.1 Web Application Logging:\n";
323 std::cout <<
" Requirements: High throughput, separate error logs, async\n";
326 auto main_log = writer_builder()
331 std::cout <<
" Main log: " << main_log->get_name() <<
"\n";
333 if (
auto* async_w =
dynamic_cast<async_writer*
>(main_log.get())) {
339 auto error_filter = std::make_unique<level_filter>(log_level::error);
340 auto error_log = writer_builder()
342 .filtered(std::move(error_filter))
345 std::cout <<
" Error log: " << error_log->get_name() <<
"\n";
347 if (
auto* async_w =
dynamic_cast<async_writer*
>(error_log.get())) {
350 log.
add_writer(
"errors", std::move(error_log));
353 auto console = writer_builder()
356 std::cout <<
" Console: " << console->get_name() <<
"\n";
357 log.
add_writer(
"console", std::move(console));
359 std::cout <<
"\n5.2 Microservice with Observability:\n";
360 std::cout <<
" Requirements: Structured logs, filtering, async\n";
362 std::cout <<
" Pattern: file → filtered → buffered → async\n";
363 std::cout <<
" Additional: OTLP writer for OpenTelemetry export\n";
365#ifdef LOGGER_WITH_ENCRYPTION
366 std::cout <<
"\n5.3 Healthcare/Financial Application:\n";
367 std::cout <<
" Requirements: HIPAA/PCI compliance, encryption, audit trail\n";
369 auto key_result = secure_key_storage::generate_key(32);
370 if (key_result.is_ok()) {
371 auto secure_log = writer_builder()
372 .file(
"audit.log.enc")
374 .encrypted(std::move(key_result.value()))
377 std::cout <<
" Audit log: " << secure_log->get_name() <<
"\n";
378 std::cout <<
" Pattern: file → buffered → encrypted → async\n";
380 if (
auto* async_w =
dynamic_cast<async_writer*
>(secure_log.get())) {
383 log.
add_writer(
"audit", std::move(secure_log));
386 std::cout <<
"\n5.3 Secure logging: Skipped (encryption not available)\n";
390 std::cout <<
"\nTesting the setup:\n";
391 log.
log(log_level::info, std::string(
"User logged in"));
392 log.
log(log_level::warning, std::string(
"Session expiring soon"));
393 log.
log(log_level::error, std::string(
"Payment processing failed"));
395 std::cout <<
" INFO: → main log, console\n";
396 std::cout <<
" WARNING: → main log, console\n";
397 std::cout <<
" ERROR: → main log, errors log, console\n";
400 std::cout <<
"\nProduction Best Practices:\n";
401 std::cout <<
" 1. Always use async for production\n";
402 std::cout <<
" 2. Separate error logs for quick triage\n";
403 std::cout <<
" 3. Buffer sizes: 100-1000 entries\n";
404 std::cout <<
" 4. Async queue: 10000-50000 entries\n";
405 std::cout <<
" 5. Monitor queue utilization\n";
406 std::cout <<
" 6. Always call flush() on shutdown\n";
417 std::cout <<
"\n6.1 Content-Based Filtering:\n";
418 auto content_filter_ptr = std::make_unique<content_filter>(
"database");
419 auto db_log = writer_builder()
420 .file(
"database_events.log")
421 .filtered(std::move(content_filter_ptr))
425 std::cout <<
" Created: " << db_log->get_name() <<
"\n";
426 std::cout <<
" Filter: Only logs containing 'database'\n";
427 std::cout <<
" Use case: Component-specific logging\n";
429 if (
auto* async_w =
dynamic_cast<async_writer*
>(db_log.get())) {
434 std::cout <<
"\n6.2 Level-Based Filtering:\n";
435 std::cout <<
" Critical errors only:\n";
436 auto critical_filter = std::make_unique<level_filter>(log_level::critical);
437 auto critical_log = writer_builder()
438 .file(
"critical.log")
439 .filtered(std::move(critical_filter))
441 std::cout <<
" Created: " << critical_log->get_name() <<
"\n";
443 std::cout <<
"\nFiltering Strategies:\n";
444 std::cout <<
" • By level: Common, efficient\n";
445 std::cout <<
" • By content: Flexible, component-specific\n";
446 std::cout <<
" • By custom logic: Implement log_filter_interface\n";
447 std::cout <<
" • Composite filters: Combine multiple filters (AND/OR)\n";
458 std::cout <<
"\nOLD (Deprecated - Manual Nesting):\n";
459 std::cout <<
" auto writer = std::make_unique<async_writer>(\n";
460 std::cout <<
" std::make_unique<buffered_writer>(\n";
461 std::cout <<
" std::make_unique<file_writer>(\"app.log\"),\n";
462 std::cout <<
" 500),\n";
463 std::cout <<
" 20000);\n";
464 std::cout <<
"\nProblems:\n";
465 std::cout <<
" ✗ Verbose and error-prone\n";
466 std::cout <<
" ✗ Nesting order is unclear\n";
467 std::cout <<
" ✗ Hard to modify (add/remove decorators)\n";
469 std::cout <<
"\nNEW (Recommended - Writer Builder):\n";
470 std::cout <<
" auto writer = writer_builder()\n";
471 std::cout <<
" .file(\"app.log\")\n";
472 std::cout <<
" .buffered(500)\n";
473 std::cout <<
" .async(20000)\n";
474 std::cout <<
" .build();\n";
475 std::cout <<
"\nBenefits:\n";
476 std::cout <<
" ✓ Clear, self-documenting\n";
477 std::cout <<
" ✓ Type-safe at compile time\n";
478 std::cout <<
" ✓ Easy to modify\n";
479 std::cout <<
" ✓ Follows decorator order convention\n";
481 auto writer = writer_builder()
482 .file(
"migration_example.log")
487 std::cout <<
"\nResult: " << writer->get_name() <<
"\n";
489 if (
auto* async_w =
dynamic_cast<async_writer*
>(writer.get())) {
494 std::cout <<
"\nMigration Steps:\n";
495 std::cout <<
" 1. Identify manual decorator nesting in your code\n";
496 std::cout <<
" 2. Replace with writer_builder() calls\n";
497 std::cout <<
" 3. Test thoroughly (behavior should be identical)\n";
498 std::cout <<
" 4. Enjoy improved readability and maintainability\n";
502 std::cout <<
"Comprehensive Decorator Pattern Usage Examples\n";
503 std::cout << std::string(60,
'=') <<
"\n";
504 std::cout <<
"\nThis example covers all decorator functionality:\n";
505 std::cout <<
" • Core writers (file, console)\n";
506 std::cout <<
" • All decorators (async, buffered, filtered, encrypted)\n";
507 std::cout <<
" • Decorator composition and order\n";
508 std::cout <<
" • Performance patterns and trade-offs\n";
509 std::cout <<
" • Real-world production scenarios\n";
510 std::cout <<
" • Migration from manual nesting\n";
522 std::cout <<
"\nRecommended Order (innermost to outermost):\n";
523 std::cout <<
" 1. Core Writer (file/console) - The actual I/O\n";
524 std::cout <<
" 2. Filtering - Reduce work early\n";
525 std::cout <<
" 3. Buffering - Batch for efficiency\n";
526 std::cout <<
" 4. Encryption - Encrypt batches\n";
527 std::cout <<
" 5. Thread-Safety - Ensure consistency\n";
528 std::cout <<
" 6. Async - Outermost for maximum non-blocking benefit\n";
530 std::cout <<
"\nQuick Reference:\n";
531 std::cout <<
" • High throughput: .buffered(1000).async(50000)\n";
532 std::cout <<
" • Low latency: .async(small_queue)\n";
533 std::cout <<
" • Secure: .buffered().encrypted().async()\n";
534 std::cout <<
" • Filtered: .filtered(filter).buffered().async()\n";
537 std::cout <<
"\nFor more details, see:\n";
538 std::cout <<
" • README.md - Quick start and examples\n";
539 std::cout <<
" • docs/guides/DECORATOR_MIGRATION.md - Migration guide\n";
540 std::cout <<
" • examples/writer_builder_example.cpp - Builder examples\n";
542 }
catch (
const std::exception& e) {
543 std::cerr <<
"\nError: " << e.what() <<
"\n";
Asynchronous wrapper for log writers.
Custom filter that filters by message content.
content_filter(std::string keyword)
std::string get_name() const override
Get the name of this filter.
bool should_log(const log_entry &entry) const override
Check if a log entry should be processed.
Asynchronous wrapper for log writers.
Decorator that buffers log entries before writing to wrapped writer.
Core console writer for logging to stdout/stderr.
std::string get_name() const override
Get writer name.
std::string get_name() const override
Get the name of this writer.
Decorator that encrypts log data before writing.
Core file writer for logging to files.
std::string get_name() const override
Get writer name.
Decorator that applies a filter to a wrapped writer.
std::string get_name() const override
Get the name of this writer.
Filter logs by minimum level.
Interface for log filters.
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)
common::VoidResult flush() override
Flush any buffered log messages (ILogger interface)
const char * data() const noexcept
Get data pointer.
size_t size() const noexcept
Get size.
bool should_log(const log_entry &entry) const override
Check if a log entry should be processed.
level_filter(log_level min_level)
std::string get_name() const override
Get the name of this filter.
Console writer for logging to stdout/stderr.
void example_single_decorators()
Example 2: Single Decorator Usage.
void print_section(const std::string &title)
void example_core_writers()
Example 1: Core Writers (No Decorators)
void example_performance_patterns()
Example 4: Performance Comparison.
void example_custom_filtering()
Example 6: Custom Filtering Patterns.
void example_migration_patterns()
Example 7: Migration from Manual Nesting.
void example_multiple_decorators()
Example 3: Multiple Decorator Composition.
void example_production_scenarios()
Example 5: Real-World Production Scenarios.
File writer for logging to files with optional buffering.
Interface for log filters used by filtered_logger.
High-performance, thread-safe logging system with asynchronous capabilities.
common::interfaces::log_level log_level
RAII wrapper for encryption keys with secure memory management.
Represents a single log entry with all associated metadata.
log_level level
Severity level of the log message.
small_string_256 message
The actual log message.