#pragma once #include #include #include #include #include #include #include #ifdef _WIN32 #include #else #include #include #include #endif enum LogLevel { LOG_INFO, LOG_WARNING, LOG_ERROR }; class CustomLogger { public: static CustomLogger& getInstance() { static CustomLogger instance; return instance; } bool initialize(const std::string& logDir = "logs") { std::lock_guard lock(LogMutex_); // 创建日志目录 if (!createDirectory(logDir)) { std::cerr << "Failed to create log directory: " << logDir << std::endl; return false; } // 生成基于时间的日志文件名 auto now = std::chrono::system_clock::now(); auto time_t = std::chrono::system_clock::to_time_t(now); std::tm tm; #ifdef _WIN32 localtime_s(&tm, &time_t); #else localtime_r(&time_t, &tm); #endif std::ostringstream filename; filename << logDir << "/log_" << std::setfill('0') << std::setw(4) << (tm.tm_year + 1900) << std::setw(2) << (tm.tm_mon + 1) << std::setw(2) << tm.tm_mday << "_" << std::setw(2) << tm.tm_hour << std::setw(2) << tm.tm_min << std::setw(2) << tm.tm_sec << ".log"; logFile_.open(filename.str(), std::ios::out | std::ios::app); if (!logFile_.is_open()) { std::cerr << "Failed to open log file: " << filename.str() << std::endl; return false; } //log(LOG_INFO, "Logger initialized successfully"); return true; } void log(LogLevel level, const std::string& message) { std::lock_guard lock(LogMutex_); std::cout << message << std::endl; return; if (!logFile_.is_open()) return; auto now = std::chrono::system_clock::now(); auto time_t = std::chrono::system_clock::to_time_t(now); std::tm tm; #ifdef _WIN32 localtime_s(&tm, &time_t); #else localtime_r(&time_t, &tm); #endif const char* levelStr = ""; switch (level) { case LOG_INFO: levelStr = "INFO"; break; case LOG_WARNING: levelStr = "WARNING"; break; case LOG_ERROR: levelStr = "ERROR"; break; } logFile_ << "[" << std::put_time(&tm, "%Y-%m-%d %H:%M:%S") << "] " << "[" << levelStr << "] " << message << std::endl; // 同时输出到控制台 logFile_.flush(); } void shutdown() { std::lock_guard lock(LogMutex_); if (logFile_.is_open()) { log(LOG_INFO, "Logger shutdown"); logFile_.close(); } } private: CustomLogger() = default; ~CustomLogger() { shutdown(); } CustomLogger(const CustomLogger&) = delete; CustomLogger& operator=(const CustomLogger&) = delete; bool createDirectory(const std::string& path) { #ifdef _WIN32 return CreateDirectoryA(path.c_str(), NULL) != 0 || GetLastError() == ERROR_ALREADY_EXISTS; #else return mkdir(path.c_str(), 0755) == 0 || errno == EEXIST; #endif } std::ofstream logFile_; std::mutex LogMutex_; }; // 宏定义简化日志调用 #define LOG_INFO(msg) CustomLogger::getInstance().log(LOG_INFO, msg) #define LOG_WARNING(msg) CustomLogger::getInstance().log(LOG_WARNING, msg) #define LOG_ERROR(msg) CustomLogger::getInstance().log(LOG_ERROR, msg)