Logger System 0.1.3
High-performance C++20 thread-safe logging system with asynchronous capabilities
Loading...
Searching...
No Matches
kcenon::logger::logger Class Reference

Main logger implementation providing high-performance logging facilities. More...

#include <logger.h>

Inheritance diagram for kcenon::logger::logger:
Inheritance graph
Collaboration diagram for kcenon::logger::logger:
Collaboration graph

Classes

class  impl
 

Public Member Functions

 logger (bool async=true, std::size_t buffer_size=8192, std::unique_ptr< backends::integration_backend > backend=nullptr)
 Constructor with optional configuration.
 
 ~logger ()
 Destructor - ensures all logs are flushed.
 
common::VoidResult log (common::interfaces::log_level level, const std::string &message) override
 Log a message with specified level (ILogger interface)
 
common::VoidResult log (common::interfaces::log_level level, std::string_view message, const common::source_location &loc=common::source_location::current()) override
 Log a message with source location (ILogger interface, C++20)
 
common::VoidResult log (const common::interfaces::log_entry &entry) override
 Log a structured entry (ILogger interface)
 
bool is_enabled (common::interfaces::log_level level) const override
 Check if logging is enabled for the specified level (ILogger interface)
 
common::VoidResult set_level (common::interfaces::log_level level) override
 Set the minimum log level (ILogger interface)
 
common::interfaces::log_level get_level () const override
 Get the current minimum log level (ILogger interface)
 
common::VoidResult flush () override
 Flush any buffered log messages (ILogger interface)
 
common::VoidResult add_writer (log_writer_ptr writer)
 
common::VoidResult clear_writers ()
 Remove all writers.
 
common::VoidResult start ()
 
common::VoidResult stop ()
 Stop the logger.
 
bool is_running () const
 Check if logger is running.
 
common::VoidResult enable_metrics_collection (bool enable=true)
 Enable or disable metrics collection.
 
bool is_metrics_collection_enabled () const
 Check if metrics collection is enabled.
 
result< metrics::logger_performance_statsget_current_metrics () const
 Get current performance metrics.
 
result< std::unique_ptr< metrics::logger_performance_stats > > get_metrics_history (std::chrono::seconds duration) const
 Get metrics history for a specific duration.
 
common::VoidResult reset_metrics ()
 Reset performance metrics.
 
logger_metrics_collector * get_metrics_collector ()
 Get metrics collector for direct access.
 
common::VoidResult add_writer (const std::string &name, log_writer_ptr writer)
 Add a writer with a specific name.
 
bool remove_writer (const std::string &name)
 Remove a writer by name.
 
log_writer_interfaceget_writer (const std::string &name)
 Get a writer by name.
 
void set_filter (std::unique_ptr< log_filter_interface > filter)
 
bool has_filter () const
 Check if a filter is currently set.
 
log_routerget_router ()
 
const log_routerget_router () const
 Get the log router (const version)
 
void set_router (std::unique_ptr< log_router > router)
 Set a new log router.
 
bool has_routing () const
 Check if routing is enabled.
 
structured_log_builder log_structured (log_level level)
 
unified_log_contextcontext ()
 
const unified_log_contextcontext () const
 Get the unified context for this logger (const version)
 
void set_sampler (std::unique_ptr< sampling::log_sampler > sampler)
 
sampling::log_samplerget_sampler ()
 Get the log sampler (if set)
 
const sampling::log_samplerget_sampler () const
 Get the log sampler (const version)
 
bool has_sampling () const
 Check if sampling is enabled.
 
sampling::sampling_stats get_sampling_stats () const
 Get sampling statistics.
 
void reset_sampling_stats ()
 Reset sampling statistics.
 
int get_emergency_fd () const override
 Get file descriptor for emergency writing.
 
const char * get_emergency_buffer () const override
 Get emergency buffer pointer.
 
size_t get_emergency_buffer_size () const override
 Get emergency buffer size.
 
- Public Member Functions inherited from kcenon::logger::security::critical_logger_interface
virtual ~critical_logger_interface ()=default
 

Private Attributes

std::unique_ptr< implpimpl_
 

Detailed Description

Main logger implementation providing high-performance logging facilities.

The logger class provides a high-performance, thread-safe logging system with:

  • Asynchronous logging with configurable batching for optimal throughput
  • Multiple writer support for outputting to different destinations simultaneously
  • Real-time metrics collection and performance monitoring
  • Configurable filtering and routing of log messages
  • Integration with monitoring backends for production observability

The logger uses the PIMPL idiom to hide implementation details and maintain ABI stability. Implements common::interfaces::ILogger for standardized logging interface (Phase 2) and common::interfaces::IMonitorable for observability (Phase 2.2). Can be adapted to legacy thread_system interfaces through dedicated adapter classes.

