#include "logger.hpp" std::ofstream Logger::log_file; std::string Logger::log_directory; std::string Logger::current_date; std::string Logger::current_filename; void Logger::init(const std::string& log_dir) { log_directory = log_dir; if (!std::filesystem::exists(log_directory)) std::filesystem::create_directories(log_directory); current_date = get_today_date(); open_log_file(); } void Logger::open_log_file() { current_filename = log_directory + "/" + current_date + ".log"; if (log_file.is_open()) log_file.close(); log_file.open(current_filename, std::ios::app); if (!log_file.is_open()) { std::cerr << "[Logger] Failed to open log file: " << current_filename << std::endl; } } void Logger::check_date_rollover() { std::string today = get_today_date(); if (today != current_date) { current_date = today; open_log_file(); } } std::string Logger::get_time_string() { using namespace std::chrono; auto now = system_clock::now(); auto ms = duration_cast(now.time_since_epoch()) % 1000; std::time_t t = system_clock::to_time_t(now); std::tm tm_now = *std::localtime(&t); std::ostringstream ss; ss << std::put_time(&tm_now, "%Y-%m-%d %H:%M:%S") << "." << std::setw(3) << std::setfill('0') << ms.count(); return ss.str(); } std::string Logger::get_today_date() { auto now = std::chrono::system_clock::now(); std::time_t t = std::chrono::system_clock::to_time_t(now); std::tm tm_now = *std::localtime(&t); std::ostringstream ss; ss << std::put_time(&tm_now, "%Y-%m-%d"); return ss.str(); } std::string Logger::get_current_time_utc8() { auto now = std::chrono::system_clock::now(); auto ms = std::chrono::duration_cast(now.time_since_epoch()) % 1000; std::time_t t = std::chrono::system_clock::to_time_t(now); std::tm tm_now = *std::localtime(&t); std::ostringstream ss; ss << std::put_time(&tm_now, "%Y%m%d%H%M%S") << std::setw(3) << std::setfill('0') << ms.count(); return ss.str(); } void Logger::log(LogLevel level, const std::string& msg) { check_date_rollover(); std::string level_str; switch (level) { case LogLevel::INFO: level_str = "[INFO] "; break; case LogLevel::WARN: level_str = "[WARN] "; break; case LogLevel::ERROR: level_str = "[ERROR]"; break; } std::string full_msg = get_time_string() + " " + level_str + " " + msg; std::cout << full_msg << std::endl; if (log_file.is_open()) { log_file << full_msg << std::endl; log_file.flush(); } }