easylogging++的那些事(四)源码分析(二)日志记录宏(二)其他基本日志宏

在上一篇我们介绍了 CLOG宏其他相关类,今天我们来看看其他基本日志宏的实现。

CPLOG 宏

宏展开

    CPLOG 宏定义如下:

    #define CPLOG(LEVEL, ...) \
        C##LEVEL(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, __VA_ARGS__)> 

    其中 ## 是连字符,__VA_ARGS__ 原样替换 ...

Info 日志宏 CPLOG(INFO, xxx)

    用个具体的例子就一目了然了:

    CPLOG(INFO, "default");

    上面实际展开后为:

    CINFO(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, __VA_ARGS__);

    CINFO 宏在 CLOG 宏展开 中已经详细分析过了,这里我们直接看展开后的结果:

   el::base::PErrorWriter(el::Level::Info, __FILE__, __LINE__, ELPP_FUNC, el::base::DispatchAction::NormalLog).construct(1, "default");

    到这里为止,所有的宏替换就完成了,实际相当于创建了 el::base::PErrorWriter 类的实例,还是个临时对象。

    其他日志级别宏的展开类似。

Trace 日志宏 CPLOG(TRACE, XXX)

    用个具体的例子就一目了然了:

    CPLOG(TRACE, "default");

    上面实际展开后为:

    CTRACE(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, "default");

    CTRACE 宏在 CLOG 宏展开 中已经详细分析过了,这里我们直接看展开后的结果:

    el::base::PErrorWriter(el::Level::Trace, __FILE__, __LINE__, ELPP_FUNC, el::base::DispatchAction::NormalLog).construct(1, "default");

    到这里为止,所有的宏替换就完成了,和 Info 级别日志宏一样,实际相当于创建了 el::base::PErrorWriter 类的实例,还是个临时对象。

Debug 日志宏 CPLOG(DEBUG, XXX)

    用个具体的例子就一目了然了:

    CPLOG(DEBUG, "default");

    上面实际展开后为:

    CDEBUG(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, "default");

    CDEBUG 宏在 CLOG 宏展开 中已经详细分析过了,这里我们直接看展开后的结果:

    el::base::PErrorWriter(el::Level::Debug, __FILE__, __LINE__, ELPP_FUNC, el::base::DispatchAction::NormalLog).construct(1, "default");

    到这里为止,所有的宏替换就完成了,和 Info 级别日志宏一样,实际相当于创建了 el::base::PErrorWriter 类的实例,还是个临时对象。

Fatal 日志宏 CPLOG(FATAL, XXX)

    用个具体的例子就一目了然了:

    CPLOG(FATAL, "default");

    上面实际展开后为:

    CFATAL(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, "default");

    CFATAL 宏在 CLOG 宏展开 中已经详细分析过了,这里我们直接看展开后的结果:

    el::base::PErrorWriter(el::Level::Fatal, __FILE__, __LINE__, ELPP_FUNC, el::base::DispatchAction::NormalLog).construct(1, "default");

    到这里为止,所有的宏替换就完成了,和 Info 级别日志宏一样,实际相当于创建了 el::base::PErrorWriter 类的实例,还是个临时对象。

Error 日志宏 CPLOG(ERROR, XXX)

    用个具体的例子就一目了然了:

    CPLOG(ERROR, "default");

    上面实际展开后为:

    CERROR(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, "default");

    CERROR 宏在 CLOG 宏展开 中已经详细分析过了,这里我们直接看展开后的结果:

    el::base::PErrorWriter(el::Level::Error, __FILE__, __LINE__, ELPP_FUNC, el::base::DispatchAction::NormalLog).construct(1, "default");

    到这里为止,所有的宏替换就完成了,和 Info 级别日志宏一样,实际相当于创建了 el::base::PErrorWriter 类的实例,还是个临时对象。

Warning 日志宏 CPLOG(WARNING, XXX)

    用个具体的例子就一目了然了:

    CPLOG(WARNING, "default");

    上面实际展开后为:

    CWARNING(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, "default");

    CWARNING 宏在 CLOG 宏展开 中已经详细分析过了,这里我们直接看展开后的结果:

    el::base::PErrorWriter(el::Level::Warning, __FILE__, __LINE__, ELPP_FUNC, el::base::DispatchAction::NormalLog).construct(1, "default");

    到这里为止,所有的宏替换就完成了,和 Info 级别日志宏一样,实际相当于创建了 el::base::PErrorWriter 类的实例,还是个临时对象。

