diff options
| author | hachem <im@hachem.wtf> | 2025-08-13 19:25:30 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2025-08-13 19:25:30 +0200 |
| commit | 1ac0f136629ce4046a5f6529cf3d1e51e96df408 (patch) | |
| tree | ea42cf71c3a7760d1454f90dca36147d353a3581 /src/core/log.cpp | |
| parent | 23086a5d33acc66414f1169bf22abe78b3383f94 (diff) | |
feat: logging system
Diffstat (limited to 'src/core/log.cpp')
| -rw-r--r-- | src/core/log.cpp | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/src/core/log.cpp b/src/core/log.cpp new file mode 100644 index 0000000..ec031a5 --- /dev/null +++ b/src/core/log.cpp @@ -0,0 +1,155 @@ +#include "log.h" +#include <filesystem> + +#if defined(DONUT_WINDOWS) + #include <windows.h> +#endif + +namespace Donut +{ + std::shared_ptr<Logger> Logger::s_logger; + + void Logger::init() + { + s_logger = std::make_shared<Logger>(); + s_logger->set_log_level(LogLevel::Info); + s_logger->enable_console_output(true); + s_logger->enable_file_output(true); + s_logger->set_log_file("logs/donut.log"); + + s_logger->log_message(LogLevel::Info, "Logging system initialized"); + } + + void Logger::shutdown() + { + if (s_logger) + s_logger->log_message(LogLevel::Info, "Shutting down logging system"); + s_logger.reset(); + } + + std::shared_ptr<Logger> Logger::get_logger() + { + return s_logger; + } + + Logger::Logger() + : m_log_level(LogLevel::Info), + m_console_output(true), + m_file_output(false) { } + + Logger::~Logger() + { + if (m_log_file.is_open()) + m_log_file.close(); + } + + void Logger::set_log_file(const std::string& filename) + { + std::filesystem::path log_path(filename); + std::filesystem::create_directories(log_path.parent_path()); + + m_log_file.open(filename, std::ios::app); + if (!m_log_file.is_open()) + std::cerr << "Failed to open log file: " << filename << std::endl; + } + + std::string Logger::get_time_stamp() + { + auto now = std::chrono::system_clock::now(); + auto time_t = std::chrono::system_clock::to_time_t(now); + + std::stringstream ss; + ss << std::put_time(std::localtime(&time_t), "%Y-%m-%d %H:%M:%S"); + + return ss.str(); + } + + std::string Logger::get_log_level_string(LogLevel level) + { + switch (level) + { + case LogLevel::trace: return "TRACE"; + case LogLevel::Info: return "INFO"; + case LogLevel::Warn: return "WARN"; + case LogLevel::Err: return "ERROR"; + case LogLevel::Fatal: return "FATAL"; + default: return "UNKNOWN"; + } + } + + void Logger::set_console_color(LogLevel level) + { +#if defined(DONUT_WINDOWS) + HANDLE h_console = GetStdHandle(STD_OUTPUT_HANDLE); + WORD color; + + switch (level) { + case LogLevel::trace: + color = FOREGROUND_RED | + FOREGROUND_GREEN | + FOREGROUND_BLUE; + break; + case LogLevel::Info: + color = FOREGROUND_GREEN | + FOREGROUND_INTENSITY; + break; + case LogLevel::Warn: + color = FOREGROUND_RED | + FOREGROUND_GREEN | + FOREGROUND_INTENSITY; + break; + case LogLevel::Err: + color = FOREGROUND_RED | + FOREGROUND_INTENSITY; + break; + case LogLevel::Fatal: + color = FOREGROUND_RED | + FOREGROUND_BLUE | + FOREGROUND_INTENSITY; + break; + default: + color = FOREGROUND_RED | + FOREGROUND_GREEN | + FOREGROUND_BLUE; + break; + } + + SetConsoleTextAttribute(h_console, color); +#else + const char* color_code; + switch (level) { + case LogLevel::trace: + color_code = "\033[37m"; + break; + case LogLevel::Info: + color_code = "\033[32;1m"; + break; + case LogLevel::Warn: + color_code = "\033[33;1m"; + break; + case LogLevel::Err: + color_code = "\033[31;1m"; + break; + case LogLevel::Fatal: + color_code = "\033[35;1m"; + break; + default: + color_code = "\033[37m"; + break; + } + std::cout << color_code; +#endif + } + + void Logger::reset_console_color() + { +#if defined(DONUT_WINDOWS) + HANDLE h_console = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleTextAttribute(h_console, FOREGROUND_RED | + FOREGROUND_GREEN | + FOREGROUND_BLUE); +#else + std::cout << "\033[0m"; +#endif + } +} |
