LiteFX 0.4.1.2025
Computer Graphics Engine
Loading...
Searching...
No Matches
logging.hpp
1#pragma once
2
3#include <litefx/config.h>
4
5#if !defined (LITEFX_LOGGING_API)
6# if defined(LiteFX_Logging_EXPORTS) && (defined _WIN32 || defined WINCE)
7# define LITEFX_LOGGING_API __declspec(dllexport)
8# elif (defined(LiteFX_Logging_EXPORTS) || defined(__APPLE__)) && defined __GNUC__ && __GNUC__ >= 4
9# define LITEFX_LOGGING_API __attribute__ ((visibility ("default")))
10# elif !defined(LiteFX_Logging_EXPORTS) && (defined _WIN32 || defined WINCE)
11# define LITEFX_LOGGING_API __declspec(dllimport)
12# endif
13#endif
14
15#ifndef LITEFX_LOGGING_API
16# define LITEFX_LOGGING_API
17#endif
18
19#include <litefx/core.h>
20#include <spdlog/spdlog.h>
21#include <spdlog/sinks/sink.h>
22
23namespace LiteFX::Logging {
24 using namespace LiteFX;
25
29 enum class LogLevel : std::uint8_t {
30 Trace = SPDLOG_LEVEL_TRACE,
31 Debug = SPDLOG_LEVEL_DEBUG,
32 Info = SPDLOG_LEVEL_INFO,
33 Warning = SPDLOG_LEVEL_WARN,
34 Error = SPDLOG_LEVEL_ERROR,
35 Fatal = SPDLOG_LEVEL_CRITICAL,
36 Off = SPDLOG_LEVEL_OFF,
37 Invalid = 0xFF
38 };
39
43 class LITEFX_LOGGING_API ISink {
44 protected:
45 ISink() noexcept = default;
46 ISink(const ISink&) = default;
47 ISink(ISink&&) noexcept = default;
48 ISink& operator=(const ISink&) = default;
49 ISink& operator=(ISink&&) noexcept = default;
50
51 public:
52 virtual ~ISink() noexcept = default;
53
57 virtual LogLevel getLevel() const = 0;
58
62 virtual String getName() const = 0;
63
67 virtual String getPattern() const = 0;
68
69 protected:
70 friend class Logger;
71 virtual spdlog::sink_ptr get() const = 0;
72 };
73
77 class LITEFX_LOGGING_API ConsoleSink : public ISink {
78 LITEFX_IMPLEMENTATION(ConsoleSinkImpl);
79
80 public:
86 ConsoleSink(LogLevel level = LogLevel::Info, const String& pattern = "%+");
87 ~ConsoleSink() noexcept override;
88
89 ConsoleSink(const ConsoleSink&) = delete;
90 ConsoleSink(ConsoleSink&&) noexcept = delete;
91 auto operator=(const ConsoleSink&) = delete;
92 auto operator=(ConsoleSink&&) noexcept = delete;
93
94 public:
96 LogLevel getLevel() const override;
97
99 String getName() const override;
100
102 String getPattern() const override;
103
104 protected:
105 spdlog::sink_ptr get() const override;
106 };
107
111 class LITEFX_LOGGING_API RollingFileSink : public ISink {
112 LITEFX_IMPLEMENTATION(RollingFileSinkImpl);
113
114 public:
123 RollingFileSink(const String& fileName, LogLevel level = LogLevel::Info, const String& pattern = "%+", bool truncate = false, int maxFiles = 0);
124 ~RollingFileSink() noexcept override;
125
127 RollingFileSink(RollingFileSink&&) noexcept = delete;
128 auto operator=(const RollingFileSink&) = delete;
129 auto operator=(RollingFileSink&&) noexcept = delete;
130
131 public:
133 LogLevel getLevel() const override;
134
136 String getName() const override;
137
139 String getPattern() const override;
140
145 virtual String getFileName() const;
146
151 virtual bool getTruncate() const;
152
157 virtual int getMaxFiles() const;
158
159 protected:
160 spdlog::sink_ptr get() const override;
161 };
162
170 class LITEFX_LOGGING_API TerminationSink : public ISink {
171 LITEFX_IMPLEMENTATION(TerminationSinkImpl);
172
173 public:
177 static constexpr std::uint32_t DEFAULT_TERMINATION_STATUS = 0xFF455252;
178
179 public:
185 TerminationSink(const LogLevel& level = LogLevel::Info, int status = static_cast<int>(DEFAULT_TERMINATION_STATUS));
186 ~TerminationSink() noexcept override;
187
189 TerminationSink(TerminationSink&&) noexcept = delete;
190 auto operator=(const TerminationSink&) = delete;
191 auto operator=(TerminationSink&&) noexcept = delete;
192
193 public:
195 LogLevel getLevel() const override;
196
198 String getName() const override;
199
201 String getPattern() const override;
202
203 protected:
204 spdlog::sink_ptr get() const override;
205 };
206
214 class LITEFX_LOGGING_API Log {
215 LITEFX_IMPLEMENTATION(LogImpl);
216
217 public:
222 Log(const String& name);
223 virtual ~Log() noexcept;
224
225 Log(Log&&) noexcept = delete;
226 Log(const Log&) = delete;
227 auto operator=(Log&&) noexcept = delete;
228 auto operator=(const Log&) = delete;
229
230 public:
234 virtual const String& getName() const noexcept;
235
236 protected:
237 virtual void log(LogLevel level, StringView message);
238
239 public:
245 template<typename ...TArgs>
246 inline void log(LogLevel level, std::format_string<TArgs...> format, TArgs&&... args) {
247 this->log(level, std::format(format, std::forward<TArgs>(args)...));
248 }
249
254 template<typename ...TArgs>
255 inline void trace([[maybe_unused]] std::format_string<TArgs...> format, [[maybe_unused]] TArgs&&... args) {
256#ifndef NDEBUG
257 this->log(LogLevel::Trace, format, std::forward<TArgs>(args)...);
258#endif
259 }
260
265 template<typename ...TArgs>
266 inline void debug([[maybe_unused]] std::format_string<TArgs...> format, [[maybe_unused]] TArgs&&... args) {
267#ifndef NDEBUG
268 this->log(LogLevel::Debug, format, std::forward<TArgs>(args)...);
269#endif
270 }
271
276 template<typename ...TArgs>
277 inline void info(std::format_string<TArgs...> format, TArgs&&... args) {
278 this->log(LogLevel::Info, format, std::forward<TArgs>(args)...);
279 }
280
285 template<typename ...TArgs>
286 inline void warning(std::format_string<TArgs...> format, TArgs&&... args) {
287 this->log(LogLevel::Warning, format, std::forward<TArgs>(args)...);
288 }
289
294 template<typename ...TArgs>
295 inline void error(std::format_string<TArgs...> format, TArgs&&... args) {
296 this->log(LogLevel::Error, format, std::forward<TArgs>(args)...);
297 }
298
303 template<typename ...TArgs>
304 inline void fatal(std::format_string<TArgs...> format, TArgs&&... args) {
305 this->log(LogLevel::Fatal, format, std::forward<TArgs>(args)...);
306 }
307 };
308
312 class LITEFX_LOGGING_API Logger {
313 private:
314 Logger() noexcept;
315
316 public:
317 virtual ~Logger() noexcept;
318
319 Logger(Logger&&) noexcept = delete;
320 Logger(const Logger&) = delete;
321 auto operator=(const Logger&) = delete;
322 auto operator=(Logger&&) noexcept = delete;
323
324 // TODO: Cache logs by name and return them, instead of re-creating them with each call.
325 public:
331 static Log get(StringView name);
332
338 static void sinkTo(const ISink* sink);
339 };
340
341}
342
343// NOLINTBEGIN(cppcoreguidelines-macro-usage)
344
345#ifndef NDEBUG
346#define LITEFX_TRACE(log, format, ...) LiteFX::Logging::Logger::get(log).trace(format, ##__VA_ARGS__)
347#define LITEFX_DEBUG(log, format, ...) LiteFX::Logging::Logger::get(log).debug(format, ##__VA_ARGS__)
348#else
349#define LITEFX_TRACE(log, format, ...)
350#define LITEFX_DEBUG(log, format, ...)
351#endif
352
353#define LITEFX_INFO(log, format, ...) LiteFX::Logging::Logger::get(log).info(format, ##__VA_ARGS__)
354#define LITEFX_WARNING(log, format, ...) LiteFX::Logging::Logger::get(log).warning(format, ##__VA_ARGS__)
355#define LITEFX_ERROR(log, format, ...) LiteFX::Logging::Logger::get(log).error(format, ##__VA_ARGS__)
356#define LITEFX_FATAL_ERROR(log, format, ...) LiteFX::Logging::Logger::get(log).fatal(format, ##__VA_ARGS__)
357
358// NOLINTEND(cppcoreguidelines-macro-usage)
Writes log messages to the console.
Definition logging.hpp:77
~ConsoleSink() noexcept override
Interface for a class that receives log messages.
Definition logging.hpp:43
ISink() noexcept=default
A log to which messages are written to.
Definition logging.hpp:214
void debug(std::format_string< TArgs... > format, TArgs &&... args)
Logs a debug message with format .
Definition logging.hpp:266
void trace(std::format_string< TArgs... > format, TArgs &&... args)
Logs a trace message with format .
Definition logging.hpp:255
void error(std::format_string< TArgs... > format, TArgs &&... args)
Logs an error message with format .
Definition logging.hpp:295
void fatal(std::format_string< TArgs... > format, TArgs &&... args)
Logs a fatal error message with format .
Definition logging.hpp:304
virtual ~Log() noexcept
void warning(std::format_string< TArgs... > format, TArgs &&... args)
Logs a warning message with format .
Definition logging.hpp:286
void info(std::format_string< TArgs... > format, TArgs &&... args)
Logs an info message with format .
Definition logging.hpp:277
A provider for Log instances.
Definition logging.hpp:312
virtual ~Logger() noexcept
Writes log messages to a rolling file.
Definition logging.hpp:111
~RollingFileSink() noexcept override
Forcefully terminates the application, if a log message of a certain level or higher is output.
Definition logging.hpp:170
~TerminationSink() noexcept override
Definition logger.cpp:10
Definition logging.hpp:23
LogLevel
Defines the various log levels.
Definition logging.hpp:29
Definition app.hpp:6
std::string String
Definition string.hpp:24
std::string_view StringView
Definition string.hpp:26