源码剖析

    从上面所有相关日志级别宏的最终展开结果可以看到: 都是创建了 el::base::PErrorWriter 类的实例,还是个临时对象。
    el::base::PErrorWriter 类的定义如下:

    class PErrorWriter : public base::Writer
    {
    public:
        PErrorWriter(Level level, const char *file, base::type::LineNumber line,
                     const char *func, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog,
                     base::type::VerboseLevel verboseLevel = 0) : base::Writer(level, file, line, func, dispatchAction, verboseLevel)
        {
        }
    
        virtual ~PErrorWriter(void);
    };
    
    PErrorWriter::~PErrorWriter(void)
    {
        if (m_proceed)
        {
    #if ELPP_COMPILER_MSVC
            char buff[256];
            strerror_s(buff, 256, errno);
            m_logger->stream() << ": " << buff << " [" << errno << "]";
    #else
            m_logger->stream() << ": " << strerror(errno) << " [" << errno << "]";
    #endif
        }
    }

    从上面的定义中可以看出 PErrorWriter 类继承了 Writer 类,相当于 PErrorWriter 类的增强类,增强的地方在 析构的时候会将 errno 的错误信息写入日志信息保存起来
    PErrorWriter 类的实例在析构(执行完使用 CPLOG 宏的这条语句后)的时候会先调用自身的析构函数,向 m_logger 成员的 stream 流(字符串流对象中)保存当前的 errno 信息,然后再调用基类子对象(Writer 类)的析构执行真正的日志写入动作。 Writer 类的析构函数在 CLOG日志输出 中已经仔细介绍过了,这里就不多说了。

    有了前面 CLOG 宏的分析,这里 CPLOG 宏的剖析就简单多了。至此 CPLOG 宏的实现就介绍完了。

CSYSLOG 宏

宏展开

    CSYSLOG 宏定义如下:

    #define CSYSLOG(LEVEL, ...) \
        C##LEVEL(el::base::Writer, el::base::DispatchAction::SysLog, __VA_ARGS__)

    其中 ## 是连字符,__VA_ARGS__ 原样替换...
    C##LEVEL 相关宏前面已经多次分析过了,这里简单看看最终展开后的结果:

Info 日志宏 CSYSLOG(INFO, xxx)

    用个具体的例子就一目了然了:

    CSYSLOG(INFO, "default");

    最终展开后为:

    el::base::Writer(el::Level::Info, __FILE__, __LINE__, ELPP_FUNC, el::base::DispatchAction::NormalLog).construct(1, "default");

Trace 日志宏 CSYSLOG(TRACE, XXX)

    用个具体的例子就一目了然了:

    CSYSLOG(TRACE, "default");

    最终展开为:

    el::base::Writer(el::Level::Trace, __FILE__, __LINE__, ELPP_FUNC, el::base::DispatchAction::NormalLog).construct(1, "default");

Debug 日志宏 CSYSLOG(DEBUG, XXX)

    用个具体的例子就一目了然了:

    CSYSLOG(DEBUG, "default");

    最终展开后为:

    el::base::Writer(el::Level::Debug, __FILE__, __LINE__, ELPP_FUNC, el::base::DispatchAction::NormalLog).construct(1, "default");

Fatal 日志宏 CSYSLOG(FATAL, XXX)

    用个具体的例子就一目了然了:

   CSYSLOG(FATAL, "default");

    最终展开为:

    el::base::Writer(el::Level::Fatal, __FILE__, __LINE__, ELPP_FUNC, el::base::DispatchAction::NormalLog).construct(1, "default");

Error 日志宏 CSYSLOG(ERROR, XXX)

    用个具体的例子就一目了然了:

    CSYSLOG(ERROR, "default");

    最终展开为:

    el::base::Writer(el::Level::Error, __FILE__, __LINE__, ELPP_FUNC, el::base::DispatchAction::NormalLog).construct(1, "default");

