LogIt++
Header-only, macro-first C++ logging library
Loading...
Searching...
No Matches
Logger.hpp
Go to the documentation of this file.
1#pragma once
2#ifndef LOGIT_CPP_HEADER_LOGIT_CPP_LOGIT_LOGGER_HPP_INCLUDED
3#define LOGIT_CPP_HEADER_LOGIT_CPP_LOGIT_LOGGER_HPP_INCLUDED
4
7
8#include "config.hpp"
9#include "loggers/ILogger.hpp"
10#include "formatter.hpp"
12#include <memory>
13#include <mutex>
14#include <sstream>
15#include <atomic>
16#include <cstddef>
17#include <vector>
18
19#if __cplusplus >= 201703L
20#include <shared_mutex>
21#define LOGIT_HAS_SHARED_MUTEX 1
22#else
23#define LOGIT_HAS_SHARED_MUTEX 0
24#endif
25
26namespace logit {
27
28#if LOGIT_HAS_SHARED_MUTEX
29 using LoggerMutex = std::shared_mutex;
30 using LoggerReadLock = std::shared_lock<LoggerMutex>;
31 using LoggerWriteLock = std::unique_lock<LoggerMutex>;
32#else
33 using LoggerMutex = std::mutex;
34 using LoggerReadLock = std::unique_lock<LoggerMutex>;
35 using LoggerWriteLock = std::unique_lock<LoggerMutex>;
36#endif
37
44 class Logger {
45 private:
46 struct LoggerStrategy;
47 using StrategyList = std::vector<std::shared_ptr<LoggerStrategy>>;
48
49 public:
50
53 static Logger& get_instance() {
54 static Logger* instance = new Logger();
55 return *instance;
56 }
57
65 std::unique_ptr<ILogger> logger,
66 std::unique_ptr<ILogFormatter> formatter,
67 bool single_mode = false) {
68 if (m_shutdown.load(std::memory_order_acquire)) return;
69 auto strategy = std::make_shared<LoggerStrategy>();
70 strategy->logger = std::move(logger);
71 strategy->formatter = std::move(formatter);
72 strategy->single_mode = single_mode;
73 strategy->enabled = true;
74
76 if (m_shutdown.load(std::memory_order_acquire)) return;
77 m_loggers.push_back(std::move(strategy));
79 }
80
84 void set_logger_enabled(int logger_index, bool enabled) {
85 if (m_shutdown) return;
87 if (logger_index >= 0 && logger_index < static_cast<int>(m_loggers.size()) && m_loggers[logger_index]) {
88 m_loggers[logger_index]->enabled.store(enabled, std::memory_order_relaxed);
89 }
90 }
91
95 bool is_logger_enabled(int logger_index) const {
97 if (logger_index >= 0 && logger_index < static_cast<int>(m_loggers.size()) && m_loggers[logger_index]) {
98 return m_loggers[logger_index]->enabled.load(std::memory_order_relaxed);
99 }
100 return false;
101 }
102
106 void set_logger_single_mode(int logger_index, bool single_mode) {
107 if (m_shutdown) return;
109 if (logger_index >= 0 && logger_index < static_cast<int>(m_loggers.size()) && m_loggers[logger_index]) {
110 m_loggers[logger_index]->single_mode.store(single_mode, std::memory_order_relaxed);
111 }
112 }
113
117 void set_timestamp_offset(int logger_index, int64_t offset_ms) {
118 if (m_shutdown) return;
120 if (logger_index >= 0 && logger_index < static_cast<int>(m_loggers.size()) && m_loggers[logger_index]) {
121 std::lock_guard<std::mutex> exec_lock(m_loggers[logger_index]->exec_mx);
122 m_loggers[logger_index]->formatter->set_timestamp_offset(offset_ms);
123 }
124 }
125
129 if (m_shutdown) return;
131 for (auto& strategy : m_loggers) {
132 if (!strategy) continue;
133 std::lock_guard<std::mutex> exec_lock(strategy->exec_mx);
134 strategy->logger->set_log_level(level);
135 }
136 }
137
141 void set_log_level(int logger_index, LogLevel level) {
142 if (m_shutdown) return;
144 if (logger_index >= 0 && logger_index < static_cast<int>(m_loggers.size()) && m_loggers[logger_index]) {
145 std::lock_guard<std::mutex> exec_lock(m_loggers[logger_index]->exec_mx);
146 m_loggers[logger_index]->logger->set_log_level(level);
147 }
148 }
149
153 bool is_logger_single_mode(int logger_index) const {
154 if (m_shutdown) return false;
156 if (logger_index >= 0 && logger_index < static_cast<int>(m_loggers.size()) && m_loggers[logger_index]) {
157 return m_loggers[logger_index]->single_mode.load(std::memory_order_relaxed);
158 }
159 return false;
160 }
161
167 void log(const LogRecord& record) {
168 if (m_shutdown.load(std::memory_order_acquire)) return;
169
170 const bool targeted = record.logger_index >= 0;
171#ifdef LOGIT_BENCH_LEGACY_REGISTRY
172 StrategyList legacy_snapshot;
173 {
174 LoggerReadLock legacy_lock(m_loggers_mx);
175 if (targeted) {
176 if (record.logger_index < static_cast<int>(m_loggers.size())) {
177 legacy_snapshot.push_back(m_loggers[record.logger_index]);
178 }
179 } else {
180 legacy_snapshot = m_loggers;
181 }
182 }
183 const StrategyList* strategies = &legacy_snapshot;
184 // The targeted legacy snapshot contains only the selected strategy,
185 // so dispatch must address its sole element rather than the original
186 // registry index. The production snapshot retains the full registry
187 // and continues to use record.logger_index below.
188 const int strategy_index = targeted ? 0 : record.logger_index;
189#else
190 const auto snapshot = std::atomic_load_explicit(
191 &m_loggers_snapshot, std::memory_order_acquire);
192 const StrategyList* strategies = snapshot ? snapshot.get() : nullptr;
193 const int strategy_index = record.logger_index;
194#endif
195 if (!strategies) return;
196
197 if (targeted) {
198 if (strategy_index < 0 ||
199 strategy_index >= static_cast<int>(strategies->size())) return;
200 const auto& strategy = (*strategies)[strategy_index];
201 if (!strategy) return;
202
203 std::lock_guard<std::mutex> exec_lock(strategy->exec_mx);
204 if (m_shutdown.load(std::memory_order_acquire)) return;
205 if (!strategy->enabled.load(std::memory_order_relaxed)) return;
206 if (!record.raw_mode &&
207 static_cast<int>(record.log_level) < static_cast<int>(strategy->logger->get_log_level())) return;
208 dispatch_to_strategy(*strategy, record);
209 return;
210 }
211
212 for (const auto& strategy : *strategies) {
213 if (!strategy) continue;
214
215 std::lock_guard<std::mutex> exec_lock(strategy->exec_mx);
216 if (m_shutdown.load(std::memory_order_acquire)) return;
217 if (strategy->single_mode.load(std::memory_order_relaxed)) continue;
218 if (!strategy->enabled.load(std::memory_order_relaxed)) continue;
219 if (!record.raw_mode &&
220 static_cast<int>(record.log_level) < static_cast<int>(strategy->logger->get_log_level())) continue;
221
222 dispatch_to_strategy(*strategy, record);
223 }
224 }
225
230 std::string get_string_param(int logger_index, const LoggerParam& param) const {
231 if (m_shutdown) return std::string();
233 if (logger_index >= 0 && logger_index < static_cast<int>(m_loggers.size()) && m_loggers[logger_index]) {
234 const auto& strategy = m_loggers[logger_index];
235 return strategy->logger->get_string_param(param);
236 }
237 return std::string();
238 }
239
244 int64_t get_int_param(int logger_index, const LoggerParam& param) const {
245 if (m_shutdown) return 0;
247 if (logger_index >= 0 && logger_index < static_cast<int>(m_loggers.size()) && m_loggers[logger_index]) {
248 const auto& strategy = m_loggers[logger_index];
249 return strategy->logger->get_int_param(param);
250 }
251 return 0;
252 }
253
258 double get_float_param(int logger_index, const LoggerParam& param) const {
259 if (m_shutdown) return 0.0;
261 if (logger_index >= 0 && logger_index < static_cast<int>(m_loggers.size()) && m_loggers[logger_index]) {
262 const auto& strategy = m_loggers[logger_index];
263 return strategy->logger->get_float_param(param);
264 }
265 return 0.0;
266 }
267
271 std::vector<std::string> get_buffered_strings(int logger_index) const {
272 if (m_shutdown) return std::vector<std::string>();
273
274 auto strategy = get_strategy_snapshot(logger_index);
275 if (!strategy) {
276 return std::vector<std::string>();
277 }
278
279 return strategy->logger->get_buffered_strings();
280 }
281
285 std::vector<BufferedLogEntry> get_buffered_entries(int logger_index) const {
286 if (m_shutdown) return std::vector<BufferedLogEntry>();
287
288 auto strategy = get_strategy_snapshot(logger_index);
289 if (!strategy) {
290 return std::vector<BufferedLogEntry>();
291 }
292
293 return strategy->logger->get_buffered_entries();
294 }
295
299 std::vector<LogFileInfo> list_log_files(int logger_index) const {
300 if (m_shutdown) return std::vector<LogFileInfo>();
301
302 auto strategy = get_strategy_snapshot(logger_index);
303 if (!strategy) {
304 return std::vector<LogFileInfo>();
305 }
306
307 return strategy->logger->list_log_files();
308 }
309
314 LogFileReadResult read_log_file(int logger_index, const std::string& path) const {
315 if (m_shutdown) {
316 LogFileReadResult result;
317 result.file.path = path;
318 result.ok = false;
319 return result;
320 }
321
322 auto strategy = get_strategy_snapshot(logger_index);
323 if (!strategy) {
324 LogFileReadResult result;
325 result.file.path = path;
326 result.ok = false;
327 return result;
328 }
329
330 return strategy->logger->read_log_file(path);
331 }
332
337 std::vector<LogFileReadResult> read_log_files(int logger_index, const std::vector<std::string>& paths) const {
338 if (m_shutdown) {
339 std::vector<LogFileReadResult> results;
340 results.reserve(paths.size());
341 for (size_t i = 0; i < paths.size(); ++i) {
342 LogFileReadResult result;
343 result.file.path = paths[i];
344 result.ok = false;
345 results.push_back(result);
346 }
347 return results;
348 }
349
350 auto strategy = get_strategy_snapshot(logger_index);
351 if (!strategy) {
352 std::vector<LogFileReadResult> results;
353 results.reserve(paths.size());
354 for (size_t i = 0; i < paths.size(); ++i) {
355 LogFileReadResult result;
356 result.file.path = paths[i];
357 result.ok = false;
358 results.push_back(result);
359 }
360 return results;
361 }
362
363 return strategy->logger->read_log_files(paths);
364 }
365
369 LogLevel get_log_level(int logger_index) const {
371
372 auto strategy = get_strategy_snapshot(logger_index);
373 if (!strategy) {
375 }
376
377 return strategy->logger->get_log_level();
378 }
379
385 template <typename... Ts>
386 auto log_and_return(const LogRecord& record, Ts&&... args) -> decltype(std::forward_as_tuple(std::forward<Ts>(args)...)) {
387 this->print(record, args...);
388 return std::forward_as_tuple(std::forward<Ts>(args)...);
389 }
390
398 template <typename T>
399 auto log_and_return(const LogRecord& record, T&& args) -> decltype(args) {
400 this->print(record, args);
401 return std::forward<decltype(args)>(args);
402 }
403
407 auto log_and_return(const LogRecord& record) -> std::tuple<> {
408 this->print(record);
409 return {};
410 }
411
415 void wait() {
416 const auto snapshot = get_all_strategy_snapshots();
417 for (const auto& strategy : snapshot) {
418 if (!strategy) continue;
419 strategy->logger->wait();
420 }
421 }
422
427 LogClearResult clear_logger(int logger_index, const LogClearOptions& options = LogClearOptions()) {
428 LogClearResult result;
429 if (m_shutdown.load(std::memory_order_acquire)) {
430 result.ok = false;
432 result.message = "logger system is shut down";
433 return result;
434 }
435
436 auto strategy = get_strategy_snapshot(logger_index);
437 if (!strategy) {
438 result.ok = false;
440 result.message = "logger index not found";
441 return result;
442 }
443
444 std::lock_guard<std::mutex> exec_lock(strategy->exec_mx);
445 if (m_shutdown.load(std::memory_order_acquire)) {
446 result.ok = false;
448 result.message = "logger system is shut down";
449 return result;
450 }
451 return strategy->logger->clear_logs(options);
452 }
453
458 LogClearResult result;
459 if (m_shutdown.load(std::memory_order_acquire)) {
460 result.ok = false;
462 result.message = "logger system is shut down";
463 return result;
464 }
465
466 const auto snapshot = get_all_strategy_snapshots();
467 std::size_t supported = 0;
468 std::size_t failed = 0;
469 std::size_t unsupported = 0;
470 for (const auto& strategy : snapshot) {
471 if (!strategy) continue;
472 std::lock_guard<std::mutex> exec_lock(strategy->exec_mx);
473 if (m_shutdown.load(std::memory_order_acquire)) {
474 result.ok = false;
476 result.message = "logger system is shut down";
477 return result;
478 }
479 const LogClearResult one = strategy->logger->clear_logs(options);
480 if (one.status == LogClearStatus::Cleared && one.ok) {
481 ++supported;
482 result.cleared_records += one.cleared_records;
483 } else if (one.status == LogClearStatus::Unsupported) {
484 ++unsupported;
485 } else {
486 ++failed;
487 if (result.message.empty()) {
488 result.message = one.message;
489 }
490 }
491 }
492
493 result.ok = supported > 0 && failed == 0;
494 if (result.ok) {
496 result.message = unsupported > 0 ? "cleared supported loggers; skipped unsupported loggers" : "cleared";
497 } else {
498 result.status = unsupported > 0 && failed == 0 ? LogClearStatus::Unsupported : LogClearStatus::Failed;
499 if (result.message.empty()) {
500 result.message = unsupported > 0 ? "no logger supports clearing" : "no loggers to clear";
501 }
502 }
503 return result;
504 }
505
507 std::size_t logger_count() const {
509 return m_loggers.size();
510 }
511
513 template <typename LoggerT>
514 LoggerT* get_logger_as(int logger_index) {
515 auto strategy = get_strategy_snapshot(logger_index);
516 return (strategy && strategy->logger)
517 ? dynamic_cast<LoggerT*>(strategy->logger.get())
518 : nullptr;
519 }
520
522 template <typename LoggerT>
523 const LoggerT* get_logger_as(int logger_index) const {
524 auto strategy = get_strategy_snapshot(logger_index);
525 return (strategy && strategy->logger)
526 ? dynamic_cast<const LoggerT*>(strategy->logger.get())
527 : nullptr;
528 }
529
534 void shutdown() {
535 if (m_shutdown.exchange(true, std::memory_order_acq_rel)) return;
536
537 const auto snapshot = get_all_strategy_snapshots();
538 for (const auto& strategy : snapshot) {
539 if (!strategy) continue;
540 std::lock_guard<std::mutex> exec_lock(strategy->exec_mx);
541 strategy->logger->shutdown();
542 }
544 }
545
546 private:
547
551 std::unique_ptr<ILogger> logger;
552 std::unique_ptr<ILogFormatter> formatter;
553 std::atomic<bool> single_mode{false};
554 std::atomic<bool> enabled{true};
555 mutable std::mutex exec_mx;
556 };
557
558 void dispatch_to_strategy(LoggerStrategy& strategy, const LogRecord& record) {
559 if (record.raw_mode) {
560 strategy.logger->log(record, record.format);
561 return;
562 }
563 if (strategy.formatter && strategy.formatter->is_passthrough()) {
564 strategy.logger->log(record, record.format);
565 return;
566 }
567 const std::string msg = strategy.formatter ? strategy.formatter->format(record) : std::string();
568 strategy.logger->log(record, msg);
569 }
570
571 std::shared_ptr<LoggerStrategy> get_strategy_snapshot(int logger_index) const {
572 const auto snapshot = std::atomic_load_explicit(
573 &m_loggers_snapshot, std::memory_order_acquire);
574 if (logger_index >= 0 &&
575 snapshot && logger_index < static_cast<int>(snapshot->size()) &&
576 (*snapshot)[logger_index]) {
577 return (*snapshot)[logger_index];
578 }
579 return std::shared_ptr<LoggerStrategy>();
580 }
581
583 const std::shared_ptr<const StrategyList> snapshot(
585 std::atomic_store_explicit(
586 &m_loggers_snapshot, snapshot, std::memory_order_release);
587 }
588
589 std::vector<std::shared_ptr<LoggerStrategy>> get_all_strategy_snapshots() const {
591 return m_loggers;
592 }
593
594 std::vector<std::shared_ptr<LoggerStrategy>> m_loggers;
595 std::shared_ptr<const StrategyList> m_loggers_snapshot;
597 std::atomic<bool> m_shutdown = ATOMIC_VAR_INIT(false);
598
599 void print(const LogRecord& record) {
600 log(record);
601 }
602
603#ifdef _MSC_VER
604# pragma warning(push)
605# pragma warning(disable: 4127) // conditional expression is constant
606#endif
607
612 template <typename... Ts>
613 void print(const LogRecord& record, Ts const&... args) {
614 if (sizeof...(Ts) == 0) {
615 log(record);
616 return;
617 }
618 // args_array is mutable cache inside LogRecord
619 auto var_names = split_arguments(record.arg_names);
620 record.args_array = args_to_array(var_names.begin(), args...);
621 log(record);
622 }
623
624#ifdef _MSC_VER
625# pragma warning(pop)
626#endif
627
629 std::atomic_store_explicit(
631 std::shared_ptr<const StrategyList>(new StrategyList()),
632 std::memory_order_release);
633 std::atexit(Logger::on_exit_handler);
634 }
635
637 shutdown();
638 }
639
640 // Deleting copy and move constructors and assignment operators to enforce singleton.
641 Logger(const Logger&) = delete;
642 Logger& operator=(const Logger&) = delete;
643 Logger(Logger&&) = delete;
644 Logger& operator=(Logger&&) = delete;
645
648 static void on_exit_handler() {
650 }
651 };
652
653}; // namespace logit
654
655#endif // LOGIT_CPP_HEADER_LOGIT_CPP_LOGIT_LOGGER_HPP_INCLUDED
Defines the interface for loggers used in the logging system.
Task executor used by asynchronous loggers.
Singleton class managing multiple loggers and formatters.
Definition Logger.hpp:44
LoggerT * get_logger_as(int logger_index)
Retrieves a typed backend pointer from a logger by index.
Definition Logger.hpp:514
auto log_and_return(const LogRecord &record) -> std::tuple<>
Logs message without arguments and returns empty tuple.
Definition Logger.hpp:407
auto log_and_return(const LogRecord &record, T &&args) -> decltype(args)
Logs message and returns argument.
Definition Logger.hpp:399
LogClearResult clear_logger(int logger_index, const LogClearOptions &options=LogClearOptions())
Clears logger-owned records for a specific logger.
Definition Logger.hpp:427
void set_logger_enabled(int logger_index, bool enabled)
Enables or disables a logger by index.
Definition Logger.hpp:84
std::vector< std::shared_ptr< LoggerStrategy > > get_all_strategy_snapshots() const
Definition Logger.hpp:589
void publish_strategy_snapshot_locked()
Definition Logger.hpp:582
void wait()
Waits for all asynchronous loggers to finish processing.
Definition Logger.hpp:415
void log(const LogRecord &record)
Logs a LogRecord using added loggers and formatters.
Definition Logger.hpp:167
void set_logger_single_mode(int logger_index, bool single_mode)
Sets single-mode flag for a logger.
Definition Logger.hpp:106
void set_timestamp_offset(int logger_index, int64_t offset_ms)
Sets timestamp offset for a specific logger.
Definition Logger.hpp:117
LoggerMutex m_loggers_mx
Protects access to logger strategies.
Definition Logger.hpp:596
std::vector< std::shared_ptr< LoggerStrategy > > m_loggers
Container for logger-formatter pairs.
Definition Logger.hpp:594
void add_logger(std::unique_ptr< ILogger > logger, std::unique_ptr< ILogFormatter > formatter, bool single_mode=false)
Adds a logger and its corresponding formatter.
Definition Logger.hpp:64
std::vector< LogFileReadResult > read_log_files(int logger_index, const std::vector< std::string > &paths) const
Reads several persisted log files exposed by a logger backend.
Definition Logger.hpp:337
Logger & operator=(const Logger &)=delete
Logger(const Logger &)=delete
std::vector< LogFileInfo > list_log_files(int logger_index) const
Lists persisted log files exposed by a logger backend.
Definition Logger.hpp:299
void shutdown()
Shuts down logger system.
Definition Logger.hpp:534
void set_log_level(int logger_index, LogLevel level)
Sets minimal log level for a specific logger.
Definition Logger.hpp:141
LogClearResult clear_all_loggers(const LogClearOptions &options=LogClearOptions())
Clears logger-owned records for all registered loggers.
Definition Logger.hpp:457
void set_log_level(LogLevel level)
Sets minimal log level for all loggers.
Definition Logger.hpp:128
void print(const LogRecord &record)
Definition Logger.hpp:599
bool is_logger_single_mode(int logger_index) const
Checks whether a logger is in single mode.
Definition Logger.hpp:153
LogFileReadResult read_log_file(int logger_index, const std::string &path) const
Reads one persisted log file exposed by a logger backend.
Definition Logger.hpp:314
std::atomic< bool > m_shutdown
Flag indicating if shutdown was requested.
Definition Logger.hpp:597
double get_float_param(int logger_index, const LoggerParam &param) const
Retrieves a floating-point parameter from a logger.
Definition Logger.hpp:258
std::string get_string_param(int logger_index, const LoggerParam &param) const
Retrieves a string parameter from a logger.
Definition Logger.hpp:230
auto log_and_return(const LogRecord &record, Ts &&... args) -> decltype(std::forward_as_tuple(std::forward< Ts >(args)...))
Logs message and returns tuple of arguments.
Definition Logger.hpp:386
void dispatch_to_strategy(LoggerStrategy &strategy, const LogRecord &record)
Definition Logger.hpp:558
int64_t get_int_param(int logger_index, const LoggerParam &param) const
Retrieves an integer parameter from a logger.
Definition Logger.hpp:244
static void on_exit_handler()
Atexit shutdown handler for Logger and TaskExecutor.
Definition Logger.hpp:648
std::shared_ptr< const StrategyList > m_loggers_snapshot
Immutable read-mostly strategy list.
Definition Logger.hpp:595
bool is_logger_enabled(int logger_index) const
Checks if a logger is enabled.
Definition Logger.hpp:95
LogLevel get_log_level(int logger_index) const
Retrieves the current minimal log level for a logger.
Definition Logger.hpp:369
static Logger & get_instance()
Retrieves singleton instance of Logger.
Definition Logger.hpp:53
Logger & operator=(Logger &&)=delete
std::size_t logger_count() const
Returns the number of registered logger strategies.
Definition Logger.hpp:507
Logger(Logger &&)=delete
std::vector< BufferedLogEntry > get_buffered_entries(int logger_index) const
Retrieves buffered structured entries from a logger.
Definition Logger.hpp:285
std::vector< std::shared_ptr< LoggerStrategy > > StrategyList
Definition Logger.hpp:47
std::vector< std::string > get_buffered_strings(int logger_index) const
Retrieves buffered formatted messages from a logger.
Definition Logger.hpp:271
const LoggerT * get_logger_as(int logger_index) const
Retrieves a typed backend pointer from a logger by index.
Definition Logger.hpp:523
std::shared_ptr< LoggerStrategy > get_strategy_snapshot(int logger_index) const
Definition Logger.hpp:571
void print(const LogRecord &record, Ts const &... args)
Logs a record with given arguments.
Definition Logger.hpp:613
void shutdown()
Stop the worker thread and drain outstanding tasks.
static TaskExecutor & get_instance()
Returns the global executor instance.
Configuration macros for the LogIt logging system.
Aggregates the formatter subsystem for convenient inclusion.
The primary namespace for the LogIt++ library.
std::unique_lock< LoggerMutex > LoggerReadLock
Definition Logger.hpp:34
std::vector< VariableValue > args_to_array(std::vector< std::string >::const_iterator)
Base case of recursion for argument conversion — when there are no more arguments.
std::vector< std::string > split_arguments(const std::string &all_names)
Splits a string of argument names into individual names, ignoring nested templates,...
std::mutex LoggerMutex
Definition Logger.hpp:33
LogLevel
Logging levels.
Definition enums.hpp:15
@ LOG_LVL_TRACE
Trace level logging.
LoggerParam
Enumeration for different logger parameters that can be retrieved.
Definition enums.hpp:47
std::unique_lock< LoggerMutex > LoggerWriteLock
Definition Logger.hpp:35
Selects which data categories a logger cleanup should remove.
Definition ILogger.hpp:19
Result returned by logger cleanup operations.
Definition ILogger.hpp:35
std::string message
Optional diagnostic or unsupported reason.
Definition ILogger.hpp:39
std::size_t cleared_records
Number of primary records/files cleared when available.
Definition ILogger.hpp:38
LogClearStatus status
Detailed cleanup status.
Definition ILogger.hpp:37
bool ok
True when the backend completed cleanup.
Definition ILogger.hpp:36
std::string path
Full path to the file.
Result of reading a persisted log file from a file-based backend.
LogFileInfo file
Metadata for the requested file.
bool ok
Whether the read succeeded.
Stores log metadata and content.
Definition LogRecord.hpp:17
const int logger_index
Logger index (-1 to log to all).
Definition LogRecord.hpp:28
const LogLevel log_level
Log level (severity).
Definition LogRecord.hpp:18
const bool raw_mode
Flag indicating if formatter and level filters should be bypassed.
Definition LogRecord.hpp:31
const std::string format
Format string for the message.
Definition LogRecord.hpp:23
std::vector< VariableValue > args_array
Argument values for the log.
Definition LogRecord.hpp:26
const std::string arg_names
Argument names for the log.
Definition LogRecord.hpp:24
Structure to hold a logger-formatter pair.
Definition Logger.hpp:550
std::mutex exec_mx
Protects formatter+logger invocation.
Definition Logger.hpp:555
std::atomic< bool > single_mode
Flag indicating if the logger is in single mode.
Definition Logger.hpp:553
std::atomic< bool > enabled
Flag indicating if the logger is enabled.
Definition Logger.hpp:554
std::unique_ptr< ILogger > logger
The logger instance.
Definition Logger.hpp:551
std::unique_ptr< ILogFormatter > formatter
The formatter instance.
Definition Logger.hpp:552