log.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | #ifndef LOG_H #define LOG_H #include <iostream> #include <fstream> #include <sstream> #include <string> #include <chrono> #include <iomanip> #include <mutex> // 定义日志级别 enum class LogLevel { DEBUG, INFO, WARNING, ERROR }; // 将日志级别转换为字符串 const char *logLevelToString(LogLevel level); // 获取当前时间的字符串表示 std::string getCurrentTime(); // 日志类 class Logger { public: // 构造函数 Logger(const std::string &filename, LogLevel minLevel = LogLevel::INFO) : minLogLevel(minLevel) { logFile.open(filename, std::ios::out | std::ios::app); if (!logFile.is_open()) { std::cerr << "Failed to open log file: " << filename << std::endl; } } // 析构函数 ~Logger() { if (logFile.is_open()) { logFile.close(); } } // 设置最小日志级别 void setMinLogLevel(LogLevel level) { minLogLevel = level; } // 打印日志 template <typename... Args> void log(LogLevel level, const char *file, int line, const char *format, Args... args) { std::lock_guard<std::mutex> lock(mutex); if (level >= minLogLevel) { std::stringstream ss; ss << "[" << getCurrentTime() << "] [" << logLevelToString(level) << "] [" << file << ":" << line << "] "; (ss << ... << args); std::string logMessage = ss.str(); std::cout << logMessage << std::endl; if (logFile.is_open()) { logFile << logMessage << std::endl; } } } private: std::ofstream logFile; LogLevel minLogLevel; std::mutex mutex; }; // 全局 logger 对象 static Logger g_logger("app.log", LogLevel::DEBUG); // 辅助宏,用于处理可变参数列表 #define LOG_HELPER(level, ...) g_logger.log(level, __FILE__, __LINE__, "%s", ##__VA_ARGS__) // 使用宏定义简化日志调用 #define LOG_DEBUG(...) LOG_HELPER(LogLevel::DEBUG, ##__VA_ARGS__) #define LOG_INFO(...) LOG_HELPER(LogLevel::INFO, ##__VA_ARGS__) #define LOG_WARNING(...) LOG_HELPER(LogLevel::WARNING, ##__VA_ARGS__) #define LOG_ERROR(...) LOG_HELPER(LogLevel::ERROR, ##__VA_ARGS__) #endif |
父主题: 用例源码