DotNameLib
Loading...
Searching...
No Matches
ILogger.hpp
Go to the documentation of this file.
1#ifndef ILOGGER_HPP
2#define ILOGGER_HPP
3
4#include "fmt/core.h"
5#include <cstdint>
6#include <memory>
7#include <sstream>
8#include <string>
9
10// Include source_location for C++20 and later
11#if __cplusplus >= 202002L
12#include <source_location>
13#endif
14
16
21 enum class Level : std::uint8_t { LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_CRITICAL };
22
26 class ILogger;
27
31 class LogStream {
32 public:
33 LogStream(std::shared_ptr<ILogger> logger, Level level, std::string caller)
34 : logger_(std::move(logger)), level_(level), caller_(std::move(caller)) {}
35
36 ~LogStream();
37
45 template <typename T>
46 LogStream &operator<<(const T &value) {
47 oss_ << value;
48 return *this;
49 }
50
57 LogStream &operator<<(std::ostream &(*manip)(std::ostream &)) {
58 oss_ << manip;
59 return *this;
60 }
61
62 private:
63 std::shared_ptr<ILogger> logger_;
64 Level level_;
65 std::string caller_;
66 std::ostringstream oss_;
67 };
68
69 class ILogger : public std::enable_shared_from_this<ILogger> {
70 public:
71 ILogger() = default;
72 virtual ~ILogger() = default;
73
80 virtual void debug(const std::string &message, const std::string &caller = "") = 0;
81
88 virtual void info(const std::string &message, const std::string &caller = "") = 0;
89
96 virtual void warning(const std::string &message, const std::string &caller = "") = 0;
97
104 virtual void error(const std::string &message, const std::string &caller = "") = 0;
105
112 virtual void critical(const std::string &message, const std::string &caller = "") = 0;
113
119 virtual void setLevel(Level level) = 0;
120
126 [[nodiscard]]
127 virtual Level getLevel() const = 0;
128
134 virtual void setAppPrefix(const std::string &prefix) = 0;
135
141 virtual std::string getAppPrefix() const = 0;
142
150 virtual bool enableFileLogging(const std::string &filename) = 0;
151
156 virtual void disableFileLogging() = 0;
157
165 LogStream stream(Level level, const std::string &caller = "") {
166 return LogStream{shared_from_this(), level, caller};
167 }
168
169 // Convenience methods for each log level
170
177 LogStream debugStream(const std::string &caller = "") {
178 return stream(Level::LOG_DEBUG, caller);
179 }
180
187 LogStream infoStream(const std::string &caller = "") { return stream(Level::LOG_INFO, caller); }
188
195 LogStream warningStream(const std::string &caller = "") {
196 return stream(Level::LOG_WARNING, caller);
197 }
198
205 LogStream errorStream(const std::string &caller = "") {
206 return stream(Level::LOG_ERROR, caller);
207 }
208
215 LogStream criticalStream(const std::string &caller = "") {
216 return stream(Level::LOG_CRITICAL, caller);
217 }
218
219 // Fmt convenience methods (non-virtual templates)
227 template <typename... Args>
228 void debugFmt(const std::string &format, Args &&...args);
229
237 template <typename... Args>
238 void infoFmt(const std::string &format, Args &&...args);
239
247 template <typename... Args>
248 void warningFmt(const std::string &format, Args &&...args);
249
257 template <typename... Args>
258 void errorFmt(const std::string &format, Args &&...args);
259
267 template <typename... Args>
268 void criticalFmt(const std::string &format, Args &&...args);
269
270#if __cplusplus >= 202002L
271 // C++20 source_location support
272
279 void debugWithLocation(const std::string &message,
280 const std::source_location &location = std::source_location::current()) {
281 debugStream() << "Log: " << message << "\n"
282 << "File: " << location.file_name() << "\n"
283 << "Function: " << location.function_name() << "\n"
284 << "Line: " << location.line() << "\n";
285 }
286
293 void infoWithLocation(const std::string &message,
294 const std::source_location &location = std::source_location::current()) {
295 infoStream() << "Log: " << message << "\n"
296 << "File: " << location.file_name() << "\n"
297 << "Function: " << location.function_name() << "\n"
298 << "Line: " << location.line() << "\n";
299 }
300
307 void warningWithLocation(const std::string &message, const std::source_location &location =
308 std::source_location::current()) {
309 warningStream() << "Log: " << message << "\n"
310 << "File: " << location.file_name() << "\n"
311 << "Function: " << location.function_name() << "\n"
312 << "Line: " << location.line() << "\n";
313 }
314
321 void errorWithLocation(const std::string &message,
322 const std::source_location &location = std::source_location::current()) {
323 errorStream() << "Log: " << message << "\n"
324 << "File: " << location.file_name() << "\n"
325 << "Function: " << location.function_name() << "\n"
326 << "Line: " << location.line() << "\n";
327 }
328
335 void criticalWithLocation(const std::string &message, const std::source_location &location =
336 std::source_location::current()) {
337 criticalStream() << "Log: " << message << "\n"
338 << "File: " << location.file_name() << "\n"
339 << "Function: " << location.function_name() << "\n"
340 << "Line: " << location.line() << "\n";
341 }
342#endif
343 };
344
350 const std::string message = oss_.str();
351 switch (level_) {
352 case Level::LOG_DEBUG: logger_->debug(message, caller_); break;
353 case Level::LOG_INFO: logger_->info(message, caller_); break;
354 case Level::LOG_WARNING: logger_->warning(message, caller_); break;
355 case Level::LOG_ERROR: logger_->error(message, caller_); break;
356 case Level::LOG_CRITICAL: logger_->critical(message, caller_); break;
357 }
358 }
359
360 // Implementations of the fmt convenience methods
361 template <typename... Args>
362 inline void ILogger::debugFmt(const std::string &format, Args &&...args) {
363 std::string message = fmt::vformat(format, fmt::make_format_args(args...));
364 debug(message, "");
365 }
366
367 template <typename... Args>
368 inline void ILogger::infoFmt(const std::string &format, Args &&...args) {
369 std::string message = fmt::vformat(format, fmt::make_format_args(args...));
370 info(message, "");
371 }
372
373 template <typename... Args>
374 inline void ILogger::warningFmt(const std::string &format, Args &&...args) {
375 std::string message = fmt::vformat(format, fmt::make_format_args(args...));
376 warning(message, "");
377 }
378
379 template <typename... Args>
380 inline void ILogger::errorFmt(const std::string &format, Args &&...args) {
381 std::string message = fmt::vformat(format, fmt::make_format_args(args...));
382 error(message, "");
383 }
384
385 template <typename... Args>
386 inline void ILogger::criticalFmt(const std::string &format, Args &&...args) {
387 std::string message = fmt::vformat(format, fmt::make_format_args(args...));
388 critical(message, "");
389 }
390
391} // namespace dotnamecpp::logging
392
393#endif
virtual void info(const std::string &message, const std::string &caller="")=0
Log an info message.
virtual bool enableFileLogging(const std::string &filename)=0
Enable logging to a file.
LogStream errorStream(const std::string &caller="")
Create a LogStream for streaming error messages.
Definition ILogger.hpp:205
LogStream warningStream(const std::string &caller="")
Create a LogStream for streaming warning messages.
Definition ILogger.hpp:195
LogStream debugStream(const std::string &caller="")
Create a LogStream for streaming debug messages.
Definition ILogger.hpp:177
virtual void warning(const std::string &message, const std::string &caller="")=0
Log a warning message.
virtual void disableFileLogging()=0
Disable logging to a file.
virtual std::string getAppPrefix() const =0
Get the App Prefix object.
void infoFmt(const std::string &format, Args &&...args)
Create a formatted info message.
Definition ILogger.hpp:368
virtual void critical(const std::string &message, const std::string &caller="")=0
Log a critical message.
virtual void debug(const std::string &message, const std::string &caller="")=0
Log a debug message.
virtual void setLevel(Level level)=0
Set the Level object.
LogStream infoStream(const std::string &caller="")
Create a LogStream for streaming info messages.
Definition ILogger.hpp:187
void debugFmt(const std::string &format, Args &&...args)
Create a formatted debug message.
Definition ILogger.hpp:362
virtual Level getLevel() const =0
Get the Level object.
LogStream criticalStream(const std::string &caller="")
Create a LogStream for streaming critical messages.
Definition ILogger.hpp:215
virtual void error(const std::string &message, const std::string &caller="")=0
Log an error message.
void criticalFmt(const std::string &format, Args &&...args)
Create a formatted critical message.
Definition ILogger.hpp:386
LogStream stream(Level level, const std::string &caller="")
Create a LogStream for streaming log messages.
Definition ILogger.hpp:165
void errorFmt(const std::string &format, Args &&...args)
Create a formatted error message.
Definition ILogger.hpp:380
virtual void setAppPrefix(const std::string &prefix)=0
Set the application prefix for log messages.
void warningFmt(const std::string &format, Args &&...args)
Create a formatted warning message.
Definition ILogger.hpp:374
virtual ~ILogger()=default
Helper class for streaming log messages.
Definition ILogger.hpp:31
LogStream(std::shared_ptr< ILogger > logger, Level level, std::string caller)
Definition ILogger.hpp:33
~LogStream()
Destroy the Log Stream:: Log Stream object.
Definition ILogger.hpp:349
LogStream & operator<<(const T &value)
Stream a value into the log message.
Definition ILogger.hpp:46
LogStream & operator<<(std::ostream &(*manip)(std::ostream &))
Stream a manipulator into the log message (e.g., std::endl)
Definition ILogger.hpp:57
Definition ILogger.hpp:15
Level
Logging levels.
Definition ILogger.hpp:21
@ LOG_CRITICAL
Definition ILogger.hpp:21
@ LOG_INFO
Definition ILogger.hpp:21
@ LOG_ERROR
Definition ILogger.hpp:21
@ LOG_WARNING
Definition ILogger.hpp:21
@ LOG_DEBUG
Definition ILogger.hpp:21