tlogger.h 5.0 KB

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