LCOV - code coverage report
Current view: top level - include/base - logger.hpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 16 16
Test Date: 2025-12-19 03:13:09 Functions: 79.5 % 73 58

            Line data    Source code
       1              : /**
       2              :  * @file logger.hpp
       3              :  * @brief 线程安全的日志输出工具
       4              :  *
       5              :  * 提供简洁的流式日志接口,确保多线程环境下日志输出的完整性。
       6              :  */
       7              : 
       8              : #pragma once
       9              : 
      10              : #include <mutex>
      11              : #include <sstream>
      12              : #include <unistd.h>
      13              : 
      14              : namespace fix40 {
      15              : 
      16              : /**
      17              :  * @class Logger
      18              :  * @brief 线程安全的日志输出器(单例模式)
      19              :  *
      20              :  * 确保每条日志完整输出,不会被其他线程的输出打断。
      21              :  * 使用 POSIX write() 系统调用保证原子性写入。
      22              :  *
      23              :  * @par 使用示例
      24              :  * @code
      25              :  * LOG() << "Connection established, fd=" << fd;
      26              :  * LOG() << "Received message: " << msg;
      27              :  * @endcode
      28              :  *
      29              :  * @note 日志会自动在末尾添加换行符
      30              :  */
      31              : class Logger {
      32              : public:
      33              :     /**
      34              :      * @brief 获取 Logger 单例实例
      35              :      * @return Logger& 单例引用
      36              :      */
      37         4056 :     static Logger& instance() {
      38              :         static Logger logger;
      39         4056 :         return logger;
      40              :     }
      41              : 
      42              :     /**
      43              :      * @brief 启用或禁用日志输出
      44              :      * @param enabled true 启用,false 禁用
      45              :      */
      46              :     void setEnabled(bool enabled) {
      47              :         enabled_ = enabled;
      48              :     }
      49              : 
      50              :     /**
      51              :      * @brief 检查日志是否启用
      52              :      * @return bool 是否启用
      53              :      */
      54              :     bool isEnabled() const {
      55              :         return enabled_;
      56              :     }
      57              : 
      58              :     /**
      59              :      * @class LogStream
      60              :      * @brief 日志流对象,支持流式输出
      61              :      *
      62              :      * 该对象在析构时将缓冲区内容原子性地写入标准输出。
      63              :      * 通过 RAII 机制确保日志完整输出。
      64              :      */
      65              :     class LogStream {
      66              :     public:
      67              :         /**
      68              :          * @brief 构造日志流
      69              :          * @param mtx 用于保护输出的互斥锁引用
      70              :          * @param enabled 是否启用输出
      71              :          */
      72         4056 :         LogStream(std::mutex& mtx, bool enabled) : mtx_(mtx), enabled_(enabled) {}
      73              :         
      74              :         /**
      75              :          * @brief 析构时输出日志
      76              :          *
      77              :          * 自动添加换行符,并使用 write() 系统调用原子性写入。
      78              :          */
      79         8112 :         ~LogStream() {
      80         4056 :             if (!enabled_) return;
      81         4056 :             buffer_ << '\n';
      82         4056 :             std::string str = buffer_.str();
      83         4056 :             std::lock_guard<std::mutex> lock(mtx_);
      84              :             // 使用 write() 系统调用,单次调用是原子的
      85         4056 :             ::write(STDOUT_FILENO, str.c_str(), str.size());
      86         4056 :         }
      87              : 
      88              :         LogStream(const LogStream&) = delete;
      89              :         LogStream& operator=(const LogStream&) = delete;
      90              :         
      91              :         /**
      92              :          * @brief 移动构造函数
      93              :          * @param other 源对象
      94              :          */
      95              :         LogStream(LogStream&& other) noexcept 
      96              :             : mtx_(other.mtx_), enabled_(other.enabled_), buffer_(std::move(other.buffer_)) {}
      97              : 
      98              :         /**
      99              :          * @brief 流式输出操作符
     100              :          * @tparam T 值类型(需支持 ostream 输出)
     101              :          * @param value 要输出的值
     102              :          * @return LogStream& 返回自身以支持链式调用
     103              :          */
     104              :         template<typename T>
     105        11558 :         LogStream& operator<<(const T& value) {
     106        11558 :             if (enabled_) {
     107        11558 :                 buffer_ << value;
     108              :             }
     109        11558 :             return *this;
     110              :         }
     111              : 
     112              :     private:
     113              :         std::mutex& mtx_;           ///< 互斥锁引用
     114              :         bool enabled_;              ///< 是否启用输出
     115              :         std::ostringstream buffer_; ///< 日志缓冲区
     116              :     };
     117              : 
     118              :     /**
     119              :      * @brief 创建日志流对象
     120              :      * @return LogStream 日志流对象
     121              :      */
     122         4056 :     LogStream log() {
     123         4056 :         return LogStream(mutex_, enabled_);
     124              :     }
     125              : 
     126              : private:
     127              :     Logger() = default;
     128              :     std::mutex mutex_;          ///< 保护日志输出的互斥锁
     129              :     bool enabled_ = true;       ///< 日志开关
     130              : };
     131              : 
     132              : /**
     133              :  * @def LOG()
     134              :  * @brief 日志输出宏
     135              :  *
     136              :  * 使用方式:LOG() << "message" << value;
     137              :  */
     138              : #define LOG() fix40::Logger::instance().log()
     139              : 
     140              : } // namespace fix40
        

Generated by: LCOV version 2.0-1