Warning
When using asynchronous mode, ensure proper shutdown by calling stop() and flush() before destroying the logger to prevent loss of buffered messages.
Since
1.0.0
2.0.0 Implements common::interfaces::ILogger
Note
For integration with common_system monitoring interfaces, use logger_monitoring_adapter

Definition at line 156 of file logger.h.

Constructor & Destructor Documentation

◆ logger()

kcenon::logger::logger::logger ( bool async = true,
std::size_t buffer_size = 8192,
std::unique_ptr< backends::integration_backend > backend = nullptr )
explicit

Constructor with optional configuration.

Parameters
asyncEnable asynchronous logging (default: true)
buffer_sizeSize of the log buffer in bytes (default: 8192)
backendIntegration backend for level conversion (default: auto-detect)

Creates a logger instance with the specified configuration. In async mode, a background thread is created to process log messages, providing better performance for high-throughput applications.

If no backend is specified, the logger will auto-detect the appropriate backend based on compile-time flags (USE_THREAD_SYSTEM_INTEGRATION).

Note
The buffer_size parameter affects memory usage and batching efficiency. Larger buffers can improve throughput but increase memory consumption.
Since
1.0.0

Definition at line 211 of file logger.cpp.

212 : pimpl_(std::make_unique<impl>(async, buffer_size, std::move(backend))) {
213 // Initialize logger with configuration
214}
std::unique_ptr< impl > pimpl_
Definition logger.h:757

◆ ~logger()

kcenon::logger::logger::~logger ( )

Destructor - ensures all logs are flushed.

Properly shuts down the logger, ensuring all buffered messages are written to their destinations before destruction. Automatically calls stop() and flush() if the logger is still running.

Warning
Destruction may block until all pending messages are processed.
Since
1.0.0

Definition at line 216 of file logger.cpp.

216 {
217 if (pimpl_ && pimpl_->running_) {
218 stop();
219 }
220}
common::VoidResult stop()
Stop the logger.
Definition logger.cpp:245

References pimpl_, and stop().

Here is the call graph for this function:

Member Function Documentation

◆ add_writer() [1/2]

common::VoidResult kcenon::logger::logger::add_writer ( const std::string & name,
log_writer_ptr writer )

Add a writer with a specific name.

Parameters
nameName for the writer (used for later retrieval/removal)
writerUnique pointer to the writer
Returns
common::VoidResult Success or error code

Adds a writer with an associated name for later lookup or removal. The writer is also added to the general writers list.

Since
1.0.0

Definition at line 282 of file logger.cpp.

282 {
283 if (!pimpl_) {
284 return common::make_error<std::monostate>(
286 "Logger not initialized",
287 "logger_system");
288 }
289 if (!writer) {
290 return common::make_error<std::monostate>(
291 static_cast<int>(logger_error_code::invalid_argument),
292 "Writer cannot be null",
293 "logger_system");
294 }
295
296 std::shared_ptr<log_writer_interface> shared_writer(std::move(writer));
297
298 {
299 std::lock_guard<std::shared_mutex> lock(pimpl_->writers_mutex_);
300 pimpl_->writers_.push_back(shared_writer);
301 if (!name.empty()) {
302 pimpl_->named_writers_[name] = shared_writer;
303 }
304 }
305
306 // Register with collector if in async mode and running
307 if (pimpl_->async_mode_ && pimpl_->collector_ && pimpl_->running_) {
308 pimpl_->collector_->add_writer(shared_writer);
309 }
310
311 return common::ok();
312}
VoidResult ok()

References kcenon::logger::invalid_argument, kcenon::logger::invalid_configuration, kcenon::common::ok(), and pimpl_.

Here is the call graph for this function:

◆ add_writer() [2/2]

common::VoidResult kcenon::logger::logger::add_writer ( log_writer_ptr writer)
Examples
critical_logging_example.cpp, decorator_usage.cpp, and writer_builder_example.cpp.

Definition at line 265 of file logger.cpp.

265 {
266 if (pimpl_ && writer) {
267 std::shared_ptr<log_writer_interface> shared_writer(std::move(writer));
268
269 {
270 std::lock_guard<std::shared_mutex> lock(pimpl_->writers_mutex_);
271 pimpl_->writers_.push_back(shared_writer);
272 }
273
274 // Register with collector if in async mode and running
275 if (pimpl_->async_mode_ && pimpl_->collector_ && pimpl_->running_) {
276 pimpl_->collector_->add_writer(shared_writer);
277 }
278 }
279 return common::ok();
280}

References kcenon::common::ok(), and pimpl_.

Referenced by example_basic_critical_writer(), example_error_handling(), example_hybrid_writer(), example_production_scenarios(), example_production_setup(), and example_write_ahead_logging().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ clear_writers()

common::VoidResult kcenon::logger::logger::clear_writers ( )

Remove all writers.

Returns
common::VoidResult Success or error code

