logger.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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. // Qt兼容接口
  88. void qtDebug(const QString& message);
  89. void qtInfo(const QString& message);
  90. void qtWarning(const QString& message);
  91. void qtError(const QString& message);
  92. // 初始化方法(全局初始化时调用)
  93. static void initialize(const std::string& logFile = "av_log.txt",
  94. LogLevel level = LogLevel::INFO,
  95. bool enableConsole = true,
  96. bool enableQt = true);
  97. private:
  98. Logger() = default;
  99. ~Logger() = default;
  100. Logger(const Logger&) = delete;
  101. Logger& operator=(const Logger&) = delete;
  102. void log(LogLevel level, const std::string& message);
  103. bool shouldLog(LogLevel level) const;
  104. std::string getCurrentTime() const;
  105. std::string levelToString(LogLevel level) const;
  106. template<typename... Args>
  107. std::string formatString(const std::string& format, Args&&... args) {
  108. std::ostringstream oss;
  109. formatImpl(oss, format, std::forward<Args>(args)...);
  110. return oss.str();
  111. }
  112. // 处理无参数情况的formatImpl重载
  113. void formatImpl(std::ostringstream& oss, const std::string& format) {
  114. oss << format;
  115. }
  116. template<typename T>
  117. void formatImpl(std::ostringstream& oss, const std::string& format, T&& value) {
  118. size_t pos = format.find("{}");
  119. if (pos != std::string::npos) {
  120. oss << format.substr(0, pos) << std::forward<T>(value) << format.substr(pos + 2);
  121. } else {
  122. oss << format;
  123. }
  124. }
  125. template<typename T, typename... Args>
  126. void formatImpl(std::ostringstream& oss, const std::string& format, T&& value, Args&&... args) {
  127. size_t pos = format.find("{}");
  128. if (pos != std::string::npos) {
  129. oss << format.substr(0, pos) << std::forward<T>(value);
  130. formatImpl(oss, format.substr(pos + 2), std::forward<Args>(args)...);
  131. } else {
  132. oss << format;
  133. }
  134. }
  135. LogLevel m_level = LogLevel::INFO;
  136. std::vector<std::unique_ptr<LogOutput>> m_outputs;
  137. mutable std::mutex m_mutex;
  138. };
  139. } // namespace av
  140. // 便捷宏定义(重命名以避免与FFmpeg宏冲突)
  141. #define AV_LOGGER_DEBUG(msg) av::Logger::instance().debug(msg)
  142. #define AV_LOGGER_INFO(msg) av::Logger::instance().info(msg)
  143. #define AV_LOGGER_WARNING(msg) av::Logger::instance().warning(msg)
  144. #define AV_LOGGER_ERROR(msg) av::Logger::instance().error(msg)
  145. #define AV_LOGGER_DEBUGF(fmt, ...) av::Logger::instance().debugf(fmt, __VA_ARGS__)
  146. #define AV_LOGGER_INFOF(fmt, ...) av::Logger::instance().infof(fmt, __VA_ARGS__)
  147. #define AV_LOGGER_WARNINGF(fmt, ...) av::Logger::instance().warningf(fmt, __VA_ARGS__)
  148. #define AV_LOGGER_ERRORF(fmt, ...) av::Logger::instance().errorf(fmt, __VA_ARGS__)
  149. // Qt兼容宏(用于逐步替换现有代码)
  150. #define AV_QDEBUG(msg) av::Logger::instance().qtDebug(msg)
  151. #define AV_QINFO(msg) av::Logger::instance().qtInfo(msg)
  152. #define AV_QWARNING(msg) av::Logger::instance().qtWarning(msg)
  153. #define AV_QERROR(msg) av::Logger::instance().qtError(msg)
  154. #endif // AV_BASE_LOGGER_H