Log4Qt 日志格式化(TTCCLayout)

高效程序员

共 5355字,需浏览 11分钟

 ·

2021-09-18 20:04

星标/置顶 公众号👇硬核文章第一时间送达



1

TTCC 概要


SimpleLayout 对象采用的格式化风格非常简单,在某些情况下可能比较有用,但有时我们希望得到更详细的信息,特别是在多线程应用程序中。当多个客户端访问同一应用程序模块时,发布日志记录的时间、活动线程等信息非常重要,可以以此来区分多个独立的客户端行为。


TTCCLayout 负责提供有关日志事件的详细信息,通常它包含以下内容:


  • Time:从启动应用程序开始,以毫秒数计算的时间;

  • Thread:调用线程;

  • Category:用于创建日志事件的类别或 Logger;

  • Context:NDC 信息。此信息不会自动包含在 LoggingEvent 对象中,必须专门包含它。因此,这是 TTCCLayout 的一个可选输出 - 即使启用了 NDC 设置,如果 LoggingEvent 不包含任何 NDC 设置,TTCCLayout 也可能不会显示任何 NDC 数据。


注意:TTCC 正是这些单词的缩写组合,因此而得名。


此外,这几个字段中的每一个都可以单独启用或禁用(可选参数,并不强制)。



强制性信息


对于 TTCCLayout 来说,可以决定是否启用上面的可选参数。然而,即使不启用它们,也仍将输出以下信息:


  • Level:日志消息的级别;

  • Message:日志消息本身;


换句话说,这两个是强制性信息,不受可选参数的影响!



日志格式


日期格式,取决于 DateFormat


枚举日期格式字符串将被格式化为
NONE"NONE"
ISO8601"ISO8601"yyyy-MM-dd hh:mm:ss.zzz
ABSOLUTE"ABSOLUTE"HH:mm:ss.zzz
DATE"DATE"MMM YYYY HH:mm:ss.zzzz
RELATIVE"RELATIVE"自程序启动以来经过的时间(以毫秒为单位)


其中,RELATIVE 是默认值。



控制日志消息


TTCCLayout 由好几部分组成,而最终各个部分能否出现在日志中,取决于它们是否作为 LoggingEvent 的一部分被提供到 TTCCLayout


通过下表中列出的属性或方法,TTCCLayout 可以灵活地控制日志消息的不同部分:


属性方法描述默认值
categoryPrefixingsetCategoryPrefixing(bool)指定 Logger 名称是否是格式化输出的一部分true
contextPrintingsetContextPrinting(bool)指定嵌套的上下文信息是否是格式化输出的一部分true
threadPrintingsetThreadPrinting(bool)指定线程名称是否是格式化输出的一部分true
dateFormatsetDateFormat(const QString &)指定布局使用的日期格式"RELATIVE"


有了这些知识,编写一个 TTCCLayout 的相关程序会简单很多。为了完整起见,我们首先会以编程方式配置 TTCCLayout,随后再通过配置文件进行配置。



2

以编程方式配置


要在程序中配置日志,首先要获得一个 Logger 实例,然后将 ConsoleAppender 附加到这个实例上。为了格式化日志消息,我们还将创建一个 TTCCLayout 对象,并将其附加到 ConsoleAppender 中。


和前面一样,输出一个简单的信息:


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

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

    // 创建一个 TTCCLayout(输出时间、线程、Logger 以及消息内容)
    Log4Qt::Logger *logger = Log4Qt::Logger::rootLogger();
    Log4Qt::TTCCLayout *layout = new Log4Qt::TTCCLayout();
    layout->setName("My Layout");
    // layout->setCategoryPrefixing(false);  // 禁用 logger 名称
    // layout->setContextPrinting(false);  // 禁用嵌套的上下文信息
    // layout->setThreadPrinting(false);  // 禁用线程名
    // layout->setDateFormat("ISO8601");  // 设置日期格式
    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();
}


注意:可以通过注释部分,对可选属性进行灵活控制。


运行此程序,将在控制台中生成以下输出:

170 [0x000002ab780c14e0] DEBUG root  - Hello, Log4Qt!

打开注释部分,再次运行程序,输出如下:

2021-09-16 22:57:44.243 DEBUG - Hello, Log4Qt!

可以看到,日期格式变了,并且 Logger、线程也被禁用了。



3

使用配置文件


现在,编写一个配置文件 - 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.TTCCLayout
log4j.appender.console.layout.categoryPrefixing=false
log4j.appender.console.layout.contextPrinting=false
log4j.appender.console.layout.threadPrinting=false
log4j.appender.console.layout.dateFormat=ISO8601


在此配置中,我们禁用了 categoryPrefixingcontextPrinting、以及 threadPrinting 属性,并为 dateFormat 指定了一个时间格式 ISO8601


然后,使用下面的程序:


#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();
}

运行此程序,将在控制台中生成以下输出:

2021-09-16 23:01:41.409 DEBUG - Hello, Log4Qt!

可以看到,无论是使用编程方式,还是配置文件方式,效果是一样的。



往期推荐




☞ 专辑 | 趣味设计模式
☞ 专辑 | 音视频开发
☞ 专辑 | C++ 进阶
☞ 专辑 | 超硬核 Qt
☞ 专辑 | 玩转 Linux
☞ 专辑 | GitHub 开源推荐
☞ 专辑 | 程序人生


关注公众「高效程序员」👇一起优秀!

回复 “入群” 进技术交流群,回复 “1024” 获取海量学习资源。
浏览 10
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报