Removes all currently registered writers from the logger. After this call, log messages will not be output anywhere until new writers are added.

Warning
This operation cannot be undone. Removed writers are destroyed.
Since
1.0.0

Definition at line 314 of file logger.cpp.

314 {
315 if (pimpl_) {
316 {
317 std::lock_guard<std::shared_mutex> lock(pimpl_->writers_mutex_);
318 pimpl_->writers_.clear();
319 pimpl_->named_writers_.clear();
320 }
321
322 // Clear collectors writers if in async mode
323 if (pimpl_->async_mode_ && pimpl_->collector_) {
324 pimpl_->collector_->clear_writers();
325 }
326 }
327 return common::ok();
328}

References kcenon::common::ok(), and pimpl_.

Here is the call graph for this function:

◆ context() [1/2]

unified_log_context & kcenon::logger::logger::context ( )
nodiscard

◆ context() [2/2]

const unified_log_context & kcenon::logger::logger::context ( ) const
nodiscard

Get the unified context for this logger (const version)

Returns
Const reference to the unified log context
Since
3.5.0

Definition at line 774 of file logger.cpp.

774 {
775 return pimpl_->context_;
776}

References pimpl_.

◆ enable_metrics_collection()

common::VoidResult kcenon::logger::logger::enable_metrics_collection ( bool enable = true)

Enable or disable metrics collection.

Parameters
enabletrue to enable metrics collection
Returns
common::VoidResult indicating success or error

Definition at line 603 of file logger.cpp.

603 {
604 if (!pimpl_) {
605 return make_logger_void_result(logger_error_code::invalid_argument, "Logger not initialized");
606 }
607
608 pimpl_->metrics_enabled_ = enable;
609 if (!enable) {
611 }
612
613 return common::ok();
614}
LOGGER_SYSTEM_API logger_performance_stats g_logger_stats
Global logger metrics instance.
common::VoidResult make_logger_void_result(logger_error_code code, const std::string &message="")

References kcenon::logger::metrics::g_logger_stats, kcenon::logger::invalid_argument, kcenon::logger::make_logger_void_result(), kcenon::common::ok(), pimpl_, and kcenon::logger::metrics::logger_performance_stats::reset().

Here is the call graph for this function:

◆ flush()

common::VoidResult kcenon::logger::logger::flush ( )
override

Flush any buffered log messages (ILogger interface)

Returns
VoidResult indicating success or error
Note
Implements common::interfaces::ILogger::flush
Since
2.0.0
Examples
decorator_usage.cpp, and writer_builder_example.cpp.

Definition at line 574 of file logger.cpp.

574 {
575 if (!pimpl_) {
576 return common::make_error<std::monostate>(
578 "Logger not initialized",
579 "logger_system");
580 }
581
582 if (pimpl_->async_mode_ && pimpl_->collector_) {
583 // Async mode: collector handles both queue draining and writer flushing
584 pimpl_->collector_->flush();
585 } else {
586 // Synchronous mode: manually flush writers
587 std::vector<std::shared_ptr<log_writer_interface>> local_writers;
588 {
589 std::shared_lock<std::shared_mutex> lock(pimpl_->writers_mutex_);
590 local_writers = pimpl_->writers_;
591 }
592
593 for (auto& writer : local_writers) {
594 if (writer) {
595 writer->flush();
596 }
597 }
598 }
599
600 return common::ok();
601}

References kcenon::logger::invalid_configuration, kcenon::common::ok(), and pimpl_.

Referenced by example_production_scenarios(), example_production_setup(), kcenon::logger::adapters::logger_adapter::flush(), kcenon::logger::adapters::logger_adapter::shutdown(), and stop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_current_metrics()

result< logger_metrics > kcenon::logger::logger::get_current_metrics ( ) const

Get current performance metrics.

Returns
Result containing metrics or error

Definition at line 620 of file logger.cpp.

620 {
621 if (!pimpl_) {
622 return result<logger_metrics>{
624 "Logger not initialized"};
625 }
626
627 if (!pimpl_->metrics_enabled_) {
628 return result<logger_metrics>{
630 "Metrics collection is not enabled"};
631 }
632
633 // Return a copy of the current global metrics (thread-safe because of copy constructor)
634 // Use static factory method to avoid constructor ambiguity
636}
static result ok_value(const T &value)

References kcenon::logger::metrics::g_logger_stats, kcenon::logger::invalid_argument, kcenon::logger::result< T >::ok_value(), and pimpl_.

Here is the call graph for this function:

◆ get_emergency_buffer()

const char * kcenon::logger::logger::get_emergency_buffer ( ) const
overridevirtual

Get emergency buffer pointer.

Returns
Pointer to buffer or nullptr

This method must be signal-safe. The buffer contains pending log messages that should be flushed in case of emergency shutdown.

Since
2.0.0

Implements kcenon::logger::security::critical_logger_interface.

