Qt5.14.2 揭秘Qt日志神器高效诊断程序潜在隐疾
对程序员而言,代码中的bug往往如同无影无踪的隐疾,影响着程序的健康运行。而及时有效的诊断手段则是治疗这些隐疾的良药。今天,我们将一窥Qt日志框架QLoggingCategory的神奇功效,探究它如何为你的Qt应用程序构筑坚实的诊断防火墙。
一、Qt日志框架简介
Qt内置了一个功能强大的日志框架,旨在帮助开发者高效诊断应用程序中潜在的问题。这套框架包含qDebug()、qInfo()、qWarning()和qCritical()等日志记录函数,以及QLoggingCategory等控制日志输出的工具类。
二、简单实践:qDebug输出
qDebug()无疑是最常用的日志输出函数,它会将日志信息输出到stderr标准错误流,从而统一输出到终端或者IDE集成工具的调试视图中。
qDebug() << "Hello Qt Log!";
qDebug() << "Value:" << 3.14;
QString str = "Debug Message";
qDebug() << str;
三、QLoggingCategory助力日志控制
借助QLoggingCategory,我们可以更细腻地控制不同日志信息的记录规则,甚至限制日志只输出在特定的平台或设备上。这对于分析复杂应用中的特定环节或组件情况极为有用。
// 1.定义日志类别
Q_LOGGINGCATEGORY(QT_EXAMPLE_MAIN, "qt.example.main")
Q_LOGGINGCATEGORY(QT_EXAMPLE_NETWORKING, "qt.example.networking", QtInfoMsg)// 2.根据类别名控制输出级别
QLoggingCategory::setFilterRules("qt.example.networking=true\nqt.example.main.debug=false");// 3.在代码中使用
qCDebug(QT_EXAMPLE_MAIN) << "Main log";
qCInfo(QT_EXAMPLE_NETWORKING) << "Network log";
QLoggingCategory允许我们在运行时动态设置日志级别,从而控制哪些级别的日志可以被输出。设置日志级别的方式很简单,使用QLoggingCategory::setFilterRules函数即可。
QLoggingCategory定义了以下几个日志级别:
- QtDebugMsg - Debug级别
- QtInfoMsg - 信息级别
- QtWarningMsg - 警告级别
- QtCriticalMsg - 严重级别
- QtFatalMsg - 致命级别
我们可以为每个日志类别设置单独的日志级别,或者为所有类别设置统一的全局级别。
下面是一些示例:
1、设置单个类别的日志级别:
Q_LOGGINGCATEGORY(APP_MAIN, "app.main")// 只输出APP_MAIN类别的WARNING及以上级别日志
QLoggingCategory::setFilterRules("app.main.warning=true");qCDebug(APP_MAIN) << "Ignored debug";
qCWarning(APP_MAIN) << "Warning message"; //会输出
2、设置所有类别的全局日志级别:
// 所有类别只输出CRITICAL及以上级别日志
QLoggingCategory::setFilterRules("*.critical=true");qCDebug(APP_MAIN) << "Ignored debug";
qCWarning(APP_MAIN) << "Ignored warning";
qCCritical(APP_MAIN) << "Critical error!"; //会输出
3、同时设置多个规则:
// APP_NETWORK类别只输出INFO及以上
// 其他类别只输出WARNING及以上
QLoggingCategory::setFilterRules("app.network.info=true\n*.warning=true");
可以看到,setFilterRules函数的参数是一个规则字符串,可以包含多条规则,以\n分隔。规则语法为:
<category>.debug|info|warning|critical|fatal=true|false
其中,category可以是具体的类别名或通配符*表示所有类别。等号后面指定是启用还是禁用该级别的日志输出。
我们也可以在程序启动时就设置好规则,比如通过命令行参数或配置文件传入。或者在运行过程中根据需求动态修改日志级别,实现灵活的日志控制。
此外,QtCreator还提供了一个非常方便的图形化界面来配置日志级别。在Analyzer->Logging->LoggingSettings中,我们可以可视化地启用禁用不同类别和级别的日志输出。
通过合理设置日志级别,我们可以在应用开发和调试的不同阶段,根据实际情况来控制输出精简的日志信息,提高诊断效率。
四、高级主题:详尽日志上下文
在实际开发中,我们往往需要获取更多辅助信息(如行号、函数名等),以确定问题发生的上下文环境。Qt提供了qDebug捕获器(QDebugStateSaverX)来记录详细的语句执行位置信息。
void myFunction(int c) {QDebugStateSaver stateSaver;qDebug() << "Entering myFunction(" << c << ")";// Function code...
}
五、QLoggingCategory其他常见用法
QLoggingCategory除了我们上面提到的控制日志输出规则和级别的功能之外,还有以下一些常见的用法:
1、将日志输出重定向到文件
通过QLoggingCategory::installMessageHandler函数,可以自定义日志输出的处理回调函数,将日志信息重定向写入到文件中,而不是直接输出到控制台。这在某些场景下非常有用,比如在服务器环境中捕获程序运行日志。
下面我们通过一个完整的示例代码来说明具体的实现步骤:
#include <QCoreApplication>
#include <QLoggingCategory>
#include <QFile>
#include <QTextStream>// 定义日志类别
Q_LOGGINGCATEGORY(LOG_CATEGORY, "example.log")// 自定义消息处理函数
void customMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{// 打开日志文件static QFile logFile("log.txt");if (!logFile.isOpen()) {logFile.open(QIODevice::WriteOnly | QIODevice::Append);}// 将日志写入文件QTextStream stream(&logFile);stream << qPrintable(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz "));switch (type) {case QtDebugMsg:stream << "Debug: ";break;case QtInfoMsg:stream << "Info: ";break;case QtWarningMsg:stream << "Warning: ";break;case QtCriticalMsg:stream << "Critical: ";break;case QtFatalMsg:stream << "Fatal: ";break;}stream << msg << " (" << context.file << ":" << context.line << ", " << context.function << ")" << endl;
}int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// 安装自定义消息处理函数qInstallMessageHandler(customMessageHandler);// 使用日志类别输出日志qCDebug(LOG_CATEGORY) << "This is a debug message";qCInfo(LOG_CATEGORY) << "This is an info message";qCWarning(LOG_CATEGORY) << "This is a warning message";qCCritical(LOG_CATEGORY) << "This is a critical message";return a.exec();
}
这个示例中,我们首先定义了一个名为LOG_CATEGORY的日志类别。
然后实现了一个自定义的消息处理函数customMessageHandler。这个函数会在Qt输出日志时被调用,我们在函数内部打开了一个名为log.txt的文件,并将日志信息以特定的格式写入到文件中。
在main函数中,我们通过qInstallMessageHandler函数将自定义的customMessageHandler安装为Qt的全局消息处理程序。
接下来,我们就可以使用qCDebug、qCInfo等带类别的日志输出函数来输出日志了。由于我们已经安装了自定义的处理程序,所以这些日志信息会被重定向写入到log.txt文件中。
运行这个程序后,您可以查看log.txt文件的内容,里面会包含程序输出的各种级别的日志信息,格式类似于:
2023-05-18 14:36:52.131 Debug: This is a debug message (main.cpp:30, main)
2023-05-18 14:36:52.132 Info: This is an info message (main.cpp:31, main)
2023-05-18 14:36:52.132 Warning: This is a warning message (main.cpp:32, main)
2023-05-18 14:36:52.132 Critical: This is a critical message (main.cpp:33, main)
可以看到,每一条日志都包含了时间戳、日志级别、消息内容以及文件名、行号、函数名等上下文信息,方便我们分析和定位问题。
通过这种方式,我们就可以将Qt程序的日志信息持久化存储到文件中,不再依赖于控制台输出,从而方便了日志的收集和管理。您也可以根据实际需求,对这个自定义消息处理函数进行修改和扩展,比如增加日志文件的循环滚动等功能。
2、条件日志输出
通过 QtMsgType 参数,QLoggingCategory可以让你有条件地输出日志,比如只输出WARNING及以上级别的日志信息。这在生产环境中很有用,可以过滤掉一些不太重要的DEBUG级别的日志。
QLoggingCategory::setFilterRules("qt.example.main.info=false");
qCDebug(QT_EXAMPLE_MAIN) << "Too verbose"; //不会输出
qCWarning(QT_EXAMPLE_MAIN) << "Important warning"; //会输出
总之,在开发Qt应用的过程中,我们需要时刻保持对代码"内疾外馁"的警惕,及时发现并排查问题。QLoggingCategory这一强大的日志框架将是你的得力助手,指引你走出调试困境,让应用程序运转更加健康稳定。
相关文章:
Qt5.14.2 揭秘Qt日志神器高效诊断程序潜在隐疾
对程序员而言,代码中的bug往往如同无影无踪的隐疾,影响着程序的健康运行。而及时有效的诊断手段则是治疗这些隐疾的良药。今天,我们将一窥Qt日志框架QLoggingCategory的神奇功效,探究它如何为你的Qt应用程序构筑坚实的诊断防火墙。…...
Mac上设置环境变量PATH
一、配置文件有哪些 在Mac系统中,环境变量的配置文件主要包括以下几个: 文件名称描述/etc/paths系统级别的配置文件,系统启动时会加载它。/etc/profile系统级别的配置文件,所有用户登录时都会读取该文件。~/.bash_profile用户级别…...

