easylogging++的那些事(四)源码分析(二)日志记录宏(六)VERBOSE日志宏

在上一篇我们分析了 检查宏,今天来看看 VERBOSE 日志宏的实现。

CVLOG 宏

宏展开

    CVLOG 宏定义如下:

#define CVLOG(vlevel, ...) CVERBOSE(el::base::Writer, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)

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

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

CVLOG(1, "default");

    上面实际展开后为:

CVERBOSE(el::base::Writer, 1, el::base::DispatchAction::NormalLog, "default");

    而 CVERBOSE 是另外一个宏:

#if ELPP_VERBOSE_LOG
#define CVERBOSE(writer, vlevel, dispatchAction, ...) if (VLOG_IS_ON(vlevel)) writer( \
    el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, dispatchAction, vlevel).construct(el_getVALength (__VA_ARGS__), __VA_ARGS__)
#else
#define CVERBOSE(writer, vlevel, dispatchAction, ...) el::base::NullWriter()
#endif  // ELPP_VERBOSE_LOG

    ELPP_VERBOSE_LOG 宏定义如下:

#if (! defined(ELPP_DISABLE_VERBOSE_LOGS) && (ELPP_LOGGING_ENABLED))
#define ELPP_VERBOSE_LOG 1
#else
#define ELPP_VERBOSE_LOG 0
#endif  // (! defined(ELPP_DISABLE_VERBOSE_LOGS) && (ELPP_LOGGING_ENABLED))

    ELPP_DISABLE_VERBOSE_LOGSELPP_LOGGING_ENABLED 用于启用 VERBOSE 日志级别。
    ELPP_INFO_LOG 值为 0 时,直接就是 el::base::NullWriter()el::base::NullWriter 类在 CLOG 宏展开 中已经介绍过了,这里就不多说了。
    这里我们直接看 ELPP_INFO_LOG 宏值为 1 的情况:

#define CVERBOSE(writer, vlevel, dispatchAction, ...) if (VLOG_IS_ON(vlevel)) writer( \
    el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, dispatchAction, vlevel).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__);

    再次展开后为:

if (VLOG_IS_ON(1)) 
    el::base::Writer(el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, el::base::DispatchAction::NormalLog, 1).construct(el_getVALength("default"), "default");

    VLOG_IS_ON 也是一个宏:

#define VLOG_IS_ON(verboseLevel) (ELPP->vRegistry()->allowed(verboseLevel, __FILE__))

    el_getVALength 宏在 CLOG 宏展开 中已经详细分析过了,表示可变参的数目,这里 el_getVALength("default") 值为 1。

    将 VLOG_IS_ON 宏和 el_getVALength 宏替换后,最终展开后为:

if(ELPP->vRegistry()->allowed(1, __FILE__))
    el::base::Writer(el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, el::base::DispatchAction::NormalLog, 1).construct(1, "default");

源码剖析

    ELPP->vRegistry()->allowed 接口后面介绍 VERBOSE 日志时会进行详细分析,这里简单提一下这个接口的作用: 是否允许指定文件记录指定级别的详细日志

    从上面宏最终展开的结果来看,其实相当于:
    当允许指定文件记录指定级别的 VERBOSE 日志时,创建 el::base::Writer 的对象并初始化,反之则啥也不干。el::base::Writer 类我们在 CLOGWriter 对象的创建以及初始化日志输出日志信息保存 已经仔细介绍过了,这里就不多说了。

CVLOG_EVERY_N 宏

宏展开

    CVLOG_EVERY_N 宏定义如下:

#define CVLOG_EVERY_N(n, vlevel, ...)\
    CVERBOSE_EVERY_N(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)

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

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

CVLOG_EVERY_N(3, 2, "default");

    上面实际展开后为:

CVERBOSE_EVERY_N(el::base::Writer, 3, 2, el::base::DispatchAction::NormalLog, "default");

    CVERBOSE_EVERY_N 也是一个宏:

#if ELPP_VERBOSE_LOG
#define CVERBOSE_EVERY_N(writer, occasion, vlevel, dispatchAction, ...) \
    CVERBOSE_IF(writer, ELPP->validateEveryNCounter(__FILE__, __LINE__, occasion), vlevel, dispatchAction, __VA_ARGS__)
#else
#define CVERBOSE_EVERY_N(writer, occasion, vlevel, dispatchAction, ...) el::base::NullWriter()
#endif  // ELPP_VERBOSE_LOG

    ELPP_VERBOSE_LOG 宏前面 CVLOG 宏中已经介绍过了。
    el::base::NullWriter 类在 CLOG 宏展开 中已经介绍过了。
    这里我们直接看 ELPP_VERBOSE_LOG 宏值为 1 的情况:

CVERBOSE_IF(writer, ELPP->validateEveryNCounter(__FILE__, __LINE__, occasion), vlevel, dispatchAction, __VA_ARGS__)

    展开后为:

