Log4Qt 日誌格式化(PatternLayout)

繼承關係圖

Log4Qt 提供了各種佈局對象,通過使用這些 Layout,我們可以根據自己的喜好來格式化日誌輸出,自由指定日誌級別、線程名稱、Logger 名稱、日期時間等信息。

Log4Qt::Layout 繼承關係圖:

在該層次結構中,頂級類是 Layout,它是 Log4Qt API 中所有其他佈局類的基類。

**注意:**這裏列出來的這幾個 Layout 比較常用,也是我們重點講解的內容。此外,還有一些其它 Layout(例如:BinaryLayoutXMLLayout 等),這裏並沒有列出,希望通過後面分享的知識,大家能夠快速熟悉它們的用法。

這些類擴展了 Layout,並根據提供的模式重寫了 format() 方法來構造日誌信息。

在內部,PatternLayoutTTCCLayout 通過 PatternFormatter 來實現格式化。當 PatternFormatter 解析模式字符串時,它會根據發現的信息創建了一個 PatternConverter 鏈,每個 PatternConverter 會處理 LoggingEvent 的某個成員。

轉換字符

**轉換字符:**用於指定數據的類型,例如:類別、級別、日期、線程名稱。

轉換說明符以百分號(%)開始,後跟轉換字符。Log4Qt 中的轉換字符有:

ua8gKL

PatternLayout

如果想生成基於模式的特定格式的日誌信息,那麼可以使用 PatternLayout 來進行格式化。

枚舉 ConversionPattern 定義了兩個常用的模式:

RGkeYw

基本使用

創建一個 PatternLayout,並將日誌信息輸出至控制檯中:

#include <QCoreApplication>
#include <log4qt/logger.h>
#include <log4qt/patternlayout.h>
#include <log4qt/consoleappender.h>
#include <log4qt/loggerrepository.h>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 創建一個 PatternLayout(根據模式字符串輸出日誌事件)
    Log4Qt::Logger *logger = Log4Qt::Logger::rootLogger();
    Log4Qt::PatternLayout *layout = new Log4Qt::PatternLayout();
    layout->setHeader("----- Header -----");  // 設置標頭信息
    layout->setFooter("----- Footer -----");  // 設置頁腳信息
    layout->setName("My Layout");
    // layout->setConversionPattern(Log4Qt::PatternLayout::TTCC_CONVERSION_PATTERN);
    // layout->setConversionPattern("%d{yyyy-MM-dd hh:mm:ss} - %m%n");
    // layout->setConversionPattern("The output message is: %m%n");
    layout->activateOptions();

    // 創建一個 ConsoleAppender(將日誌內容輸出到控制檯上)
    Log4Qt::ConsoleAppender *appender = new Log4Qt::ConsoleAppender(layout, Log4Qt::ConsoleAppender::STDOUT_TARGET);
    appender->setName("My Appender");
    appender->activateOptions();
    logger->addAppender(appender);

    logger->setLevel(Log4Qt::Level::DEBUG_INT);
    logger->debug("Hello, Log4Qt!");

    // 關閉 logger
    logger->removeAllAppenders();
    logger->loggerRepository()->shutdown();

    return a.exec();
}

**注意:**除正文之外,還可以爲日誌消息指定標頭和頁腳。佈局對象的內容類型默認爲 text/plain,如果要自定義佈局並制定其他類型,需要重寫 Layout 的 contentType() 方法。

默認情況下,轉換模式爲 DEFAULT_CONVERSION_PATTERN,只會輸出簡單的日誌信息:

----- Header -----

Hello, Log4Qt!

----- Footer -----

由於我們在代碼中指定了標頭和頁腳,所以在日誌信息的前後會輸出相關信息,這有時在區分日誌時會很有用。

指定轉換模式

和其他佈局相比,PatternLayout 很大的一個優勢在於靈活。除了上述方式之外,還可以指定其它模式。

若要修改默認模式,可以打開代碼中的註釋部分:

layout->setConversionPattern(Log4Qt::PatternLayout::TTCC_CONVERSION_PATTERN);

運行程序,這時不僅會輸出日誌信息,還會輸出啓動時間、線程名稱、logger 名稱:

4 [0x000001bdc8415750] DEBUG root  - Hello, Log4Qt!

實際上,這採用的是和 TTCCLayout 相同的模式,從名字就可以看出。

此外,還可以通過自定義模式字符串來指定日期時間:

layout->setConversionPattern("%d{yyyy-MM-dd hh:mm:ss} - %m%n");

運行程序,輸出如下:

2021-08-17 22:54:04 - Hello, Log4Qt!

如果想額外爲消息添加一些文本,也非常簡單:

layout->setConversionPattern("The output message is: %m%n");

運行程序,輸出如下:

The output message is: Hello, Log4Qt!

通過這種方式,我們可以自由地在轉換模式中插入任何文本,使用起來相當方便。

使用配置文件

出於靈活性考慮,在以後的使用中,配置文件將是我們的首選,所以務必要學會如何有效地利用它。

編寫一個配置文件 - log4qt.properties,執行與上例中使用相同的任務:

# 定義 rootLogger
log4j.rootLogger=DEBUG, console

# 定義 ConsoleAppender
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.immediateFlush=true
log4j.appender.console.target=STDOUT_TARGET

# 爲 ConsoleAppender 定義 Layout
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.header=----- Header -----
log4j.appender.console.layout.footer=----- Footer -----
log4j.appender.console.layout.conversionPattern=%r [%t] %p %c %x - %m%n

然後,使用下面的程序:

#include <QCoreApplication>
#include <log4qt/logger.h>
#include <log4qt/loggerrepository.h>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 獲取 rootLogger
    Log4Qt::Logger* logger = Log4Qt::Logger::rootLogger();

    // 打印消息
    logger->debug("Hello, Log4Qt!");

    // 關閉 rootLogger
    logger->removeAllAppenders();
    logger->loggerRepository()->shutdown();

    return a.exec();
}

注意:最後記得關閉 logger,否則不會釋放資源,也不會輸出 Footer。

運行程序,輸出如下:

----- Header -----

65 [0x000001d25ec81f70] DEBUG root  - Hello, Log4Qt!

----- Footer -----

可以看出,使用配置文件和純代碼的效果是一樣的。

關注公衆**「高效程序員」**👇,一起優秀!

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/eFAy4h4TSIWT3WI-d7MuLQ