| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- #ifndef AV_BASE_LOGGER_H
- #define AV_BASE_LOGGER_H
- #include <string>
- #include <memory>
- #include <mutex>
- #include <fstream>
- #include <sstream>
- #include <chrono>
- #include <iomanip>
- #include <vector>
- // 前向声明Qt类型,避免在头文件中包含Qt
- class QString;
- namespace av {
- // 日志级别枚举
- 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;
- };
- // Qt输出(用于兼容现有Qt日志系统)
- class QtOutput : public LogOutput {
- public:
- void write(LogLevel level, const std::string& message) override;
- };
- // 主日志类
- 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)...));
- }
- }
-
- // Qt兼容接口
- void qtDebug(const QString& message);
- void qtInfo(const QString& message);
- void qtWarning(const QString& message);
- void qtError(const QString& message);
-
- // 初始化方法(全局初始化时调用)
- 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 av
- // 便捷宏定义(重命名以避免与FFmpeg宏冲突)
- #define AV_LOGGER_DEBUG(msg) av::Logger::instance().debug(msg)
- #define AV_LOGGER_INFO(msg) av::Logger::instance().info(msg)
- #define AV_LOGGER_WARNING(msg) av::Logger::instance().warning(msg)
- #define AV_LOGGER_ERROR(msg) av::Logger::instance().error(msg)
- #define AV_LOGGER_DEBUGF(fmt, ...) av::Logger::instance().debugf(fmt, __VA_ARGS__)
- #define AV_LOGGER_INFOF(fmt, ...) av::Logger::instance().infof(fmt, __VA_ARGS__)
- #define AV_LOGGER_WARNINGF(fmt, ...) av::Logger::instance().warningf(fmt, __VA_ARGS__)
- #define AV_LOGGER_ERRORF(fmt, ...) av::Logger::instance().errorf(fmt, __VA_ARGS__)
- // Qt兼容宏(用于逐步替换现有代码)
- #define AV_QDEBUG(msg) av::Logger::instance().qtDebug(msg)
- #define AV_QINFO(msg) av::Logger::instance().qtInfo(msg)
- #define AV_QWARNING(msg) av::Logger::instance().qtWarning(msg)
- #define AV_QERROR(msg) av::Logger::instance().qtError(msg)
- #endif // AV_BASE_LOGGER_H
|