CVERBOSE_IF(el::base::Writer, ELPP->validateEveryNCounter(__FILE__, __LINE__, 3), 2, el::base::DispatchAction::NormalLog, "default");

    CVERBOSE_IF 也是一个宏:

#if ELPP_VERBOSE_LOG
#define CVERBOSE_IF(writer, condition_, vlevel, dispatchAction, ...) if (VLOG_IS_ON(vlevel) && (condition_)) writer( \
    el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, dispatchAction, vlevel).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
#else
#define CVERBOSE_IF(writer, condition_, vlevel, dispatchAction, ...) el::base::NullWriter()
#endif  // ELPP_VERBOSE_LOG

    和上面一样,这里直接看 ELPP_VERBOSE_LOG 宏值为 1 的情况:

#define CVERBOSE_IF(writer, condition_, vlevel, dispatchAction, ...) if (VLOG_IS_ON(vlevel) && (condition_)) writer( \
    el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, dispatchAction, vlevel).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)

继续展开后为:

if (VLOG_IS_ON(2) && (ELPP->validateEveryNCounter(__FILE__, __LINE__, 3))) 
    el::base::Writer(el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, el::base::DispatchAction::NormalLog, 2).construct(el_getVALength("default"), "default");  

    VLOG_IS_ON 宏在前面已经介绍过了,这里就不多说了。
    el_getVALength 宏在 CLOG 宏展开 中已经详细分析过了,表示可变参的数目,这里 el_getVALength("default") 值为 1。

    将 VLOG_IS_ON 宏和 el_getVALength 宏替换后,最终展开为:

if (ELPP->vRegistry()->allowed(2, __FILE__) && (ELPP->validateEveryNCounter(__FILE__, __LINE__, 3))) 
    el::base::Writer(el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, el::base::DispatchAction::NormalLog, 2).construct(1, "default");  

源码剖析

    ELPP->vRegistry()->allowed 接口在前面 CVLOG 中已经介绍过了:是否允许指定文件记录指定级别的详细日志。
    ELPP->validateEveryNCounter 接口在 偶尔日志宏 中已经介绍过了:给定的偶尔记日志的次数有是指定的次数的倍数时则返回真。

    从上面宏最终展开的结果来看,其实相当于:
    当允许指定文件记录指定级别的详细日志时并且给定的偶尔记日志的次数是 3 的倍数时,创建 el::base::Writer 对象并初始化,否则啥也不干。el::base::Writer 类我们在 CLOGWriter 对象的创建以及初始化日志输出日志信息保存 已经仔细介绍过了,这里就不多说了。

CVLOG_AFTER_N 宏

宏展开

    CVLOG_AFTER_N 宏定义如下:

#define CVLOG_AFTER_N(n, vlevel, ...)\
    CVERBOSE_AFTER_N(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)

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

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

CVLOG_AFTER_N(3, 2, "default");

    上面实际展开后为:

CVERBOSE_AFTER_N(el::base::Writer, 3, 2, el::base::DispatchAction::NormalLog, "default");

    CVERBOSE_AFTER_N 也是一个宏:

#if ELPP_VERBOSE_LOG
#define CVERBOSE_AFTER_N(writer, n, vlevel, dispatchAction, ...) \
    CVERBOSE_IF(writer, ELPP->validateAfterNCounter(__FILE__, __LINE__, n), vlevel, dispatchAction, __VA_ARGS__)
#else
#define CVERBOSE_AFTER_N(writer, n, vlevel, dispatchAction, ...) el::base::NullWriter()
#endif  // ELPP_VERBOSE_LOG

    ELPP_VERBOSE_LOG 宏前面 CVLOG 宏中已经介绍过了。
    el::base::NullWriter 类在 CLOG 宏展开 中已经介绍过了。
    这里我们直接看 ELPP_VERBOSE_LOG 宏值为 1 的情况:

CVERBOSE_IF(writer, ELPP->validateAfterNCounter(__FILE__, __LINE__, n), vlevel, dispatchAction, __VA_ARGS__)

    展开后为:

CVERBOSE_IF(el::base::Writer, ELPP->validateAfterNCounter(__FILE__, __LINE__, 3), 2, el::base::DispatchAction::NormalLog, "default");

    CVERBOSE_IF 宏在前面 CVLOG_EVERY_N 宏中已经介绍过了,这里直接最后展开的结果:

if (ELPP->vRegistry()->allowed(2, __FILE__) && (ELPP->validateAfterNCounter(__FILE__, __LINE__, 3))) 
    el::base::Writer(el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, el::base::DispatchAction::NormalLog, 2).construct(1, "default");  

