1. 程式人生 > 其它 >easylogging++的那些事(四)原始碼分析(二)日誌記錄巨集(四)VERBOSE日誌巨集

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 類我們在 CLOG 巨集 Writer 物件的建立以及初始化日誌輸出日誌資訊儲存 已經仔細介紹過了,這裡就不多說了。

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 類我們在 CLOG 巨集 Writer 物件的建立以及初始化日誌輸出日誌資訊儲存 已經仔細介紹過了,這裡就不多說了。

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 類我們在 CLOG 巨集 Writer 物件的建立以及初始化日誌輸出日誌資訊儲存 已經仔細介紹過了,這裡就不多說了。

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 類我們在 CLOG 巨集 Writer 物件的建立以及初始化日誌輸出日誌資訊儲存 已經仔細介紹過了,這裡就不多說了。

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 日誌巨集就介紹完了,下一篇我們開始介紹日誌格式的配置與載入。