• easylogging++学习记录(二):流式日志


    easylogging++日志库流式日志的写入,依赖于el::base::Writer类的析构,以debug日志为例:具体代码如下:

    #define LOG(LEVEL) CLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)
    #define CLOG(LEVEL, ...)
        C##LEVEL(el::base::Writer, el::base::DispatchAction::NormalLog, __VA_ARGS__)
    #if ELPP_DEBUG_LOG
    #   define CDEBUG(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Debug, dispatchAction, __VA_ARGS__)
    
    #define ELPP_WRITE_LOG(writer, level, dispatchAction, ...) 
        writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)

    宏替换之后就是调用了Writer类的一个构造函数和一个construct()成员函数,等同于下面代码:

    el::base::Writer(...).construct(...)

    单独调用一个构造函数的话,会产生一个临时对象,在语句结束后,这个临时对象会被析构,进而触发析构函数中的日志写入逻辑,可以通过下列代码进行验证:

      1 #include <iostream>
      2 #include <sstream>
      3 
      4 class A
      5 {
      6 public:
      7     A() { }
      8     
      9     ~A()
     10     {
     11         std::cout << m_ss.str() << std::endl;
     12     }   
     13     
     14     template<typename T>
     15     A& operator << (const T& t)
     16     {
     17         m_ss << t;
     18         return *this;
     19     }   
     20     
     21 private:
     22     std::ostringstream m_ss;
     23 };  
     24 
     25 #define SLOG() LOG(A)
     26 
     27 #define LOG(a) 
     28     a()
     29 
     30 class B
     31 {
     32 public:
     33     B() {}
     34     ~B()
     35     {
     36         std::cout << "~B()" << std::endl;
     37     }   
     38 };  
     39 
     40 int main()
     41 {
     42     std::cout << ".........begin........." << std::endl;
     43     SLOG() << "first....";
     44     B();
     45     std::cout << "..........middle......." << std::endl;
     46     B b;
     47     b = B();
     48     std::cout << ".........end.........." << std::endl;
     49     return 0;
     50 }

    以上代码编译输出结果如下:

    $ g++ macro.cpp -o main
    $ ./main 
    .........begin.........
    first....
    ~B()
    ..........middle.......
    ~B()
    .........end..........
    ~B()

    begin和middle之间两次单独调用构造函数的地方产生的临时对象,都在语句结束后被析构了,在middle和end之间,47行处,调用了构造函数构造出一个临时变量,然后通过赋值构造函数赋值给变量b,随即临时变量被析构,而变量b直到main函数结束才被析构掉。

    总而言之,要对easylogging++做一层封装并保持其流式日志的特性,可以通过同样的方式,在析构函数上做手脚。

  • 相关阅读:
    CPP(c++) google gflags
    CPP(c++) google gtest
    CPP(c++) google gmock
    CPP(c++) google glog
    CPP(c++) lambda
    CPP(c++) 多线程
    可以使退出终端后仍运行的命令行
    python下输出指定年月日的方法之一
    linux下时间相差8小时的问题
    C# 中结束阻塞模式的接收方法
  • 原文地址:https://www.cnblogs.com/minglee/p/9157083.html
Copyright © 2020-2023  润新知