logger.h 5.6 KB

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