#ifndef TLOGGER_H #define TLOGGER_H #include #include #include #include #include #include // 前向声明Qt类型,避免在头文件中包含Qt class QString; namespace TC { // 日志级别枚举 enum class LogLevel { DEBUG = 0, INFO = 1, WARNING = 2, ERROR = 3 }; // 日志输出接口 class LogOutput { public: virtual ~LogOutput() = default; virtual void write(LogLevel level, const std::string& message) = 0; }; // 控制台输出 class ConsoleOutput : public LogOutput { public: void write(LogLevel level, const std::string& message) override; }; // 文件输出 class FileOutput : public LogOutput { public: explicit FileOutput(const std::string& filename); ~FileOutput(); void write(LogLevel level, const std::string& message) override; private: std::ofstream m_file; std::mutex m_mutex; }; // 主日志类 class Logger { public: static Logger& instance(); // 设置日志级别 void setLevel(LogLevel level); LogLevel getLevel() const; // 添加输出目标 void addOutput(std::unique_ptr output); void clearOutputs(); // 日志记录方法 void debug(const std::string& message); void info(const std::string& message); void warning(const std::string& message); void error(const std::string& message); // 格式化日志记录 template void debugf(const std::string& format, Args&&... args) { if (shouldLog(LogLevel::DEBUG)) { log(LogLevel::DEBUG, formatString(format, std::forward(args)...)); } } template void infof(const std::string& format, Args&&... args) { if (shouldLog(LogLevel::INFO)) { log(LogLevel::INFO, formatString(format, std::forward(args)...)); } } template void warningf(const std::string& format, Args&&... args) { if (shouldLog(LogLevel::WARNING)) { log(LogLevel::WARNING, formatString(format, std::forward(args)...)); } } template void errorf(const std::string& format, Args&&... args) { if (shouldLog(LogLevel::ERROR)) { log(LogLevel::ERROR, formatString(format, std::forward(args)...)); } } #ifdef QT_CORE_LIB // Qt兼容接口 void qtDebug(const QString& message); void qtInfo(const QString& message); void qtWarning(const QString& message); void qtError(const QString& message); #endif // 初始化方法(全局初始化时调用) static void initialize(const std::string& logFile = "av_log.txt", LogLevel level = LogLevel::INFO, bool enableConsole = true, bool enableQt = true); private: Logger() = default; ~Logger() = default; Logger(const Logger&) = delete; Logger& operator=(const Logger&) = delete; void log(LogLevel level, const std::string& message); bool shouldLog(LogLevel level) const; std::string getCurrentTime() const; std::string levelToString(LogLevel level) const; template std::string formatString(const std::string& format, Args&&... args) { std::ostringstream oss; formatImpl(oss, format, std::forward(args)...); return oss.str(); } // 处理无参数情况的formatImpl重载 void formatImpl(std::ostringstream& oss, const std::string& format) { oss << format; } template void formatImpl(std::ostringstream& oss, const std::string& format, T&& value) { size_t pos = format.find("{}"); if (pos != std::string::npos) { oss << format.substr(0, pos) << std::forward(value) << format.substr(pos + 2); } else { oss << format; } } template void formatImpl(std::ostringstream& oss, const std::string& format, T&& value, Args&&... args) { size_t pos = format.find("{}"); if (pos != std::string::npos) { oss << format.substr(0, pos) << std::forward(value); formatImpl(oss, format.substr(pos + 2), std::forward(args)...); } else { oss << format; } } LogLevel m_level = LogLevel::INFO; std::vector> m_outputs; mutable std::mutex m_mutex; }; } // namespace TC #define T_LOGGER_DEBUG(msg) TC::Logger::instance().debug(msg) #define T_LOGGER_INFO(msg) TC::Logger::instance().info(msg) #define T_LOGGER_WARNING(msg) TC::Logger::instance().warning(msg) #define T_LOGGER_ERROR(msg) TC::Logger::instance().error(msg) #define T_LOGGER_DEBUGF(fmt, ...) TC::Logger::instance().debugf(fmt, __VA_ARGS__) #define T_LOGGER_INFOF(fmt, ...) TC::Logger::instance().infof(fmt, __VA_ARGS__) #define T_LOGGER_WARNINGF(fmt, ...) TC::Logger::instance().warningf(fmt, __VA_ARGS__) #define T_LOGGER_ERRORF(fmt, ...) TC::Logger::instance().errorf(fmt, __VA_ARGS__) #endif // TLOGGER_H