Definition at line 647 of file logger.cpp.

647 {
648 if (!pimpl_) {
649 return nullptr;
650 }
651 return pimpl_->emergency_buffer_;
652}

References pimpl_.

◆ get_emergency_buffer_size()

size_t kcenon::logger::logger::get_emergency_buffer_size ( ) const
overridevirtual

Get emergency buffer size.

Returns
Buffer size in bytes

This method must be signal-safe.

Since
2.0.0

Implements kcenon::logger::security::critical_logger_interface.

Definition at line 654 of file logger.cpp.

654 {
655 if (!pimpl_) {
656 return 0;
657 }
658 return pimpl_->emergency_buffer_used_.load(std::memory_order_acquire);
659}

References pimpl_.

◆ get_emergency_fd()

int kcenon::logger::logger::get_emergency_fd ( ) const
overridevirtual

Get file descriptor for emergency writing.

Returns
File descriptor or -1 if not available

This method provides a file descriptor for signal-safe emergency writing. It must be signal-safe (no allocations, no locks).

Since
2.0.0

Implements kcenon::logger::security::critical_logger_interface.

Definition at line 640 of file logger.cpp.

640 {
641 if (!pimpl_) {
642 return -1;
643 }
644 return pimpl_->emergency_fd_.load(std::memory_order_acquire);
645}

References pimpl_.

◆ get_level()

common::interfaces::log_level kcenon::logger::logger::get_level ( ) const
override

Get the current minimum log level (ILogger interface)

Returns
Current minimum log level using common::interfaces::log_level
Note
Implements common::interfaces::ILogger::get_level
Since
2.0.0

Definition at line 567 of file logger.cpp.

567 {
568 if (pimpl_) {
569 return pimpl_->min_level_.load();
570 }
571 return common::interfaces::log_level::info;
572}

References pimpl_.

Referenced by kcenon::logger::adapters::logger_adapter::get_level().

Here is the caller graph for this function:

◆ get_metrics_collector()

logger_metrics_collector * kcenon::logger::logger::get_metrics_collector ( )

Get metrics collector for direct access.

Returns
Pointer to metrics collector (may be null if not enabled)

◆ get_metrics_history()

result< std::unique_ptr< metrics::logger_performance_stats > > kcenon::logger::logger::get_metrics_history ( std::chrono::seconds duration) const

Get metrics history for a specific duration.

Parameters
durationHow far back to retrieve metrics
Returns
Result containing metrics snapshot or error

◆ get_router() [1/2]

log_router & kcenon::logger::logger::get_router ( )

Definition at line 680 of file logger.cpp.

680 {
681 if (!pimpl_) {
682 throw std::runtime_error("Logger not initialized");
683 }
684 std::shared_lock<std::shared_mutex> lock(pimpl_->router_mutex_);
685 return *pimpl_->router_;
686}

References pimpl_.

◆ get_router() [2/2]

const log_router & kcenon::logger::logger::get_router ( ) const

Get the log router (const version)

Returns
Const reference to the log router
Since
2.0.0

Definition at line 688 of file logger.cpp.

688 {
689 if (!pimpl_) {
690 throw std::runtime_error("Logger not initialized");
691 }
692 std::shared_lock<std::shared_mutex> lock(pimpl_->router_mutex_);
693 return *pimpl_->router_;
694}

References pimpl_.

◆ get_sampler() [1/2]

sampling::log_sampler * kcenon::logger::logger::get_sampler ( )
nodiscard

Get the log sampler (if set)

Returns
Pointer to sampler or nullptr if not set
Since
3.3.0

Definition at line 829 of file logger.cpp.

829 {
830 if (pimpl_) {
831 std::shared_lock<std::shared_mutex> lock(pimpl_->sampler_mutex_);
832 return pimpl_->sampler_.get();
833 }
834 return nullptr;
835}

References pimpl_.

◆ get_sampler() [2/2]

const sampling::log_sampler * kcenon::logger::logger::get_sampler ( ) const
nodiscard

Get the log sampler (const version)

Returns
Pointer to sampler or nullptr if not set
Since
3.3.0

Definition at line 837 of file logger.cpp.

837 {
838 if (pimpl_) {
839 std::shared_lock<std::shared_mutex> lock(pimpl_->sampler_mutex_);
840 return pimpl_->sampler_.get();
841 }
842 return nullptr;
843}

References pimpl_.

◆ get_sampling_stats()

sampling::sampling_stats kcenon::logger::logger::get_sampling_stats ( ) const
nodiscard

Get sampling statistics.

Returns
Sampling statistics including sampled/dropped counts
Since
3.3.0

Definition at line 853 of file logger.cpp.

853 {
854 if (pimpl_) {
855 std::shared_lock<std::shared_mutex> lock(pimpl_->sampler_mutex_);
856 if (pimpl_->sampler_) {
857 return pimpl_->sampler_->get_stats();
858 }
859 }
860 return sampling::sampling_stats{};
861}

