| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- #ifndef TLOGGER_H
- #define TLOGGER_H
- #include <fstream>
- #include <memory>
- #include <mutex>
- #include <sstream>
- #include <string>
- #include <vector>
- // 前向声明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<LogOutput> 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<typename... Args>
- void debugf(const std::string& format, Args&&... args)
- {
- if (shouldLog(LogLevel::DEBUG)) {
- log(LogLevel::DEBUG, formatString(format, std::forward<Args>(args)...));
- }
- }
- template<typename... Args>
- void infof(const std::string& format, Args&&... args)
- {
- if (shouldLog(LogLevel::INFO)) {
- log(LogLevel::INFO, formatString(format, std::forward<Args>(args)...));
- }
- }
- template<typename... Args>
- void warningf(const std::string& format, Args&&... args)
- {
- if (shouldLog(LogLevel::WARNING)) {
- log(LogLevel::WARNING, formatString(format, std::forward<Args>(args)...));
- }
- }
- template<typename... Args>
- void errorf(const std::string& format, Args&&... args)
- {
- if (shouldLog(LogLevel::ERROR)) {
- log(LogLevel::ERROR, formatString(format, std::forward<Args>(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<typename... Args>
- std::string formatString(const std::string& format, Args&&... args)
- {
- std::ostringstream oss;
- formatImpl(oss, format, std::forward<Args>(args)...);
- return oss.str();
- }
- // 处理无参数情况的formatImpl重载
- void formatImpl(std::ostringstream& oss, const std::string& format) { oss << format; }
- template<typename T>
- 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<T>(value) << format.substr(pos + 2);
- } else {
- oss << format;
- }
- }
- template<typename T, typename... Args>
- 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<T>(value);
- formatImpl(oss, format.substr(pos + 2), std::forward<Args>(args)...);
- } else {
- oss << format;
- }
- }
- LogLevel m_level = LogLevel::INFO;
- std::vector<std::unique_ptr<LogOutput>> 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
|