0.简介

QLoggingCategory在运行时表示某个日志记录类别(由字符串标识),可以将消息类别配置为启用或禁用。Qt有六种消息类型,四个普通的QtDebugMsg、QtInfoMsg、QtWarningMsg、QtCriticalMsg,外加两个特殊的QtFatalMsg和QtSystemMsg,一般操作四个普通的消息类型。

1.基本使用

头文件中使用宏声明

#include <QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(mylog)

源文件中使用宏定义

Q_LOGGING_CATEGORY(mylog, "mymodule.mylog")
//也可以加上初始日志级别
Q_LOGGING_CATEGORY(mylog, "mymodule.mylog", QtWarningMsg)

配置注意事项,日志记录类别字符串的命名(mymodule.mylog那一串)

  • 仅使用字母和数字。
  • 使用点将类别进一步划分为公共区域。
  • 避免类别名称:debuginfowarning,和critical
  • 带有qt前缀的类别名称仅保留用于Qt模块。

可以设置全局过滤规则,使用字符串匹配

(下面代码把宏定义时设置的Warning级别覆盖了,现在所有类别都会输出) 

QLoggingCategory::setFilterRules("mymodule.mylog*=true");

多个规则字符串用换行符分隔,每一行格式为: <category>[.<type>] = true|false 

多次调用这个函数的话会以最后一次为准,所以多个设置要么放到一个规则配置,要么单独对指定QLoggingCategory设置。

也可以安装过滤器

在这种情况下,将忽略所有过滤器规则

(参照文档示例,注意install一个无效的过滤器会使用默认的并返回,这样就拿到了默认的)

QLoggingCategory::CategoryFilter old_filter;
//除了指定的都用默认的过滤器
void new_filter_func(QLoggingCategory *category)
{
    if (qstrcmp(category->categoryName(), "mymodule.mylog") == 0)
        category->setEnabled(QtDebugMsg, true);
    else
        old_filter(category);
}

// ... ...
void main()
{
    old_filter=QLoggingCategory::installFilter(nullptr);
    QLoggingCategory::installFilter(new_filter_func);
}

使用方式

(可以用qCDebug、qCInfo、qCWarning、qCCritical来使用自己定义的QLoggingCategory)

//默认的QLoggingCategory或qt.xx来管理     
qDebug()<<"qDebug()";
qInfo()<<"qInfo()";
qWarning()<<"qWarning()";
qCritical()<<"qCritical()";
//这个和一般的打印不一样,如果使用默认消息处理(qInstallMessageHandler那个),会终止程序
//qFatal("qFatal()");

//自己定义的QLoggingCategory
qCDebug(mylog)<<"qCDebug(mylog)";
qCInfo(mylog)<<"qCInfo(mylog)";
qCWarning(mylog)<<"qCWarning(mylog)";
qCCritical(mylog)<<"qCCritical(mylog)";

2.宏定义对应源码

#define Q_DECLARE_LOGGING_CATEGORY(name) \
    extern const QLoggingCategory &name();

#define Q_LOGGING_CATEGORY(name, ...) \
    const QLoggingCategory &name() \
    { \
        static const QLoggingCategory category(__VA_ARGS__); \
        return category; \
    }

3.setFilterRules使用实例(参考博客里的)

注册四个log:

Q_LOGGING_CATEGORY(logAa, "logA.loga")
Q_LOGGING_CATEGORY(logAb, "logA.logb")
Q_LOGGING_CATEGORY(logBa, "logB.loga")
Q_LOGGING_CATEGORY(logBb, "logB.logb")

试验方法:

//关闭logAa debug输出
QLoggingCategory::setFilterRules(QLatin1String("logA.loga.debug=false"));

//关闭logBb info输出
QLoggingCategory::setFilterRules(QLatin1String("logB.logb.info=false"));

//关闭log*b waring输出
QLoggingCategory::setFilterRules(QLatin1String("*.logb.warning=false"));

//关闭logAa 所有输出
QLoggingCategory::setFilterRules(QLatin1String("logA.loga*=false"));

//关闭logA 所有输出
QLoggingCategory::setFilterRules(QLatin1String("logA*=false"));

//关闭logAa debug 和 info 输出
QLoggingCategory::setFilterRules(QLatin1String("logA.loga.debug=false\nlogA.loga.info=false"));
												   
//只打开logAa debug输出
QLoggingCategory::setFilterRules(QLatin1String("*=false\nlogA.loga.debug=true"));

4.日志的规则配置

可以通过设置日志记录规则或安装自定义过滤器来覆盖类别的默认配置。

每一行规则的格式:

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

可以使用setFilterRules静态函数设置规则:

QLoggingCategory::setFilterRules("mymodule.mylog*=true");

也可以使用Qt工程配置或者设置环境变量,不过这种比较麻烦的我就懒得测试了。

共有五种方法设置日志过滤规则,如下优先级依次递增:

  • [QLibraryInfo::DataPath]/qtlogging.ini
  • QtProject/qtlogging.ini:如在/home/zet/.config/QtProject创建qtlogging.ini文件
  • setFilterRules()
  • QT_LOGGING_CONF :环境变量,指定日志过滤规则的文件,可以是相对路径或绝对路径,如:export QT_LOGGING_CONF=/test/qt/LoggingCategory/logconfig.ini
  • QT_LOGGING_RULES:环境变量,可以设置多个规则用逗号分割,如:QT_LOGGING_RULES="*.debug=false;logA.loga.debug=false"

注意:如果使用了installFilter,将忽略所有过滤器规则。 

5.打印当前的QLoggingCategory日志记录类别

可以使用%{category}占位符在默认消息处理程序中打印日志记录类别(mymodule.mylog那一串),如设置全局的:

qSetMessagePattern("%{category}: %{message}");

那么打印出来就像这样:

还可以使用%{if-category}...%{endif}过滤出非默认的category,如:

qSetMessagePattern("%{if-category}[ %{category} ]%{endif}%{message}");

(这个函数还有其他的占位符,可以自己操作下) 

6.参考

文档:https://doc.qt.io/qt-5/qloggingcategory.html

博客:https://blog.csdn.net/u010168781/article/details/84667524

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