References pimpl_.

◆ get_writer()

log_writer_interface * kcenon::logger::logger::get_writer ( const std::string & name)

Get a writer by name.

Parameters
nameName of the writer
Returns
Pointer to writer or nullptr if not found

Definition at line 359 of file logger.cpp.

359 {
360 if (!pimpl_ || name.empty()) {
361 return nullptr;
362 }
363
364 std::shared_lock<std::shared_mutex> lock(pimpl_->writers_mutex_);
365
366 auto it = pimpl_->named_writers_.find(name);
367 if (it != pimpl_->named_writers_.end() && it->second) {
368 return it->second.get();
369 }
370
371 return nullptr;
372}

References pimpl_.

◆ has_filter()

bool kcenon::logger::logger::has_filter ( ) const

Check if a filter is currently set.

Returns
true if a filter is active, false otherwise
Since
2.0.0

Definition at line 670 of file logger.cpp.

670 {
671 if (!pimpl_) {
672 return false;
673 }
674 std::shared_lock<std::shared_mutex> lock(pimpl_->filter_mutex_);
675 return pimpl_->filter_ != nullptr;
676}

References pimpl_.

◆ has_routing()

bool kcenon::logger::logger::has_routing ( ) const

Check if routing is enabled.

Returns
true if router has any routes configured
Since
2.0.0

Definition at line 703 of file logger.cpp.

703 {
704 if (!pimpl_) {
705 return false;
706 }
707 std::shared_lock<std::shared_mutex> lock(pimpl_->router_mutex_);
708 // Check if router has any routes configured by checking if get_writers_for_log
709 // returns anything for a test entry
710 return pimpl_->router_ != nullptr;
711}

References pimpl_.

◆ has_sampling()

bool kcenon::logger::logger::has_sampling ( ) const
nodiscard

Check if sampling is enabled.

Returns
true if a sampler is set and enabled
Since
3.3.0

Definition at line 845 of file logger.cpp.

845 {
846 if (pimpl_) {
847 std::shared_lock<std::shared_mutex> lock(pimpl_->sampler_mutex_);
848 return pimpl_->sampler_ != nullptr && pimpl_->sampler_->is_enabled();
849 }
850 return false;
851}

References pimpl_.

◆ is_enabled()

bool kcenon::logger::logger::is_enabled ( common::interfaces::log_level level) const
override

Check if logging is enabled for the specified level (ILogger interface)

Parameters
levelLog level to check using common::interfaces::log_level
Returns
true if logging is enabled for this level
Note
Implements common::interfaces::ILogger::is_enabled
Since
2.0.0

Definition at line 551 of file logger.cpp.

551 {
552 return pimpl_ && meets_threshold(level, pimpl_->min_level_.load());
553}

References pimpl_.

◆ is_metrics_collection_enabled()

bool kcenon::logger::logger::is_metrics_collection_enabled ( ) const

Check if metrics collection is enabled.

Returns
true if metrics collection is enabled

Definition at line 616 of file logger.cpp.

616 {
617 return pimpl_ && pimpl_->metrics_enabled_;
618}

References pimpl_.

◆ is_running()

bool kcenon::logger::logger::is_running ( ) const

Check if logger is running.

Returns
true if the logger is currently running, false otherwise

In async mode, returns true if the background processing thread is active. In sync mode, always returns true.

Since
1.0.0

Definition at line 261 of file logger.cpp.

261 {
262 return pimpl_ && pimpl_->running_;
263}

References pimpl_.

◆ log() [1/3]

common::VoidResult kcenon::logger::logger::log ( common::interfaces::log_level level,
const std::string & message )
override

Log a message with specified level (ILogger interface)

Parameters
levelLog level using common::interfaces::log_level
messageLog message
Returns
VoidResult indicating success or error
Note
Implements common::interfaces::ILogger::log
Since
2.0.0
Examples
critical_logging_example.cpp, decorator_usage.cpp, metrics_demo.cpp, and writer_builder_example.cpp.

Definition at line 378 of file logger.cpp.

