logger.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #ifndef AV_BASE_LOGGER_H
  2. #define AV_BASE_LOGGER_H
  3. #include <chrono>
  4. #include <fstream>
  5. #include <iomanip>
  6. #include <memory>
  7. #include <mutex>
  8. #include <sstream>
  9. #include <string>
  10. #include <vector>
  11. // 前向声明Qt类型,避免在头文件中包含Qt
  12. class QString;
  13. namespace av {
  14. // 日志级别枚举
  15. enum class LogLevel { DEBUG = 0, INFO = 1, WARNING = 2, ERROR = 3 };
  16. // 日志输出接口
  17. class LogOutput
  18. {
  19. public:
  20. virtual ~LogOutput() = default;
  21. virtual void write(LogLevel level, const std::string& message) = 0;
  22. };
  23. // 控制台输出
  24. class ConsoleOutput : public LogOutput
  25. {
  26. public:
  27. void write(LogLevel level, const std::string& message) override;
  28. };
  29. // 文件输出
  30. class FileOutput : public LogOutput
  31. {
  32. public:
  33. explicit FileOutput(const std::string& filename);
  34. ~FileOutput();
  35. void write(LogLevel level, const std::string& message) override;
  36. private:
  37. std::ofstream m_file;
  38. std::mutex m_mutex;
  39. };
  40. // Qt输出(用于兼容现有Qt日志系统)
  41. class QtOutput : public LogOutput
  42. {
  43. public:
  44. void write(LogLevel level, const std::string& message) override;
  45. };
  46. // 主日志类
  47. class Logger
  48. {
  49. public:
  50. static Logger& instance();
  51. // 设置日志级别
  52. void setLevel(LogLevel level);
  53. LogLevel getLevel() const;
  54. // 添加输出目标
  55. void addOutput(std::unique_ptr<LogOutput> output);
  56. void clearOutputs();
  57. // 日志记录方法
  58. void debug(const std::string& message);
  59. void info(const std::string& message);
  60. void warning(const std::string& message);
  61. void error(const std::string& message);
  62. // 格式化日志记录
  63. template<typename... Args>
  64. void debugf(const std::string& format, Args&&... args)
  65. {
  66. if (shouldLog(LogLevel::DEBUG)) {
  67. log(LogLevel::DEBUG, formatString(format, std::forward<Args>(args)...));
  68. }
  69. }
  70. template<typename... Args>
  71. void infof(const std::string& format, Args&&... args)
  72. {
  73. if (shouldLog(LogLevel::INFO)) {
  74. log(LogLevel::INFO, formatString(format, std::forward<Args>(args)...));
  75. }
  76. }
  77. template<typename... Args>
  78. void warningf(const std::string& format, Args&&... args)
  79. {
  80. if (shouldLog(LogLevel::WARNING)) {
  81. log(LogLevel::WARNING, formatString(format, std::forward<Args>(args)...));
  82. }
  83. }
  84. template<typename... Args>
  85. void errorf(const std::string& format, Args&&... args)
  86. {
  87. if (shouldLog(LogLevel::ERROR)) {
  88. log(LogLevel::ERROR, formatString(format, std::forward<Args>(args)...));
  89. }
  90. }
  91. #ifdef QT_CORE_LIB
  92. // Qt兼容接口
  93. void qtDebug(const QString& message);
  94. void qtInfo(const QString& message);
  95. void qtWarning(const QString& message);
  96. void qtError(const QString& message);
  97. #endif
  98. // 初始化方法(全局初始化时调用)
  99. static void initialize(const std::string& logFile = "av_log.txt",
  100. LogLevel level = LogLevel::INFO,
  101. bool enableConsole = true,
  102. bool enableQt = true);
  103. private:
  104. Logger() = default;
  105. ~Logger() = default;
  106. Logger(const Logger&) = delete;
  107. Logger& operator=(const Logger&) = delete;
  108. void log(LogLevel level, const std::string& message);
  109. bool shouldLog(LogLevel level) const;
  110. std::string getCurrentTime() const;
  111. std::string levelToString(LogLevel level) const;
  112. template<typename... Args>
  113. std::string formatString(const std::string& format, Args&&... args)
  114. {
  115. std::ostringstream oss;
  116. formatImpl(oss, format, std::forward<Args>(args)...);
  117. return oss.str();
  118. }
  119. // 处理无参数情况的formatImpl重载
  120. void formatImpl(std::ostringstream& oss, const std::string& format) { oss << format; }
  121. template<typename T>
  122. void formatImpl(std::ostringstream& oss, const std::string& format, T&& value)
  123. {
  124. size_t pos = format.find("{}");
  125. if (pos != std::string::npos) {
  126. oss << format.substr(0, pos) << std::forward<T>(value) << format.substr(pos + 2);
  127. } else {
  128. oss << format;
  129. }
  130. }
  131. template<typename T, typename... Args>
  132. void formatImpl(std::ostringstream& oss, const std::string& format, T&& value, Args&&... args)
  133. {
  134. size_t pos = format.find("{}");
  135. if (pos != std::string::npos) {
  136. oss << format.substr(0, pos) << std::forward<T>(value);
  137. formatImpl(oss, format.substr(pos + 2), std::forward<Args>(args)...);
  138. } else {
  139. oss << format;
  140. }
  141. }
  142. LogLevel m_level = LogLevel::INFO;
  143. std::vector<std::unique_ptr<LogOutput>> m_outputs;
  144. mutable std::mutex m_mutex;
  145. };
  146. } // namespace av
  147. // 便捷宏定义(重命名以避免与FFmpeg宏冲突)
  148. #define AV_LOGGER_DEBUG(msg) av::Logger::instance().debug(msg)
  149. #define AV_LOGGER_INFO(msg) av::Logger::instance().info(msg)
  150. #define AV_LOGGER_WARNING(msg) av::Logger::instance().warning(msg)
  151. #define AV_LOGGER_ERROR(msg) av::Logger::instance().error(msg)
  152. #define AV_LOGGER_DEBUGF(fmt, ...) av::Logger::instance().debugf(fmt, __VA_ARGS__)
  153. #define AV_LOGGER_INFOF(fmt, ...) av::Logger::instance().infof(fmt, __VA_ARGS__)
  154. #define AV_LOGGER_WARNINGF(fmt, ...) av::Logger::instance().warningf(fmt, __VA_ARGS__)
  155. #define AV_LOGGER_ERRORF(fmt, ...) av::Logger::instance().errorf(fmt, __VA_ARGS__)
  156. // Qt兼容宏(用于逐步替换现有代码)
  157. #define AV_QDEBUG(msg) av::Logger::instance().qtDebug(msg)
  158. #define AV_QINFO(msg) av::Logger::instance().qtInfo(msg)
  159. #define AV_QWARNING(msg) av::Logger::instance().qtWarning(msg)
  160. #define AV_QERROR(msg) av::Logger::instance().qtError(msg)
  161. #endif // AV_BASE_LOGGER_H