Redis 全景图(1)--- 关于 Redis 的6大模块
这是我第一次尝试以长文的形式写一篇 Redis 的总结文章。这篇文章我想写很久了,只是一直碍于我对 Redis 的掌握没有那么的好,因此迟迟未动笔。这几天,我一直在看各种不同类型的 Redis 文章,通过阅读这些文章,引发了我对…...

Lambda表达式,Stream流
文章目录 Lambda表达式作用前提函数式接口特点 语法省略模式和匿名对象类的区别 Stream流思想作用三类方法获取方法单列集合(Collection[List,Set双列集合Map(不能直接获取)数组同一类型元素(Stream中的静态方法) 常见的中间方法终结方法收集方法 Optional类 Lambda表达式 作用…...

Apache Hive的基本使用语法(一)
一、数据库操作 创建数据库 create database if not exists myhive;查看数据库 use myhive; desc database myhive;创建数据库并指定hdfs存储 create database myhive2 location /myhive2;删除空数据库(如果有表会报错) drop database myhive;…...

Python爬虫详解:原理、常用库与实战案例
前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家:https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言引言:一、爬虫原理1. HTTP请求与响应过程2. 常用爬虫技术 二、P…...

搭建跨境电商电商独立站如何接入1688平台API接口|通过1688API接口采集商品通过链接搜索商品下单
接口设计|接口接入 对于mall项目中商品模块的接口设计,大家可以参考项目的Swagger接口文档,以Pms开头的接口就是商品模块对应的接口。 参数说明 通用参数说明 参数不要乱传,否则不管成功失败都会扣费url说明……d.cn/平台/API类型/ 平台&…...

【GlobalMapper精品教程】073:像素到点(Pixels-to-Points)从无人机图像轻松生成点云
文章目录 一、工具介绍二、生成点云三、生成正射四、生成3D模型五、注意事项一、工具介绍 Global Mapper v19引入的新的像素到点工具使用摄影测量原理,从重叠图像生成高密度点云、正射影像及三维模型。它使LiDAR模块成为已经功能很强大的的必备Global Mapper扩展功能。 打开…...
论文复现1:Mobilealoha
abstract:从人类演示中进行的模仿学习在机器人技术中表现出了令人印象深刻的表现。然而,大多数结果都集中在桌面操作上,缺乏一般有用任务所需的移动性和灵活性。在这项工作中,我们开发了一种用于模仿双手且需要全身控制的移动操纵任务的系统。我们首先推出 Mobile ALOHA,这…...

pycharm复习
目录 1.基础语法 2.判断语句 3.while循环 4.函数 5.数据容器 1.基础语法 1.字面量 2.注释: 单行注释# 多行注释" " " " " " 3.变量: 变量名 变量值 print:输出多个结果&#x…...

【SQLSERVER】批量导出所有作业或链接脚本
1.在Microsoft SQL Server Management Studio中选择–>视图(v)–>对象资源管理器详细信息(F7) 2.SSMS图形界面,左侧是“对象资源管理器”,右侧是“对象资源管理器详细信息”界面 3.左侧的“对象资源管理器”界面–>点击“SQLSserver代理”–…...

函数参数缺省和内联函数【C++】
文章目录 函数参数缺省函数参数缺省的条件和要求 内联函数内联函数的工作原理内联函数的定义方法内联函数的要求解决方法:直接在.h中定义内联函数的函数体 内联函数再Debug模式下默认是不展开的 函数参数缺省 顾名思义:可以少传一个/多个参数给函数&…...

javaWeb城市公交查询系统的设计与实现
一、选题背景 随着低碳生活的普及,人们更倾向于低碳环保的出行方式,完善公交系统无疑具有重要意义。公交是居民日常生活中最常使用的交通工具之一,伴随着我国经济繁荣和城市人口增长,出行工具的选择也变得越来越重要。政府在公共…...

企业案例:金蝶云星空对接旺店通·企业版
某知名化妆品企业,主要专注于化妆品,护肤品等研发,销售,生产于一体化的企业。企业的业务模式涉及比较广,有2B,2C和国内外电商领域。由于对内部业务流程的连贯性和数据的准确性比较关注。财务系统用的金蝶云星空&#x…...

wpsword求和操作教程
wpsword求和怎么操作: 1、首先,单纯的数据是无法求和的,所以我们必须要“插入”一个“表格” 2、接着将需要求和的数据填入到表格中。 3、填完后,进入“布局”选项卡。 4、然后打开其中的“公式” 5、在其中选择求和公式“SUM”并…...
Android 手机部署whisper 模型
Whisper 是什么? “Whisper” 是一个由OpenAI开发的开源深度学习模型,专门用于语音识别任务。这个模型能够将语音转换成文本,支持多种语言,并且在处理不同的口音、环境噪音以及跨语言的语音识别方面表现出色。Whisper模型的目标是提供一个高效、准确的工具,以支持自动字幕…...

通信术语:初学者入门指南(二)
1.SAR:Synthetic Aperture Radar合成孔径雷达,是一种雷达系统,通常用于地球或行星的遥感成像。相较于传统的实孔径雷达,SAR 通过在相对较长的时间内,对来自同一地点的多个雷达反射信号进行综合处理,实现了更…...
Java中使用MQTT客户端库实现TLS/SSL加密通信的示例
以下是一个完整的Java代码示例,展示了如何使用Eclipse Paho MQTT客户端库在Java中实现TLS/SSL加密的MQTT通信。在这个示例中,我们将创建一个简单的MQTT客户端,该客户端连接到支持TLS/SSL的MQTT代理,并发布和订阅消息。 首先&…...
【m122】webrtc的比较
uint16的比较IsNewerSequenceNumber 和 u32的比较LatestTimestamp G:\CDN\WEBRTC-DEV\libwebrtc_build\src\modules\include\module_common_types_public.h/** Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.** Use of this source code is governed …...

axios发送get请求但参数中有数组导致请求路径多出了“[]“的处理办法
一、情况 使用axios发送get请求携带了数组参数时,请求路径中就会多出[]字符,而在后端也会报错 二、解决办法 1、安装qs 当前项目的命令行中安装 npm install qs2、引入qs库(使用qs库来将参数对象转换为字符串) // 全局 import qs from qs Vue.proto…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...