Warning 日志宏 CSYSLOG(WARNING, XXX)

    用个具体的例子就一目了然了:

    CSYSLOG(WARNING, "default");

    最终展开为:

    el::base::Writer(el::Level::Warning, __FILE__, __LINE__, ELPP_FUNC, el::base::DispatchAction::NormalLog).construct(1, "default");

源码剖析

    从上面所有用户日志相关日志级别宏的最终展开结果可以看到: 都是创建了 el::base::Writer 类的实例,还是个临时对象。
    Writer 类我们在 CLOGWriter 对象的创建以及初始化日志输出日志信息的保存 已经仔细介绍过了,这里就不多说了。

LOG 宏

    LOG 宏定义如下:

    #define LOG(LEVEL) CLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)

    ELPP_CURR_FILE_LOGGER_ID 的定义如下:

    #ifdef ELPP_DEFAULT_LOGGER
    static const char *kDefaultLoggerId = ELPP_DEFAULT_LOGGER;
    #else
    static const char *kDefaultLoggerId = "default";
    #endif
    
    #if defined(ELPP_DEFAULT_LOGGER)
    #define ELPP_CURR_FILE_LOGGER_ID ELPP_DEFAULT_LOGGER
    #else
    #define ELPP_CURR_FILE_LOGGER_ID el::base::consts::kDefaultLoggerId
    #endif

    CLOG 宏在前面 CLOG 宏展开Writer 对象的创建以及初始化日志输出日志信息的保存 已经仔细介绍过了,这里就不多说了。

PLOG 宏

    PLOG 宏定义如下:

    #define PLOG(LEVEL) CPLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)

    CPLOG 宏在前面已经仔细介绍过了。

SYSLOG 宏

    SYSLOG 宏定义如下:

    #define SYSLOG(LEVEL) CSYSLOG(LEVEL, el::base::consts::kSysLogLoggerId)

    CSYSLOG 宏在前面已经仔细介绍过了。

DCLOG 宏

    DCLOG 宏定义如下:

    #define DCLOG(LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG(LEVEL, __VA_ARGS__)

    ELPP_DEBUG_LOG 是一个宏,定义如下:

    #if (!defined(ELPP_DISABLE_DEBUG_LOGS) && (ELPP_LOGGING_ENABLED))
    #define ELPP_DEBUG_LOG 1
    #else
    #define ELPP_DEBUG_LOG 0
    #endif // (!defined(ELPP_DISABLE_DEBUG_LOGS) && (ELPP_LOGGING_ENABLED))

    ELPP_DISABLE_DEBUG_LOGS 宏和 ELPP_LOGGING_ENABLED 宏在 easylogging++的 宏定义 中介绍过。
    CLOG 宏在前面 CLOG 宏展开Writer 对象的创建以及初始化日志输出日志信息的保存 已经仔细介绍过了。

DCPLOG 宏

    DCPLOG 宏定义如下:

    #define DCPLOG(LEVEL, ...) \
        if (ELPP_DEBUG_LOG)    \
        C##LEVEL(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, __VA_ARGS__)

    ELPP_DEBUG_LOG 宏和 C##LEVEL 相关宏在前面已经仔细介绍过了。

DCSYSLOG 宏

    DCSYSLOG 宏定义如下:

    #define DCSYSLOG(LEVEL, ...) if (ELPP_DEBUG_LOG) C##LEVEL(el::base::Writer, el::base::DispatchAction::SysLog, __VA_ARGS__)

    ELPP_DEBUG_LOG 宏和 C##LEVEL 相关宏在前面已经仔细介绍过了。

DLOG 宏

    DLOG 宏定义如下:

    #define DLOG(LEVEL) DCLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)

    DCLOG 宏在前面已经仔细介绍过了。

DPLOG 宏

    DPLOG 宏定义如下:

    #define DPLOG(LEVEL) DCPLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)

    DCPLOG 宏在前面已经仔细介绍过了。

DSYSLOG 宏

    DSYSLOG 宏定义如下:

    #define DSYSLOG(LEVEL) DCSYSLOG(LEVEL, el::base::consts::kSysLogLoggerId)

    DCSYSLOG 宏在前面已经仔细介绍过了。

至此 easylogging++的基本日志宏就全部介绍完了,下一篇我们开始介绍条件日志宏。

posted @ 2022-11-27 22:04  节奏自由  阅读(61)  评论(0编辑  收藏  举报