| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- #pragma once
- #include <iostream>
- #include <fstream>
- #include <string>
- #include <chrono>
- #include <iomanip>
- #include <sstream>
- #include <mutex>
- #ifdef _WIN32
- #include <windows.h>
- #else
- #include <unistd.h>
- #include <limits.h>
- #include <sys/stat.h>
- #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<std::mutex> 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<std::mutex> 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<std::mutex> 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)
|