LogIt++
Loading...
Searching...
No Matches
ConsoleLogger.hpp
Go to the documentation of this file.
1#pragma once
2#ifndef _LOGIT_CONSOLE_LOGGER_HPP_INCLUDED
3#define _LOGIT_CONSOLE_LOGGER_HPP_INCLUDED
6
7#include "ILogger.hpp"
8#include "../TaskExecutor.hpp"
9#include "../LogMacros.hpp"
10#include <iostream>
11#if defined(__MINGW32__) || defined(_WIN32)
12#include <windows.h>
13#endif
14#include <mutex>
15#include <atomic>
16
17namespace logit {
18
30 class ConsoleLogger : public ILogger {
31 public:
32
39
43 }
44
47 ConsoleLogger(const Config& config) : m_config(config) {
49 }
50
53 ConsoleLogger(const bool async) {
54 m_config.async = async;
56 }
57
58 virtual ~ConsoleLogger() = default;
59
63 void set_config(const Config& config) {
64 std::lock_guard<std::mutex> lock(m_mutex);
65 m_config = config;
66 }
67
72 std::lock_guard<std::mutex> lock(m_mutex);
73 return m_config;
74 }
75
83 void log(const LogRecord& record, const std::string& message) override {
85 std::unique_lock<std::mutex> lock(m_mutex);
86 if (!m_config.async) {
87# if defined(__MINGW32__) || defined(_WIN32)
88 // For Windows, parse the message for ANSI color codes and apply them
89 handle_ansi_colors_windows(message);
90# else
91 // For other systems, output the message as is
92 std::cout << message << std::endl;
93# endif
94 return;
95 }
96 lock.unlock();
97 TaskExecutor::get_instance().add_task([this, message](){
98 std::lock_guard<std::mutex> lock(m_mutex);
99# if defined(__MINGW32__) || defined(_WIN32)
100 // For Windows, parse the message for ANSI color codes and apply them
101 handle_ansi_colors_windows(message);
102# else
103 // For other systems, output the message as is
104 std::cout << message << std::endl;
105# endif
106 });
107 }
108
116 std::string get_string_param(const LoggerParam& param) const override {
117 switch (param) {
118 case LoggerParam::LastLogTimestamp: return std::to_string(get_last_log_ts());
119 case LoggerParam::TimeSinceLastLog: return std::to_string(get_time_since_last_log());
120 default:
121 break;
122 };
123 return std::string();
124 }
125
129 int64_t get_int_param(const LoggerParam& param) const override {
130 switch (param) {
133 default:
134 break;
135 };
136 return 0;
137 }
138
142 double get_float_param(const LoggerParam& param) const override {
143 switch (param) {
144 case LoggerParam::LastLogTimestamp: return (double)get_last_log_ts() / 1000.0;
145 case LoggerParam::TimeSinceLastLog: return (double)get_time_since_last_log() / 1000.0;
146 default:
147 break;
148 };
149 return 0.0;
150 }
151
154 void wait() override {
155 std::unique_lock<std::mutex> lock(m_mutex);
156 if (!m_config.async) return;
157 lock.unlock();
159 }
160
161 private:
162 mutable std::mutex m_mutex;
164 std::atomic<int64_t> m_last_log_ts = ATOMIC_VAR_INIT(0);
165
166# if defined(__MINGW32__) || defined(_WIN32)
167
168 // Windows console colors
169 enum class WinColor {
170 Black = 0,
171 DarkBlue = 1,
172 DarkGreen = 2,
173 DarkCyan = 3,
174 DarkRed = 4,
175 DarkMagenta = 5,
176 DarkYellow = 6,
177 Gray = 7,
178 DarkGray = 8,
179 Blue = 9,
180 Green = 10,
181 Cyan = 11,
182 Red = 12,
183 Magenta = 13,
184 Yellow = 14,
185 White = 15,
186 };
187
190 void handle_ansi_colors_windows(const std::string& message) const {
191 std::string::size_type start = 0;
192 std::string::size_type pos = 0;
193
194 HANDLE handle_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
195
196 while ((pos = message.find("\033[", start)) != std::string::npos) {
197 // Output the part of the string before the ANSI code
198 if (pos > start) {
199 std::cout << message.substr(start, pos - start);
200 }
201
202 // Find the end of the ANSI code
203 std::string::size_type end_pos = message.find('m', pos);
204 if (end_pos != std::string::npos) {
205 // Extract the ANSI code
206 std::string ansi_code = message.substr(pos + 2, end_pos - pos - 2);
207 apply_color_from_ansi_code(ansi_code, handle_stdout);
208
209 // Update position
210 start = end_pos + 1;
211 } else {
212 break;
213 }
214 }
215
216 // Output any remaining part of the message
217 if (start < message.size()) {
218 std::cout << message.substr(start);
219 }
220 if (!message.empty()) std::cout << std::endl;
221
222 // Reset the console color to default
223 SetConsoleTextAttribute(handle_stdout, static_cast<WORD>(text_color_to_win_color(m_config.default_color)));
224 }
225
229 void apply_color_from_ansi_code(const std::string& ansi_code, HANDLE handle_stdout) const {
230 WORD color_value = static_cast<WORD>(text_color_to_win_color(m_config.default_color)); // Default color
231 const int code = std::stoi(ansi_code);
232 switch (code) {
233 case 30: color_value = static_cast<WORD>(WinColor::Black); break;
234 case 31: color_value = static_cast<WORD>(WinColor::DarkRed); break;
235 case 32: color_value = static_cast<WORD>(WinColor::DarkGreen); break;
236 case 33: color_value = static_cast<WORD>(WinColor::DarkYellow); break;
237 case 34: color_value = static_cast<WORD>(WinColor::DarkBlue); break;
238 case 35: color_value = static_cast<WORD>(WinColor::DarkMagenta); break;
239 case 36: color_value = static_cast<WORD>(WinColor::DarkCyan); break;
240 case 37: color_value = static_cast<WORD>(WinColor::Gray); break;
241 case 90: color_value = static_cast<WORD>(WinColor::DarkGray); break;
242 case 91: color_value = static_cast<WORD>(WinColor::Red); break;
243 case 92: color_value = static_cast<WORD>(WinColor::Green); break;
244 case 93: color_value = static_cast<WORD>(WinColor::Yellow); break;
245 case 94: color_value = static_cast<WORD>(WinColor::Blue); break;
246 case 95: color_value = static_cast<WORD>(WinColor::Magenta); break;
247 case 96: color_value = static_cast<WORD>(WinColor::Cyan); break;
248 case 97: color_value = static_cast<WORD>(WinColor::White); break;
249 default:
250 // Unknown code, use default color
251 break;
252 };
253 // Set the console text attribute to the desired color
254 SetConsoleTextAttribute(handle_stdout, color_value);
255 }
256
260 WinColor text_color_to_win_color(const TextColor& color) const {
261 switch (color) {
262 case TextColor::Black: return WinColor::Black;
263 case TextColor::DarkRed: return WinColor::DarkRed;
264 case TextColor::DarkGreen: return WinColor::DarkGreen;
265 case TextColor::DarkYellow: return WinColor::DarkYellow;
266 case TextColor::DarkBlue: return WinColor::DarkBlue;
267 case TextColor::DarkMagenta: return WinColor::DarkMagenta;
268 case TextColor::DarkCyan: return WinColor::DarkCyan;
269 case TextColor::LightGray: return WinColor::Gray;
270 case TextColor::DarkGray: return WinColor::DarkGray;
271 case TextColor::Red: return WinColor::Red;
272 case TextColor::Green: return WinColor::Green;
273 case TextColor::Yellow: return WinColor::Yellow;
274 case TextColor::Blue: return WinColor::Blue;
275 case TextColor::Magenta: return WinColor::Magenta;
276 case TextColor::Cyan: return WinColor::Cyan;
277 case TextColor::White: return WinColor::White;
278 default: return WinColor::White;
279 }
280 }
281# endif
282
284 void reset_color() {
285# if defined(__MINGW32__) || defined(_WIN32)
286 handle_ansi_colors_windows(std::string());
287# else
288 std::cout << to_string(m_config.default_color);
289# endif
290 }
291
294 int64_t get_last_log_ts() const {
295 return m_last_log_ts;
296 }
297
300 int64_t get_time_since_last_log() const {
302 }
303 }; // ConsoleLogger
304
305}; // namespace logit
306
307#endif // _LOGIT_CONSOLE_LOGGER_HPP_INCLUDED
Defines the interface for loggers used in the logging system.
Provides various logging macros for different log levels and options.
Defines the TaskExecutor class, which manages task execution in a separate thread.
Outputs log messages to the console with optional ANSI color support.
void log(const LogRecord &record, const std::string &message) override
Logs a message to the console with thread safety.
ConsoleLogger()
Default constructor that uses default configuration.
double get_float_param(const LoggerParam &param) const override
Retrieves a floating-point parameter from the logger.
std::mutex m_mutex
Mutex to protect console output.
int64_t get_last_log_ts() const
Retrieves the timestamp of the last log.
virtual ~ConsoleLogger()=default
int64_t get_time_since_last_log() const
Retrieves the time since the last log.
std::string get_string_param(const LoggerParam &param) const override
Retrieves a string parameter from the logger.
void set_config(const Config &config)
Sets the logger configuration. This method sets the logger's configuration and ensures thread safety ...
int64_t get_int_param(const LoggerParam &param) const override
Retrieves an integer parameter from the logger.
ConsoleLogger(const bool async)
Constructor with asynchronous flag.
Config get_config()
Gets the current logger configuration. Returns the logger's configuration with thread safety ensured.
std::atomic< int64_t > m_last_log_ts
ConsoleLogger(const Config &config)
Constructor with custom configuration.
Config m_config
Configuration for the console logger.
void wait() override
Waits for all asynchronous tasks to complete. If asynchronous logging is enabled, waits for all pendi...
void reset_color()
Resets the console text color to the default.
Interface for loggers that handle log message output.
Definition ILogger.hpp:27
void add_task(std::function< void()> task)
Adds a task to the queue in a thread-safe manner.
void wait()
Waits for all tasks in the queue to be processed.
static TaskExecutor & get_instance()
Get the singleton instance of the TaskExecutor.
#define LOGIT_DEFAULT_COLOR
Defines the default color for console output. If LOGIT_DEFAULT_COLOR is not defined,...
#define LOGIT_CURRENT_TIMESTAMP_MS()
Macro to get the current timestamp in milliseconds. If LOGIT_CURRENT_TIMESTAMP_MS is not defined,...
The primary namespace for the LogIt++ library.
std::string to_string(LogLevel level, int mode=0)
Convert LogLevel to a std::string representation.
Definition Enums.hpp:89
LoggerParam
Enumeration for different logger parameters that can be retrieved.
Definition Enums.hpp:46
@ TimeSinceLastLog
The time elapsed since the last log in seconds.
@ LastLogTimestamp
The timestamp of the last log.
TextColor
Text colors for console output.
Definition Enums.hpp:25
Configuration for the console logger.
bool async
Flag indicating whether logging should be asynchronous.
TextColor default_color
Default text color for console output.
Stores log metadata and content.
Definition LogRecord.hpp:15
const int64_t timestamp_ms
Timestamp in milliseconds.
Definition LogRecord.hpp:17