379 {
380 if (!pimpl_ || !meets_threshold(level, pimpl_->min_level_.load())) {
381 return common::ok();
382 }
383
384 // Create log entry for filtering and routing
385 log_entry entry(level, message);
386
387 // Apply filter if set
388 {
389 std::shared_lock<std::shared_mutex> filter_lock(pimpl_->filter_mutex_);
390 if (pimpl_->filter_) {
391 if (!pimpl_->filter_->should_log(entry)) {
392 return common::ok(); // Message filtered out (not an error)
393 }
394 }
395 }
396
397 // Apply sampling if set
398 {
399 std::shared_lock<std::shared_mutex> sampler_lock(pimpl_->sampler_mutex_);
400 if (pimpl_->sampler_ && pimpl_->sampler_->is_enabled()) {
401 if (!pimpl_->sampler_->should_sample(entry)) {
402 return common::ok(); // Message sampled out (not an error)
403 }
404 }
405 }
406
407 // Record metrics if enabled
408 auto start_time = std::chrono::high_resolution_clock::now();
409
410 // Synchronous path: dispatch with routing support
411 pimpl_->dispatch_to_writers(level, message, "", 0, "", entry);
412
413 // Update metrics after logging
414 if (pimpl_->metrics_enabled_) {
415 auto end_time = std::chrono::high_resolution_clock::now();
416 auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time);
417 metrics::record_message_logged(duration.count());
418 }
419
420 return common::ok();
421}
void record_message_logged(uint64_t time_ns)
Record a logged message.

References kcenon::common::ok(), pimpl_, and kcenon::logger::metrics::record_message_logged().

Referenced by example_basic_critical_writer(), example_error_handling(), example_hybrid_writer(), example_production_scenarios(), example_production_setup(), example_write_ahead_logging(), generate_logs(), kcenon::logger::adapters::logger_adapter::log(), kcenon::logger::adapters::logger_adapter::log(), kcenon::logger::core::filtered_logger< MinLevel >::log(), kcenon::logger::core::filtered_logger< MinLevel >::log(), kcenon::logger::adapters::logger_adapter::log_entry(), and kcenon::logger::adapters::logger_adapter::log_with_location().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ log() [2/3]

common::VoidResult kcenon::logger::logger::log ( common::interfaces::log_level level,
std::string_view message,
const common::source_location & loc = common::source_location::current() )
override

Log a message with source location (ILogger interface, C++20)

Parameters
levelLog level
messageLog message (string_view for efficiency)
locSource location (automatically captured at call site)
Returns
VoidResult indicating success or error
Note
Implements common::interfaces::ILogger::log with source_location
Since
2.0.0

Definition at line 423 of file logger.cpp.

425 {
426 if (!pimpl_ || !meets_threshold(level, pimpl_->min_level_.load())) {
427 return common::ok();
428 }
429
430 std::string msg_str(message);
431 std::string file_str(loc.file_name());
432 int line = loc.line();
433 std::string func_str(loc.function_name());
434
435 // Create log entry for filtering and routing
436 log_entry entry(level, msg_str, file_str, line, func_str);
437
438 // Apply filter if set
439 {
440 std::shared_lock<std::shared_mutex> filter_lock(pimpl_->filter_mutex_);
441 if (pimpl_->filter_) {
442 if (!pimpl_->filter_->should_log(entry)) {
443 return common::ok(); // Message filtered out
444 }
445 }
446 }
447
448 // Apply sampling if set
449 {
450 std::shared_lock<std::shared_mutex> sampler_lock(pimpl_->sampler_mutex_);
451 if (pimpl_->sampler_ && pimpl_->sampler_->is_enabled()) {
452 if (!pimpl_->sampler_->should_sample(entry)) {
453 return common::ok(); // Message sampled out
454 }
455 }
456 }
457
458 // Record metrics if enabled
459 auto start_time = std::chrono::high_resolution_clock::now();
460
461 // Use async path if in async mode
462 if (pimpl_->async_mode_ && pimpl_->collector_) {
463 // Enqueue to collector for background processing
464 auto now = std::chrono::system_clock::now();
465 pimpl_->collector_->enqueue(level, msg_str, file_str, line, func_str, now);
466
467 // Update metrics if enabled (async path is much faster)
468 if (pimpl_->metrics_enabled_) {
469 auto end_time = std::chrono::high_resolution_clock::now();
470 auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time);
471 metrics::record_message_logged(duration.count());
472 }
473 return common::ok();
474 }
475
476 // Synchronous path: dispatch with routing support
477 pimpl_->dispatch_to_writers(level, msg_str, file_str, line, func_str, entry);
478
479 // Update metrics after logging
480 if (pimpl_->metrics_enabled_) {
481 auto end_time = std::chrono::high_resolution_clock::now();
482 auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time);
483 metrics::record_message_logged(duration.count());
484 }
485
486 return common::ok();
487}

References kcenon::common::ok(), pimpl_, and kcenon::logger::metrics::record_message_logged().

Here is the call graph for this function:

◆ log() [3/3]

common::VoidResult kcenon::logger::logger::log ( const common::interfaces::log_entry & entry)
override

Log a structured entry (ILogger interface)

Parameters
entryLog entry containing all information
Returns
VoidResult indicating success or error
Note
Implements common::interfaces::ILogger::log(const log_entry&)
Since
2.0.0

Definition at line 489 of file logger.cpp.

