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…...
vue3的mars3d点击右键出现置顶、向下、向上等选项
效果图 下载插件 imengyu/vue3-context-menu npm i imengyu/vue3-context-menu在要使用的页面中引入一下代码 import "imengyu/vue3-context-menu/lib/vue3-context-menu.css"; import ContextMenu from "imengyu/vue3-context-menu";如果是使用在树的…...
MySQL进阶-----SQL提示与覆盖索引
目录 前言 一、SQL提示 1.数据准备 2. SQL的自我选择 3.SQL提示 二、覆盖索引 前言 MySQL进阶篇的索引部分基本上要结束了,这里就剩下SQL提示、覆盖索引、前缀索引以及单例联合索引的内容。那本期的话我们就先讲解SQL提示和覆盖索引先,剩下的内容就…...
机器学习模型之K近邻
K近邻(K-Nearest Neighbors,KNN)是一种基本的机器学习算法,它既可以用于分类问题,也可以用于回归问题。KNN算法的核心思想非常简单:一个新样本的分类或回归值取决于它与训练集中最相似的K个样本的多数类别或…...
强化基础-Java-泛型基础
什么是泛型? 泛型其实就参数化类型,也就是说这个类型类似一个变量是可变的。 为什么会有泛型? 在没有泛型之前,java中是通过Object来实现泛型的功能。但是这样做有下面两个缺陷: 1 获取值的时候必须进行强转 2 没有…...
c++20协程详解(一)
前言 本文是c协程第一篇,主要是让大家对协程的定义,以及协程的执行流有一个初步的认识,后面还会出两篇对协程的高阶封装。 在开始正式开始协程之前,请务必记住,c协程 不是挂起当前协程,转而执行其他协程&a…...
go: go.mod file not found in current directory or any parent directory.如何解决?
这个错误表明你正在执行 go get 命令,但是当前目录或任何父目录中都找不到 go.mod 文件。这可能是因为你的项目还没有使用 Go Modules 进行管理。 要解决这个问题,有几种方法: go mod init <module-name> 其中 <module-name>…...
Go-Gin全局错误处理中间件
为了防止报错引起Gin服务挂掉以及错误日志记录,我们使用全局错误中间件进行管理。 package middlewareimport ("ToDoList/global""github.com/gin-gonic/gin""go.uber.org/zap""net""net/http""net/http/h…...
图神经网络实战(6)——使用PyTorch构建图神经网络
图神经网络实战(6)——使用PyTorch构建图神经网络 0. 前言1. 传统机器学习与人工智能2. 人工神经网络基础2.1 人工神经网络组成2.2 神经网络的训练 3. 图神经网络4. 使用香草神经网络执行节点分类4.1 数据集构建4.2 模型构建4.3 模型训练 5. 实现香草图神…...
【Flutter】windows环境配置
windows 11 环境 官方教程 配置了flutter 环境变量在系统的path里 bin 路径。 死活没反应 关闭了git关闭了dart.exe关闭了vs还是不行卸载重新来 新版git flutter doctor 还需要android 环境...
毕马威:《智慧之眼:开启汽车感知新时代》
在全球科技飞速发展和产业革新的大潮中,汽车产业正在以前所未有的速度向网联化、智能化的方向转型。汽车传感器作为智能联网汽车发展的关键环节之一,扮演着举足轻重的角色。 毕马威一直关注汽车产业的变化与发展,为了更好地为汽车行业赋能&a…...
电子科技网站模板/广州最新政策
起因很简单,也很悲剧。工厂大门门卫那里没有电话线,也没网线,成了一个没有信息的“孤岛”。没网线也就罢了,因为有WIFI。全厂区都覆盖了WIFI无线局域网。电话可不行。尤其是前台和门卫有时要沟通。于是采购了两部WIFI IP电话机。前…...
浩森宇特北京网站设计/百度一下图片识别
gitlab通过rpm包安装后,默认存储位置在/var/opt/gitlab/git-data/repositories,通常需要更改此路径到单独的一个分区来存储仓库的数据。 例如我这里把数据存放到/data/gitlab目录下 创建/data/gitlab目录 mkdir -p /data/gitlab 修改gitlab配置文件&…...
长沙做网站seo优化外包/如何在百度发布广告
:%!python -m json.tool https://www.jianshu.com/p/91c2d7a54eb7...
广州哪家做网站好/网站开发软件
1 编辑: paste/sort/uniq/cut/tr/splitpaste 将文件按照行合并,默认分隔符为tab。用-d指定分隔符。rootubuntu:/home/fsj/templates# cat 1.txtbcaedfrootubuntu:/home/fsj/templates# cat 2.txt3245111rootubuntu:/home/fsj/templates# paste 1.txt 2.txtb 3c 2a 4…...
网站官网建设企业/全网推广代理
2019独角兽企业重金招聘Python工程师标准>>> 浏览器禁止js跨域取数据,可能在两个方面防止,一是ajax取数据的时候发现不是同源,阻止获取数据;另外一种是ajax获取了数据,但是浏览器禁止这些数据在当前域下显示…...
保定建网站需要多少钱/全网网站推广
php中在做文件下载的时候,其中要加上这么一些header信息: 1 2 3 4 header("Content-type: application/octet-stream"); header("Accept-Ranges: bytes"); header("Accept-Length:".$fileSize); //请用Content-Length he…...