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
25 class ConsoleLogger : public ILogger {
26 public:
27
34
38 }
39
42 ConsoleLogger(const Config& config) : m_config(config) {
44 }
45
48 ConsoleLogger(const bool async) {
49 m_config.async = async;
51 }
52
53 virtual ~ConsoleLogger() = default;
54
58 void set_config(const Config& config) {
59 std::lock_guard<std::mutex> lock(m_mutex);
60 m_config = config;
61 }
62
67 std::lock_guard<std::mutex> lock(m_mutex);
68 return m_config;
69 }
70
78 void log(const LogRecord& record, const std::string& message) override {
80 std::unique_lock<std::mutex> lock(m_mutex);
81 if (!m_config.async) {
82# if defined(__MINGW32__) || defined(_WIN32)
83 // For Windows, parse the message for ANSI color codes and apply them
84 handle_ansi_colors_windows(message);
85# else
86 // For other systems, output the message as is
87 std::cout << message << std::endl;
88# endif
89 return;
90 }
91 lock.unlock();
92 TaskExecutor::get_instance().add_task([this, message](){
93 std::lock_guard<std::mutex> lock(m_mutex);
94# if defined(__MINGW32__) || defined(_WIN32)
95 // For Windows, parse the message for ANSI color codes and apply them
96 handle_ansi_colors_windows(message);
97# else
98 // For other systems, output the message as is
99 std::cout << message << std::endl;
100# endif
101 });
102 }
103
111 std::string get_string_param(const LoggerParam& param) const override {
112 switch (param) {
113 case LoggerParam::LastLogTimestamp: return std::to_string(get_last_log_ts());
114 case LoggerParam::TimeSinceLastLog: return std::to_string(get_time_since_last_log());
115 default:
116 break;
117 };
118 return std::string();
119 }
120
124 int64_t get_int_param(const LoggerParam& param) const override {
125 switch (param) {
128 default:
129 break;
130 };
131 return 0;
132 }
133
137 double get_float_param(const LoggerParam& param) const override {
138 switch (param) {
139 case LoggerParam::LastLogTimestamp: return (double)get_last_log_ts() / 1000.0;
140 case LoggerParam::TimeSinceLastLog: return (double)get_time_since_last_log() / 1000.0;
141 default:
142 break;
143 };
144 return 0.0;
145 }
146
149 void wait() override {
150 std::unique_lock<std::mutex> lock(m_mutex);
151 if (!m_config.async) return;
152 lock.unlock();
154 }
155
156 private:
157 mutable std::mutex m_mutex;
159 std::atomic<int64_t> m_last_log_ts = ATOMIC_VAR_INIT(0);
160
161# if defined(__MINGW32__) || defined(_WIN32)
162
163 // Windows console colors
164 enum class WinColor {
165 Black = 0,
166 DarkBlue = 1,
167 DarkGreen = 2,
168 DarkCyan = 3,
169 DarkRed = 4,
170 DarkMagenta = 5,
171 DarkYellow = 6,
172 Gray = 7,
173 DarkGray = 8,
174 Blue = 9,
175 Green = 10,
176 Cyan = 11,
177 Red = 12,
178 Magenta = 13,
179 Yellow = 14,
180 White = 15,
181 };
182
185 void handle_ansi_colors_windows(const std::string& message) const {
186 std::string::size_type start = 0;
187 std::string::size_type pos = 0;
188
189 HANDLE handle_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
190
191 while ((pos = message.find("\033[", start)) != std::string::npos) {
192 // Output the part of the string before the ANSI code
193 if (pos > start) {
194 std::cout << message.substr(start, pos - start);
195 }
196
197 // Find the end of the ANSI code
198 std::string::size_type end_pos = message.find('m', pos);
199 if (end_pos != std::string::npos) {
200 // Extract the ANSI code
201 std::string ansi_code = message.substr(pos + 2, end_pos - pos - 2);
202 apply_color_from_ansi_code(ansi_code, handle_stdout);
203
204 // Update position
205 start = end_pos + 1;
206 } else {
207 break;
208 }
209 }
210
211 // Output any remaining part of the message
212 if (start < message.size()) {
213 std::cout << message.substr(start);
214 }
215 if (!message.empty()) std::cout << std::endl;
216
217 // Reset the console color to default
218 SetConsoleTextAttribute(handle_stdout, static_cast<WORD>(text_color_to_win_color(m_config.default_color)));
219 }
220
224 void apply_color_from_ansi_code(const std::string& ansi_code, HANDLE handle_stdout) const {
225 WORD color_value = static_cast<WORD>(text_color_to_win_color(m_config.default_color)); // Default color
226 const int code = std::stoi(ansi_code);
227 switch (code) {
228 case 30: color_value = static_cast<WORD>(WinColor::Black); break;
229 case 31: color_value = static_cast<WORD>(WinColor::DarkRed); break;
230 case 32: color_value = static_cast<WORD>(WinColor::DarkGreen); break;
231 case 33: color_value = static_cast<WORD>(WinColor::DarkYellow); break;
232 case 34: color_value = static_cast<WORD>(WinColor::DarkBlue); break;
233 case 35: color_value = static_cast<WORD>(WinColor::DarkMagenta); break;
234 case 36: color_value = static_cast<WORD>(WinColor::DarkCyan); break;
235 case 37: color_value = static_cast<WORD>(WinColor::Gray); break;
236 case 90: color_value = static_cast<WORD>(WinColor::DarkGray); break;
237 case 91: color_value = static_cast<WORD>(WinColor::Red); break;
238 case 92: color_value = static_cast<WORD>(WinColor::Green); break;
239 case 93: color_value = static_cast<WORD>(WinColor::Yellow); break;
240 case 94: color_value = static_cast<WORD>(WinColor::Blue); break;
241 case 95: color_value = static_cast<WORD>(WinColor::Magenta); break;
242 case 96: color_value = static_cast<WORD>(WinColor::Cyan); break;
243 case 97: color_value = static_cast<WORD>(WinColor::White); break;
244 default:
245 // Unknown code, use default color
246 break;
247 };
248 // Set the console text attribute to the desired color
249 SetConsoleTextAttribute(handle_stdout, color_value);
250 }
251
255 WinColor text_color_to_win_color(const TextColor& color) const {
256 switch (color) {
257 case TextColor::Black: return WinColor::Black;
258 case TextColor::DarkRed: return WinColor::DarkRed;
259 case TextColor::DarkGreen: return WinColor::DarkGreen;
260 case TextColor::DarkYellow: return WinColor::DarkYellow;
261 case TextColor::DarkBlue: return WinColor::DarkBlue;
262 case TextColor::DarkMagenta: return WinColor::DarkMagenta;
263 case TextColor::DarkCyan: return WinColor::DarkCyan;
264 case TextColor::LightGray: return WinColor::Gray;
265 case TextColor::DarkGray: return WinColor::DarkGray;
266 case TextColor::Red: return WinColor::Red;
267 case TextColor::Green: return WinColor::Green;
268 case TextColor::Yellow: return WinColor::Yellow;
269 case TextColor::Blue: return WinColor::Blue;
270 case TextColor::Magenta: return WinColor::Magenta;
271 case TextColor::Cyan: return WinColor::Cyan;
272 case TextColor::White: return WinColor::White;
273 default: return WinColor::White;
274 }
275 }
276# endif
277
279 void reset_color() {
280# if defined(__MINGW32__) || defined(_WIN32)
281 handle_ansi_colors_windows(std::string());
282# else
283 std::cout << to_string(m_config.default_color);
284# endif
285 }
286
289 int64_t get_last_log_ts() const {
290 return m_last_log_ts;
291 }
292
295 int64_t get_time_since_last_log() const {
297 }
298 }; // ConsoleLogger
299
300}; // namespace logit
301
302#endif // _LOGIT_CONSOLE_LOGGER_HPP_INCLUDED
Defines the interface for loggers used in the logging system.
#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,...
Provides various logging macros for different log levels and options.
Defines the TaskExecutor class, which manages task execution in a separate thread.
Logger that outputs log messages to the console with optional color coding.
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:13
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.
The primary namespace for the LogIt++ library.
std::string to_string(const LogLevel &level, const 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