这篇文章上次修改于 192 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

QT的应用程序在运行过程中,自己程序的日志,我们是可以控制并打印输出的。另外,Qt框架内部也包含大量重要的日志输出,只不过这些日志默认处于禁止状态。

当遇到需要深入Qt框架内调查的问题时,若需查看部分Qt源码运行时日志,这时候就需要打开qt源码的日志开关了。

框架日志

Qt源码中,日志输出使用的宏:qCDebugqCWarningqCInfoqCCritical,如:

qCDebug(lcAccessibilityCache) << "insert - id:" << id << " iface:" << iface;
//usbEntries()只在driverUsb类别debug类型输出启用时才发生调用
qCDebug(driverUsb) << "devices: " << usbEntries(); 

这些宏实际是通过QLoggingCategory进行日志管理:

#  define qCDebug(category, ...) \
    for (bool qt_category_enabled = category().isDebugEnabled(); qt_category_enabled; qt_category_enabled = false) \
        QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC, category().categoryName()).debug(__VA_ARGS__)

QLoggingCategory提供了多种控制打印输出类别的方法,方便在调试时过滤掉不关心的信息。

日志类别

Qt框架中,声明了大量的qt.开头的日志类别。你也可以使用Q_DECLARE_LOGGING_CATEGORY()Q_LOGGING_CATEGORY()宏可以方便地声明和创建自己的日志类别:

 // in a header
 Q_DECLARE_LOGGING_CATEGORY(driverUsb)

 // in one source file
 Q_LOGGING_CATEGORY(driverUsb, "driver.usb")

类别名称应遵循以下约定:

  • 仅使用字母和数字。
  • 使用点划分子类别。
  • 避免使用类别名称:debuginfowarning critical
  • 带有qt前缀的类别名称仅保留给Qt模块。

QLoggingCategory() 构造函数和Q_LOGGING_CATEGORY()宏都接受可选的QtMsgType参数,该参数禁用所有严重性较低的消息类型。如:

Q_LOGGING_CATEGORY(driverUsbEvents, “driver.usb.events”, QtWarningMsg)

将记录 QtWarningMsg、QtCriticalMsg、QtFatalMsg 类型的消息,但忽略 QtDebugMsg 和 QtInfoMsg 类型的消息。

如果未传递任何参数,则记录所有消息。

日志规则

日志记录规则允许您以灵活的方式启用或禁用类别的日志记录,每条规则的格式:

<category>[.<type>] = true|false

<category>是类别的名称,可能使用*作为通配符匹配一个或多个位置。可选项<type>必须是 debuginfowarning critical,不符合的行将被忽略。

规则按文本顺序进行设置,如果两个规则应用于同一个类别+类型,则后面的规则有效。

输出配置

环境变量

可以在QT_LOGGING_RULES环境变量中指定日志记录规则,多个规则时用分号;分隔:

QT_LOGGING_RULES="*.debug=false;driver.usb.debug=true"

配置文件

除使用环境变量配置外,还可以使用配置文件(ini格式)进行配置。日志记录规则会从文件的[Rules]部分加载,配置文件位置见下文:

[Rules]
*.debug=false
driver.usb.debug=true

应用顺序

  • [QLibraryInfo::DataPath]/qtlogging.ini
  • QtProject/qtlogging.ini
  • setFilterRules()
  • QT_LOGGING_CONF
  • QT_LOGGING_RULES
    说明:
  1. QtProject/qtlogging.ini文件在QStandardPaths::GenericConfigLocation()返回的所有目录中查找。
  2. setFilterRules()设置的规则优先于QtProject配置目录中指定的规则,所以通过此接口设置的规则可以被QT_LOGGING_CONF指定的配置文件中的规则和QT_LOGGING_RULES设置的规则覆盖。
  3. 设置QT_LOGGING_DEBUG环境变量可以输出日志记录规则的加载位置。

输出Qt框架日志

回到文章题目提出的问题,在开发环境中可以在Qt安装目录中创建配置文件(C:\Qt\Qt5.15\5.15.2\msvc2019\qtlogging.ini),如:

[Rules]
*.debug=false
qt.accessibility.cache=true

将禁用除qt.accessibility.cache外的所有日志。当然也可以按上文中说明将文件放置在其他目录。