From 616fb227257029c4f7f5c00120afd24c56528517 Mon Sep 17 00:00:00 2001 From: hachem Date: Wed, 13 Aug 2025 19:25:30 +0200 Subject: [add]: Logging system --- src/Core/Log.h | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 src/Core/Log.h (limited to 'src/Core/Log.h') diff --git a/src/Core/Log.h b/src/Core/Log.h new file mode 100644 index 0000000..ad1b959 --- /dev/null +++ b/src/Core/Log.h @@ -0,0 +1,154 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Donut +{ + enum class LogLevel + { + TRACE = 0, + INFO = 2, + WARN = 3, + ERR = 4, + FATAL = 5 + }; + + class Logger + { + public: + static void Init(); + static void Shutdown(); + + static std::shared_ptr GetLogger(); + + template + static void Trace(const std::string_view& format, const Args&... args) + { + auto logger = GetLogger(); + if (logger) logger->LogMessage(LogLevel::TRACE, format, args...); + } + + template + static void Info(const std::string_view& format, const Args&... args) + { + auto logger = GetLogger(); + if (logger) logger->LogMessage(LogLevel::INFO, format, args...); + } + + template + static void Warn(const std::string_view& format, const Args&... args) + { + auto logger = GetLogger(); + if (logger) logger->LogMessage(LogLevel::WARN, format, args...); + } + + template + static void Error(const std::string_view& format, const Args&... args) + { + auto logger = GetLogger(); + if (logger) logger->LogMessage(LogLevel::ERR, format, args...); + } + + template + static void Fatal(const std::string_view& format, const Args&... args) + { + auto logger = GetLogger(); + if (logger) logger->LogMessage(LogLevel::FATAL, format, args...); + } + + template + void LogMessage(LogLevel level, const std::string_view& format, const Args&... args) + { + if (level < m_LogLevel) + return; + + std::lock_guard lock(m_Mutex); + std::string message = FormatString(format, args...); + std::string fullMessage = GetTimeStamp() + " [" + GetLogLevelString(level) + "] " + message; + + if (m_ConsoleOutput) + { + SetConsoleColor(level); + std::cout << fullMessage << std::endl; + ResetConsoleColor(); + } + + if (m_FileOutput && m_LogFile.is_open()) + { + m_LogFile << fullMessage << std::endl; + m_LogFile.flush(); + } + } + + template + std::string FormatString(const std::string_view& format, const Args&... args) + { + std::string result = format.data(); + std::vector argStrings = { ToString(args)... }; + + size_t argIndex = 0; + size_t pos = 0; + + while ((pos = result.find("{}", pos)) != std::string::npos && argIndex < argStrings.size()) + { + result.replace(pos, 2, argStrings[argIndex]); + pos += argStrings[argIndex].length(); + argIndex++; + } + + return result; + } + + template + std::string ToString(const T& value) + { + std::stringstream ss; + ss << value; + return ss.str(); + } + + void SetLogLevel(LogLevel level) { m_LogLevel = level; } + void EnableConsoleOutput(bool enable) { m_ConsoleOutput = enable; } + void EnableFileOutput(bool enable) { m_FileOutput = enable; } + void SetLogFile(const std::string& filename); + public: + Logger(); + ~Logger(); + + std::string GetTimeStamp(); + std::string GetLogLevelString(LogLevel level); + void SetConsoleColor(LogLevel level); + void ResetConsoleColor(); + private: + LogLevel m_LogLevel; + bool m_ConsoleOutput; + bool m_FileOutput; + std::ofstream m_LogFile; + std::mutex m_Mutex; + + static std::shared_ptr s_Logger; + }; +} + +#if defined(DONUT_DEBUG) + #define DONUT_TRACE(format, ...) ::Donut::Logger::Trace(format, ##__VA_ARGS__) + #define DONUT_INFO(format, ...) ::Donut::Logger::Info(format, ##__VA_ARGS__) + #define DONUT_WARN(format, ...) ::Donut::Logger::Warn(format, ##__VA_ARGS__) + #define DONUT_ERROR(format, ...) ::Donut::Logger::Error(format, ##__VA_ARGS__) + #define DONUT_FATAL(format, ...) ::Donut::Logger::Fatal(format, ##__VA_ARGS__) +#else + #define DONUT_TRACE(format, ...) {} + #define DONUT_INFO(format, ...) {} + #define DONUT_WARN(format, ...) {} + #define DONUT_ERROR(format, ...) {} + #define DONUT_FATAL(format, ...) {} +#endif \ No newline at end of file -- cgit v1.3