489 {
490 if (!pimpl_ || !meets_threshold(entry.level, pimpl_->min_level_.load())) {
491 return common::ok();
492 }
493
494 std::string msg_str(entry.message);
495 std::string file_str(entry.file);
496 int line = entry.line;
497 std::string func_str(entry.function);
498
499 // Create log entry for filtering and routing
500 log_entry internal_entry(entry.level, msg_str, file_str, line, func_str);
501
502 // Apply filter if set
503 {
504 std::shared_lock<std::shared_mutex> filter_lock(pimpl_->filter_mutex_);
505 if (pimpl_->filter_) {
506 if (!pimpl_->filter_->should_log(internal_entry)) {
507 return common::ok();
508 }
509 }
510 }
511
512 // Apply sampling if set
513 {
514 std::shared_lock<std::shared_mutex> sampler_lock(pimpl_->sampler_mutex_);
515 if (pimpl_->sampler_ && pimpl_->sampler_->is_enabled()) {
516 if (!pimpl_->sampler_->should_sample(internal_entry)) {
517 return common::ok();
518 }
519 }
520 }
521
522 // Record metrics if enabled
523 auto start_time = std::chrono::high_resolution_clock::now();
524
525 // Use async path if in async mode
526 if (pimpl_->async_mode_ && pimpl_->collector_) {
527 auto now = std::chrono::system_clock::now();
528 pimpl_->collector_->enqueue(entry.level, msg_str, file_str, line, func_str, now);
529
530 if (pimpl_->metrics_enabled_) {
531 auto end_time = std::chrono::high_resolution_clock::now();
532 auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time);
533 metrics::record_message_logged(duration.count());
534 }
535 return common::ok();
536 }
537
538 // Synchronous path: dispatch with routing support
539 pimpl_->dispatch_to_writers(entry.level, msg_str, file_str, line, func_str, internal_entry);
540
541 // Update metrics after logging
542 if (pimpl_->metrics_enabled_) {
543 auto end_time = std::chrono::high_resolution_clock::now();
544 auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time);
545 metrics::record_message_logged(duration.count());
546 }
547
548 return common::ok();
549}

References kcenon::common::ok(), pimpl_, and kcenon::logger::metrics::record_message_logged().

Here is the call graph for this function:

◆ log_structured()

structured_log_builder kcenon::logger::logger::log_structured ( log_level level)
nodiscard

Definition at line 717 of file logger.cpp.

717 {
718 // Get context fields from unified_log_context (thread-safe internally)
719 log_fields ctx_fields;
720 if (pimpl_ && !pimpl_->context_.empty()) {
721 ctx_fields = pimpl_->context_.to_fields();
722 }
723
724 // Capture by value since we need the fields to outlive this scope
725 return structured_log_builder(
726 level,
727 [this, level](log_entry&& entry) {
728 if (!pimpl_ || !meets_threshold(level, pimpl_->min_level_.load())) {
729 return;
730 }
731
732 // Apply filter if set
733 {
734 std::shared_lock<std::shared_mutex> filter_lock(pimpl_->filter_mutex_);
735 if (pimpl_->filter_) {
736 if (!pimpl_->filter_->should_log(entry)) {
737 return;
738 }
739 }
740 }
741
742 // Dispatch to writers
743 std::string file_str;
744 int line = 0;
745 std::string func_str;
746 if (entry.location) {
747 file_str = entry.location->file.to_string();
748 line = entry.location->line;
749 func_str = entry.location->function.to_string();
750 }
751
752 pimpl_->dispatch_to_writers(
753 entry.level,
754 entry.message.to_string(),
755 file_str,
756 line,
757 func_str,
758 entry
759 );
760 },
761 ctx_fields.empty() ? nullptr : &ctx_fields
762 );
763}
std::unordered_map< std::string, log_value > log_fields
Type alias for structured fields map.
Definition log_entry.h:75

References pimpl_.

◆ remove_writer()

bool kcenon::logger::logger::remove_writer ( const std::string & name)

Remove a writer by name.

Parameters
nameName of the writer to remove
Returns
true if writer was found and removed

Definition at line 330 of file logger.cpp.

330 {
331 if (!pimpl_ || name.empty()) {
332 return false;
333 }
334
335 std::lock_guard<std::shared_mutex> lock(pimpl_->writers_mutex_);
336
337 auto it = pimpl_->named_writers_.find(name);
338 if (it == pimpl_->named_writers_.end()) {
339 return false;
340 }
341
342 auto writer_to_remove = it->second;
343
344 // Remove from named_writers_ map
345 pimpl_->named_writers_.erase(it);
346
347 // Remove from writers_ vector
348 auto vec_it = std::find(pimpl_->writers_.begin(), pimpl_->writers_.end(), writer_to_remove);
349 if (vec_it != pimpl_->writers_.end()) {
350 pimpl_->writers_.erase(vec_it);
351 }
352
353 // Note: Cannot remove from collector's writers list as it doesn't support removal
354 // The writer will be skipped during iteration if it's no longer valid
355
356 return true;
357}

