LogIt++
Loading...
Searching...
No Matches
Logger.hpp
Go to the documentation of this file.
1#pragma once
2#ifndef _LOGIT_LOGGER_HPP_INCLUDED
3#define _LOGIT_LOGGER_HPP_INCLUDED
6
7#include "Logger/ILogger.hpp"
9#include <memory>
10#include <mutex>
11#include <sstream>
12#include <atomic>
13
14namespace logit {
15
22 class Logger {
23 public:
24
27 static Logger& get_instance() {
28 static Logger* instance = new Logger();
29 return *instance;
30 }
31
39 std::unique_ptr<ILogger> logger,
40 std::unique_ptr<ILogFormatter> formatter,
41 bool single_mode = false) {
42 if (m_shutdown) return;
43 std::lock_guard<std::mutex> lock(m_mutex);
44 m_loggers.push_back(
45 LoggerStrategy{std::move(logger),
46 std::move(formatter),
47 single_mode,
48 true // Loggers are enabled by default
49 });
50 }
51
55 void set_logger_enabled(int logger_index, bool enabled) {
56 if (m_shutdown) return;
57 std::lock_guard<std::mutex> lock(m_mutex);
58 if (logger_index >= 0 && logger_index < static_cast<int>(m_loggers.size())) {
59 m_loggers[logger_index].enabled = enabled;
60 }
61 }
62
66 bool is_logger_enabled(int logger_index) const {
67 std::lock_guard<std::mutex> lock(m_mutex);
68 if (logger_index >= 0 && logger_index < static_cast<int>(m_loggers.size())) {
69 return m_loggers[logger_index].enabled;
70 }
71 return false;
72 }
73
77 void set_logger_single_mode(int logger_index, bool single_mode) {
78 if (m_shutdown) return;
79 std::lock_guard<std::mutex> lock(m_mutex);
80 if (logger_index >= 0 && logger_index < static_cast<int>(m_loggers.size())) {
81 m_loggers[logger_index].single_mode = single_mode;
82 }
83 }
84
88 void set_timestamp_offset(int logger_index, int64_t offset_ms) {
89 if (m_shutdown) return;
90 std::lock_guard<std::mutex> lock(m_mutex);
91 if (logger_index >= 0 && logger_index < static_cast<int>(m_loggers.size())) {
92 m_loggers[logger_index].formatter->set_timestamp_offset(offset_ms);
93 }
94 }
95
99 bool is_logger_single_mode(int logger_index) const {
100 if (m_shutdown) return false;
101 std::lock_guard<std::mutex> lock(m_mutex);
102 if (logger_index >= 0 && logger_index < static_cast<int>(m_loggers.size())) {
103 return m_loggers[logger_index].single_mode;
104 }
105 return false;
106 }
107
113 void log(const LogRecord& record) {
114 if (m_shutdown) return;
115 std::lock_guard<std::mutex> lock(m_mutex);
116 // Log to the specific logger if the index is valid
117 if (record.logger_index >= 0 && record.logger_index < static_cast<int>(m_loggers.size())) {
118 const auto& strategy = m_loggers[record.logger_index];
119 if (!strategy.enabled) return;
120 strategy.logger->log(record, strategy.formatter->format(record));
121 return;
122 }
123 for (const auto& strategy : m_loggers) {
124 if (strategy.single_mode) continue;
125 if (!strategy.enabled) continue;
126 strategy.logger->log(record, strategy.formatter->format(record));
127 }
128 }
129
134 std::string get_string_param(int logger_index, const LoggerParam& param) const {
135 if (m_shutdown) return std::string();
136 if (logger_index >= 0 && logger_index < static_cast<int>(m_loggers.size())) {
137 const auto& strategy = m_loggers[logger_index];
138 return strategy.logger->get_string_param(param);
139 }
140 return std::string();
141 }
142
147 int64_t get_int_param(int logger_index, const LoggerParam& param) const {
148 if (m_shutdown) return 0;
149 if (logger_index >= 0 && logger_index < static_cast<int>(m_loggers.size())) {
150 const auto& strategy = m_loggers[logger_index];
151 return strategy.logger->get_int_param(param);
152 }
153 return 0;
154 }
155
160 double get_float_param(int logger_index, const LoggerParam& param) const {
161 if (m_shutdown) return 0.0;
162 if (logger_index >= 0 && logger_index < static_cast<int>(m_loggers.size())) {
163 const auto& strategy = m_loggers[logger_index];
164 return strategy.logger->get_float_param(param);
165 }
166 return 0.0;
167 }
168
174 template <typename... Ts>
175 auto log_and_return(const LogRecord& record, Ts&&... args) -> decltype(std::forward_as_tuple(std::forward<Ts>(args)...)) {
176 this->print(record, args...);
177 return std::forward_as_tuple(std::forward<Ts>(args)...);
178 }
179
187 template <typename T>
188 auto log_and_return(const LogRecord& record, T&& args) -> decltype(args) {
189 this->print(record, args);
190 return std::forward<decltype(args)>(args);
191 }
192
196 auto log_and_return(const LogRecord& record) -> std::tuple<> {
197 this->print(record);
198 return {};
199 }
200
204 void wait() {
205 for (const auto& strategy : m_loggers) {
206 strategy.logger->wait();
207 }
208 }
209
214 void shutdown() {
215 if (m_shutdown) return;
216 m_shutdown = true;
217 wait();
219 }
220
221 private:
222
226 std::unique_ptr<ILogger> logger;
227 std::unique_ptr<ILogFormatter> formatter;
229 bool enabled;
230 };
231
232 std::vector<LoggerStrategy> m_loggers;
233 mutable std::mutex m_mutex;
234 std::atomic<bool> m_shutdown = ATOMIC_VAR_INIT(false);
235
240 template <typename... Ts>
241 void print(const LogRecord& record, Ts const&... args) {
242 if (sizeof...(Ts) == 0) {
243 log(record);
244 return;
245 }
246 LogRecord mutable_record = record;
247 auto var_names = split_arguments(mutable_record.arg_names);
248 mutable_record.args_array = args_to_array(var_names.begin(), args...);
249 log(mutable_record);
250 }
251
253 std::atexit(Logger::on_exit_handler);
254 }
255
257 shutdown();
258 }
259
260 // Deleting copy and move constructors and assignment operators to enforce singleton.
261 Logger(const Logger&) = delete;
262 Logger& operator=(const Logger&) = delete;
263 Logger(Logger&&) = delete;
264 Logger& operator=(Logger&&) = delete;
265
268 static void on_exit_handler() {
270 }
271 };
272
273}; // namespace logit
274
275#endif // _LOGIT_LOGGER_HPP_INCLUDED
Defines the interface for log formatters used in the logging system.
Defines the interface for loggers used in the logging system.
auto log_and_return(const LogRecord &record) -> std::tuple<>
Logs message without arguments and returns empty tuple.
Definition Logger.hpp:196
auto log_and_return(const LogRecord &record, T &&args) -> decltype(args)
Logs message and returns argument.
Definition Logger.hpp:188
void set_logger_enabled(int logger_index, bool enabled)
Enables or disables a logger by index.
Definition Logger.hpp:55
void wait()
Waits for all asynchronous loggers to finish processing.
Definition Logger.hpp:204
void log(const LogRecord &record)
Logs a LogRecord using added loggers and formatters.
Definition Logger.hpp:113
void set_logger_single_mode(int logger_index, bool single_mode)
Sets single-mode flag for a logger.
Definition Logger.hpp:77
void set_timestamp_offset(int logger_index, int64_t offset_ms)
Sets timestamp offset for a specific logger.
Definition Logger.hpp:88
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:38
Logger & operator=(const Logger &)=delete
Logger(const Logger &)=delete
void shutdown()
Shuts down logger system.
Definition Logger.hpp:214
std::vector< LoggerStrategy > m_loggers
Container for logger-formatter pairs.
Definition Logger.hpp:232
std::mutex m_mutex
Mutex for thread safety during logging operations.
Definition Logger.hpp:233
bool is_logger_single_mode(int logger_index) const
Checks whether a logger is in single mode.
Definition Logger.hpp:99
std::atomic< bool > m_shutdown
Flag indicating if shutdown was requested.
Definition Logger.hpp:234
double get_float_param(int logger_index, const LoggerParam &param) const
Retrieves a floating-point parameter from a logger.
Definition Logger.hpp:160
std::string get_string_param(int logger_index, const LoggerParam &param) const
Retrieves a string parameter from a logger.
Definition Logger.hpp:134
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:175
int64_t get_int_param(int logger_index, const LoggerParam &param) const
Retrieves an integer parameter from a logger.
Definition Logger.hpp:147
static void on_exit_handler()
Atexit shutdown handler for Logger and TaskExecutor.
Definition Logger.hpp:268
bool is_logger_enabled(int logger_index) const
Checks if a logger is enabled.
Definition Logger.hpp:66
static Logger & get_instance()
Retrieves singleton instance of Logger.
Definition Logger.hpp:27
Logger & operator=(Logger &&)=delete
Logger(Logger &&)=delete
void print(const LogRecord &record, Ts const &... args)
Logs a record with given arguments.
Definition Logger.hpp:241
void shutdown()
Shuts down the TaskExecutor by stopping the worker thread.
static TaskExecutor & get_instance()
Get the singleton instance of the TaskExecutor.
The primary namespace for the LogIt++ library.
std::vector< std::string > split_arguments(const std::string &all_names)
Splits a string of argument names into individual names, ignoring nested templates,...
LoggerParam
Enumeration for different logger parameters that can be retrieved.
Definition Enums.hpp:46
std::vector< VariableValue > args_to_array(std::vector< std::string >::const_iterator name_iter)
Base case of recursion for argument conversion — when there are no more arguments.
Stores log metadata and content.
Definition LogRecord.hpp:13
const int logger_index
Logger index (-1 to log to all).
Definition LogRecord.hpp:23
const std::string format
Format string for the message.
Definition LogRecord.hpp:19
std::vector< VariableValue > args_array
Argument values for the log.
Definition LogRecord.hpp:21
const std::string arg_names
Argument names for the log.
Definition LogRecord.hpp:20
Structure to hold a logger-formatter pair.
Definition Logger.hpp:225
std::unique_ptr< ILogger > logger
The logger instance.
Definition Logger.hpp:226
bool single_mode
Flag indicating if the logger is in single mode.
Definition Logger.hpp:228
std::unique_ptr< ILogFormatter > formatter
The formatter instance.
Definition Logger.hpp:227
bool enabled
Flag indicating if the logger is enabled.
Definition Logger.hpp:229