#include "XNLogger.h" XNLogger::XNLogger() : consoleOutputEnabled{true, true, true, true}, fileOutputEnabled{true, true, true, true} { // 获取当前工作目录 std::filesystem::path currentDir = std::filesystem::current_path(); std::filesystem::path logDirPath = currentDir / "log"; // 创建 log 文件夹 if (!std::filesystem::exists(logDirPath)) { std::filesystem::create_directories(logDirPath); } // 创建以当前日期和时间命名的日志文件 auto now = std::chrono::system_clock::now(); auto time = std::chrono::system_clock::to_time_t(now); std::stringstream ss; ss << std::put_time(std::localtime(&time), "%Y%m%d_%H%M%S"); std::string logFileName = "log_" + ss.str() + ".log"; logFilePath = (logDirPath / logFileName).string(); logFile.open(logFilePath, std::ios::app); } XNLogger::~XNLogger() { if (logFile.is_open()) { logFile.close(); } } std::string XNLogger::getCurrentTimeString() const { auto now = std::chrono::system_clock::now(); auto time = std::chrono::system_clock::to_time_t(now); auto ms = std::chrono::duration_cast(now.time_since_epoch()) % 1000; std::stringstream ss; ss << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S"); ss << '.' << std::setfill('0') << std::setw(3) << ms.count(); return ss.str(); } void XNLogger::log(LogLevel level, const std::string &message) { std::lock_guard locker(mutex); std::string logMessage = "[" + getCurrentTimeString() + "] [" + logLevelToString(level) + "] " + message; std::string coloredMessage; // 根据日志等级设置颜色 switch (level) { case Debug: coloredMessage = COLOR_DEBUG + logMessage + COLOR_RESET; break; case Info: coloredMessage = COLOR_INFO + logMessage + COLOR_RESET; break; case Warning: coloredMessage = COLOR_WARNING + logMessage + COLOR_RESET; break; case Error: coloredMessage = COLOR_ERROR + logMessage + COLOR_RESET; break; default: coloredMessage = logMessage; // 默认无颜色 break; } // 控制台输出 if (consoleOutputEnabled[level]) { if (level == Time) { // 如果是时间日志,则不换行,回退到该行开始 std::cout << coloredMessage << "\r" << std::flush; } else { std::cout << coloredMessage << std::endl; } } // 文件输出 if (fileOutputEnabled[level] && logFile.is_open()) { if (level == Time) { logFile << logMessage << "\r" << std::flush; } else { logFile << logMessage << std::endl; } } } void XNLogger::enableConsoleOutput(LogLevel level, bool enable) { consoleOutputEnabled[level] = enable; } void XNLogger::enableFileOutput(LogLevel level, bool enable) { fileOutputEnabled[level] = enable; } std::string XNLogger::logLevelToString(LogLevel level) const { switch (level) { case Debug: return "DEBUG"; case Info: return "INFO"; case Warning: return "WARNING"; case Error: return "ERROR"; case Time: return "TIME"; default: return "UNKNOWN"; } }