References pimpl_.

◆ reset_metrics()

common::VoidResult kcenon::logger::logger::reset_metrics ( )

Reset performance metrics.

Returns
common::VoidResult indicating success or error

◆ reset_sampling_stats()

void kcenon::logger::logger::reset_sampling_stats ( )

Reset sampling statistics.

Since
3.3.0

Definition at line 863 of file logger.cpp.

863 {
864 if (pimpl_) {
865 std::shared_lock<std::shared_mutex> lock(pimpl_->sampler_mutex_);
866 if (pimpl_->sampler_) {
867 pimpl_->sampler_->reset_stats();
868 }
869 }
870}

References pimpl_.

◆ set_filter()

void kcenon::logger::logger::set_filter ( std::unique_ptr< log_filter_interface > filter)

Definition at line 663 of file logger.cpp.

663 {
664 if (pimpl_) {
665 std::lock_guard<std::shared_mutex> lock(pimpl_->filter_mutex_);
666 pimpl_->filter_ = std::move(filter);
667 }
668}

References pimpl_.

◆ set_level()

common::VoidResult kcenon::logger::logger::set_level ( common::interfaces::log_level level)
override

Set the minimum log level (ILogger interface)

Parameters
levelMinimum level for messages to be logged
Returns
VoidResult indicating success or error
Note
Implements common::interfaces::ILogger::set_level
Since
2.0.0

Definition at line 555 of file logger.cpp.

555 {
556 if (!pimpl_) {
557 return common::make_error<std::monostate>(
559 "Logger not initialized",
560 "logger_system");
561 }
562
563 pimpl_->min_level_.store(level);
564 return common::ok();
565}

References kcenon::logger::invalid_configuration, kcenon::common::ok(), and pimpl_.

Referenced by kcenon::logger::adapters::logger_adapter::set_level(), and kcenon::logger::adapters::logger_adapter::set_level().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_router()

void kcenon::logger::logger::set_router ( std::unique_ptr< log_router > router)

Set a new log router.

Parameters
routerRouter to use

Replaces the current router with the provided one. Useful for setting up a pre-configured router.

Since
2.0.0

Definition at line 696 of file logger.cpp.

696 {
697 if (pimpl_ && router) {
698 std::lock_guard<std::shared_mutex> lock(pimpl_->router_mutex_);
699 pimpl_->router_ = std::move(router);
700 }
701}

References pimpl_.

◆ set_sampler()

void kcenon::logger::logger::set_sampler ( std::unique_ptr< sampling::log_sampler > sampler)

Definition at line 822 of file logger.cpp.

822 {
823 if (pimpl_) {
824 std::lock_guard<std::shared_mutex> lock(pimpl_->sampler_mutex_);
825 pimpl_->sampler_ = std::move(sampler);
826 }
827}

References pimpl_.

◆ start()

common::VoidResult kcenon::logger::logger::start ( )

Definition at line 222 of file logger.cpp.

222 {
223 if (pimpl_ && !pimpl_->running_) {
224 pimpl_->running_ = true;
225
226 // Start async collector if in async mode
227 if (pimpl_->async_mode_ && pimpl_->collector_) {
228 // Register all existing writers with the collector
229 {
230 std::shared_lock<std::shared_mutex> lock(pimpl_->writers_mutex_);
231 for (const auto& writer : pimpl_->writers_) {
232 if (writer) {
233 pimpl_->collector_->add_writer(writer);
234 }
235 }
236 }
237
238 // Start the background processing thread
239 pimpl_->collector_->start();
240 }
241 }
242 return common::ok();
243}

References kcenon::common::ok(), and pimpl_.

Here is the call graph for this function:

◆ stop()

common::VoidResult kcenon::logger::logger::stop ( )

Stop the logger.

Returns
common::VoidResult Success or error code

Stops the background processing thread and flushes all pending messages. This is a blocking operation that waits for all queued messages to be processed.

Note
After stopping, the logger can be restarted with start().
Warning
Stopping the logger may take time if there are many pending messages.
Since
1.0.0

Definition at line 245 of file logger.cpp.

245 {
246 if (pimpl_ && pimpl_->running_) {
247 // Stop async collector if in async mode
248 // The collector's stop() drains the queue and flushes writers automatically
249 if (pimpl_->async_mode_ && pimpl_->collector_) {
250 pimpl_->collector_->stop();
251 } else {
252 // Synchronous mode: manually flush writers
253 flush();
254 }
255
256 pimpl_->running_ = false;
257 }
258 return common::ok();
259}
common::VoidResult flush() override
Flush any buffered log messages (ILogger interface)
Definition logger.cpp:574

References flush(), kcenon::common::ok(), and pimpl_.

Referenced by ~logger().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ pimpl_


The documentation for this class was generated from the following files: