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

Public Member Functions

 impl (std::size_t buffer_size, std::size_t batch_size)
 
 ~impl ()
 
bool enqueue (log_level level, const std::string &message, const std::string &file, int line, const std::string &function, const std::chrono::system_clock::time_point &timestamp)
 
void add_writer (std::shared_ptr< log_writer_interface > writer)
 
void clear_writers ()
 
void start ()
 
void stop ()
 
void flush ()
 
std::pair< std::size_t, std::size_t > get_queue_metrics () const
 

Private Member Functions

void drain_queue ()
 
void flush_writers ()
 
void write_to_all (const log_entry &entry)
 

Private Attributes

std::shared_ptr< log_collector_shared_statestate_
 
std::unique_ptr< log_collector_jthread_workerworker_
 
std::atomic< std::uint64_t > dropped_messages_ {0}
 

Detailed Description

Definition at line 250 of file log_collector.cpp.

Constructor & Destructor Documentation

◆ impl()

kcenon::logger::log_collector::impl::impl ( std::size_t buffer_size,
std::size_t batch_size )
inlineexplicit

Definition at line 252 of file log_collector.cpp.

253 : state_(std::make_shared<log_collector_shared_state>(buffer_size, batch_size))
254 , worker_(std::make_unique<log_collector_jthread_worker>(state_)) {
255 }
std::shared_ptr< log_collector_shared_state > state_
std::unique_ptr< log_collector_jthread_worker > worker_

◆ ~impl()

kcenon::logger::log_collector::impl::~impl ( )
inline

Definition at line 257 of file log_collector.cpp.

257 {
258 stop();
259 }

References stop().

Here is the call graph for this function:

Member Function Documentation

◆ add_writer()

void kcenon::logger::log_collector::impl::add_writer ( std::shared_ptr< log_writer_interface > writer)
inline

Definition at line 299 of file log_collector.cpp.

299 {
300 if (!writer) {
301 return;
302 }
303 std::lock_guard<std::mutex> lock(state_->writers_mutex);
304 state_->writers.push_back(writer);
305 }

References state_.

◆ clear_writers()

void kcenon::logger::log_collector::impl::clear_writers ( )
inline

Definition at line 307 of file log_collector.cpp.

307 {
308 std::lock_guard<std::mutex> lock(state_->writers_mutex);
309 state_->writers.clear();
310 }

References state_.

◆ drain_queue()

void kcenon::logger::log_collector::impl::drain_queue ( )
inlineprivate

Definition at line 354 of file log_collector.cpp.

354 {
355 std::queue<log_entry> remaining;
356 {
357 std::lock_guard<std::mutex> lock(state_->queue_mutex);
358 std::swap(remaining, state_->queue);
359 }
360
361 // Process remaining entries
362 while (!remaining.empty()) {
363 auto entry = std::move(remaining.front());
364 remaining.pop();
365 write_to_all(entry);
366 }
367 }
void write_to_all(const log_entry &entry)

References state_, and write_to_all().

Referenced by stop().

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

◆ enqueue()

bool kcenon::logger::log_collector::impl::enqueue ( log_level level,
const std::string & message,
const std::string & file,
int line,
const std::string & function,
const std::chrono::system_clock::time_point & timestamp )
inline

Definition at line 261 of file log_collector.cpp.

266 {
267 {
268 std::lock_guard<std::mutex> lock(state_->queue_mutex);
269
270 // Check if queue is full
271 if (state_->queue.size() >= state_->buffer_size) {
272 // Track dropped message
273 std::uint64_t dropped = dropped_messages_.fetch_add(1, std::memory_order_relaxed) + 1;
274
275 // Log warning periodically (every 100 dropped messages) to avoid spam
276 if (dropped % 100 == 1) {
277 std::fprintf(stderr, "[WARNING] Log queue full: %llu messages dropped total\n",
278 static_cast<unsigned long long>(dropped));
279 }
280
281 return false;
282 }
283
284 // Create log_entry with optional source location
285 log_entry entry(level, message, timestamp);
286 if (!file.empty() || line != 0 || !function.empty()) {
287 entry.location = source_location{file, line, function};
288 }
289 state_->queue.push(std::move(entry));
290 }
291
292 // Notify worker thread
293 if (worker_) {
294 worker_->notify_work();
295 }
296 return true;
297 }
std::atomic< std::uint64_t > dropped_messages_

References dropped_messages_, kcenon::logger::log_entry::location, state_, and worker_.

◆ flush()

void kcenon::logger::log_collector::impl::flush ( )
inline

Definition at line 331 of file log_collector.cpp.

331 {
332 // Wait for queue to be empty
333 while (true) {
334 {
335 std::lock_guard<std::mutex> lock(state_->queue_mutex);
336 if (state_->queue.empty()) {
337 break;
338 }
339 }
340 // Brief yield to allow worker to process
341 std::this_thread::sleep_for(std::chrono::microseconds(100));
342 }
343
344 // Flush all writers
346 }

References flush_writers(), and state_.

Here is the call graph for this function:

◆ flush_writers()

void kcenon::logger::log_collector::impl::flush_writers ( )
inlineprivate

Definition at line 369 of file log_collector.cpp.

369 {
370 std::vector<std::shared_ptr<log_writer_interface>> writers_snapshot;
371 {
372 std::lock_guard<std::mutex> lock(state_->writers_mutex);
373 writers_snapshot.reserve(state_->writers.size());
374 for (auto& weak_writer : state_->writers) {
375 if (auto writer = weak_writer.lock()) {
376 writers_snapshot.push_back(writer);
377 }
378 }
379 }
380
381 for (auto& writer : writers_snapshot) {
382 try {
383 writer->flush();
384 } catch (...) {
385 // Swallow exceptions during flush
386 }
387 }
388 }

References state_.

Referenced by flush(), and stop().

Here is the caller graph for this function:

◆ get_queue_metrics()

std::pair< std::size_t, std::size_t > kcenon::logger::log_collector::impl::get_queue_metrics ( ) const
inlinenodiscard

Definition at line 348 of file log_collector.cpp.

348 {
349 std::lock_guard<std::mutex> lock(state_->queue_mutex);
350 return {state_->queue.size(), state_->buffer_size};
351 }

References state_.

◆ start()

void kcenon::logger::log_collector::impl::start ( )
inline

Definition at line 312 of file log_collector.cpp.

312 {
313 if (worker_) {
314 worker_->start();
315 }
316 }

References worker_.

◆ stop()

void kcenon::logger::log_collector::impl::stop ( )
inline

Definition at line 318 of file log_collector.cpp.

318 {
319 // Stop the worker thread first
320 if (worker_) {
321 worker_->stop();
322 }
323
324 // Drain remaining entries
325 drain_queue();
326
327 // Flush all writers
329 }

References drain_queue(), flush_writers(), and worker_.

Referenced by ~impl().

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

◆ write_to_all()

void kcenon::logger::log_collector::impl::write_to_all ( const log_entry & entry)
inlineprivate

Definition at line 390 of file log_collector.cpp.

390 {
391 // Snapshot writers under lock
392 std::vector<std::shared_ptr<log_writer_interface>> writers_snapshot;
393 {
394 std::lock_guard<std::mutex> lock(state_->writers_mutex);
395 writers_snapshot.reserve(state_->writers.size());
396 for (auto& weak_writer : state_->writers) {
397 if (auto writer = weak_writer.lock()) {
398 writers_snapshot.push_back(writer);
399 }
400 }
401 }
402
403 // Write to all writers without holding mutex
404 for (auto& writer : writers_snapshot) {
405 try {
406 writer->write(entry);
407 } catch (...) {
408 // Swallow exceptions to prevent issues
409 }
410 }
411 }

References state_.

Referenced by drain_queue().

Here is the caller graph for this function:

Member Data Documentation

◆ dropped_messages_

std::atomic<std::uint64_t> kcenon::logger::log_collector::impl::dropped_messages_ {0}
private

Definition at line 416 of file log_collector.cpp.

416{0};

Referenced by enqueue().

◆ state_

std::shared_ptr<log_collector_shared_state> kcenon::logger::log_collector::impl::state_
private

◆ worker_

std::unique_ptr<log_collector_jthread_worker> kcenon::logger::log_collector::impl::worker_
private

Definition at line 415 of file log_collector.cpp.

Referenced by enqueue(), start(), and stop().


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