源码剖析

    ELPP->vRegistry()->allowed 接口在前面 CVLOG 宏中已经介绍过了:是否允许指定文件记录指定级别的详细日志。
    ELPP->validateAfterNCounter 接口在 偶尔日志宏 中已经介绍过了:给定的偶尔记日志的次数大于等于指定的次数时则返回真。

    从上面宏最终展开的结果来看,其实相当于:
    当允许指定文件记录指定级别的详细日志并且给定的偶尔记日志的次数大于等于 3 次时,则创建 el::base::Writer 对象并初始化,否则啥也不干。
    el::base::Writer 类我们在 CLOGWriter 对象的创建以及初始化日志输出日志信息保存 已经仔细介绍过了,这里就不多说了。

CVLOG_N_TIMES 宏

宏展开

    CVLOG_AFTER_N 宏定义如下:

#define CVLOG_N_TIMES(n, vlevel, ...)\
    CVERBOSE_N_TIMES(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)

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

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

CVLOG_N_TIMES(3, 2, "default");

    上面实际展开后为:

CVERBOSE_N_TIMES(el::base::Writer, 3, 2, el::base::DispatchAction::NormalLog, "default");

    CVERBOSE_AFTER_N 也是一个宏:

#if ELPP_VERBOSE_LOG
#define CVERBOSE_N_TIMES(writer, n, vlevel, dispatchAction, ...) \
    CVERBOSE_IF(writer, ELPP->validateNTimesCounter(__FILE__, __LINE__, n), vlevel, dispatchAction, __VA_ARGS__)
#else
#define CVERBOSE_N_TIMES(writer, n, vlevel, dispatchAction, ...) el::base::NullWriter()
#endif  // ELPP_VERBOSE_LOG

    ELPP_VERBOSE_LOG 宏前面 CVLOG 宏中已经介绍过了。
    el::base::NullWriter 类在 CLOG 宏展开 中已经介绍过了。
    这里我们直接看 ELPP_VERBOSE_LOG 宏值为 1 的情况:

CVERBOSE_IF(writer, ELPP->validateNTimesCounter(__FILE__, __LINE__, n), vlevel, dispatchAction, __VA_ARGS__)

    展开后为:

CVERBOSE_IF(el::base::Writer, ELPP->validateNTimesCounter(__FILE__, __LINE__, 3), 2, el::base::DispatchAction::NormalLog, "default");

    CVERBOSE_IF 宏在前面 CVLOG_EVERY_N 宏中已经介绍过了,这里直接最后展开的结果:

if (ELPP->vRegistry()->allowed(2, __FILE__) && (ELPP->validateNTimesCounter(__FILE__, __LINE__, 3))) 
    el::base::Writer(el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, el::base::DispatchAction::NormalLog, 2).construct(1, "default");  

源码剖析

    ELPP->vRegistry()->allowed 接口在前面 CVLOG 宏中已经介绍过了:是否允许指定文件记录指定级别的详细日志。
    ELPP->validateNTimesCounter 接口在 偶尔日志宏 中已经介绍过了:给定的偶尔记日志的次数小于等于指定的次数时则返回真。

    从上面宏最终展开的结果来看,其实相当于:
    当允许指定文件记录指定级别的详细日志并且给定的偶尔记日志的次数小于等于 3 次时,则创建 el::base::Writer 对象并初始化,否则啥也不干。
    el::base::Writer 类我们在 CLOGWriter 对象的创建以及初始化日志输出日志信息保存 已经仔细介绍过了,这里就不多说了。

VLOG 宏

    VLOG 宏定义如下:

#define VLOG(vlevel) CVLOG(vlevel, ELPP_CURR_FILE_LOGGER_ID)

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

DCVLOG 宏

    DCVLOG 宏定义如下:

#define DCVLOG(vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG(vlevel, __VA_ARGS__)

    ELPP_DEBUG_LOG 宏在 CLOG 宏展开 已经仔细介绍过了。
    CVLOG 宏在前面已经仔细介绍过了。

DVLOG 宏

    DVLOG 宏定义如下:

#define DVLOG(vlevel) DCVLOG(vlevel, ELPP_CURR_FILE_LOGGER_ID)

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

VLOG_EVERY_N 宏

    VLOG_EVERY_N 宏定义如下:

#define VLOG_EVERY_N(n, vlevel) CVLOG_EVERY_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)

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

VLOG_AFTER_N 宏

    VLOG_AFTER_N 宏定义如下:

#define VLOG_AFTER_N(n, vlevel) CVLOG_AFTER_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)

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

VLOG_N_TIMES 宏

    VLOG_N_TIMES 宏定义如下:

#define VLOG_N_TIMES(n, vlevel) CVLOG_N_TIMES(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)

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

至此,VERBOSE 日志宏就介绍完了,下一篇我们开始介绍logger类的类printf接口。

posted @ 2022-11-30 12:30  节奏自由  阅读(86)  评论(0编辑  收藏  举报