Qt日志输出及QsLog日志库

news/2024/9/25 5:38:05/

目录

  • Qt日志输出及QsLog日志库
    • 日志输出
      • 格式化日志
      • 普通格式化
      • 条件格式化
      • 环境变量设置格式化
      • 日志输出位置
      • 日志输出对象信息
      • 禁用输出
    • QsLog日志库
      • 使用方法
        • 1. 将QsLog目录添加到项目中
        • 2. 配置CMakeLists.txt文件
        • 3. 配置.pro文件
        • 4. 日志记录器的配置
        • 5. 运行程序
        • 6. 启用行号和文件名
          • CMakeLists.txt
          • .pro 文件
        • 7. 禁用日志输出
          • CMakeLists.txt
          • .pro 文件

Qt日志输出及QsLog日志库

日志输出

Qt提供了多种方式进行日志输出,常用的有qDebug(), qInfo(), qWarning(), qCritical()qFatal()

这些输出函数定义在#include <QDebug>中,并且可以像标准C++的输出流一样使用。

分类说明
qDebug()用于调试信息输出,通常用于开发阶段输出调试信息。
qInfo()用于一般的信息输出,适合输出一般运行状态信息。
qWarning()用于警告信息输出,通常用于提示可能的问题。
qCritical()用于严重错误信息输出,通常用于提示不可恢复的错误。
qFatal()用于致命错误信息输出,通常会中止程序的运行。

C风格输出

qDebug("我是%s,今年%d岁了~","qDebug",20);
qInfo("老铁%d",666);
qWarning("hello %s","warning");
qCritical("helo %s","critical");
qFatal("hello %s","qFatal");		// 注意:qFatal 会中断程序执行

C++风格

qDebug()<<"qDebug";
qInfo()<<"qInfo";
qWarning()<<"qWarnning";
qCritical()<<"qCritical";
#qFatal()<<"qFatal";			   // qFatal()不能用"<<"输出

格式化日志

默认情况下,日志格式是只输出对应的日志内容没有额外信息的。可以通过修改环境变量QT_MESSAGE_PATTERN或者调用方法 qSetMessagePattern来修改日志的输出格式。日志格式中常用的占位符号如下所示:

%{appname}     应用程序的名称(QCoreApplication::applicationName())
%{category}    日志所处的领域
%{file}        打印该日志的文件路径 
%{function}    打印日志的函数
%{line}        打印日志在文件中的行数
%{message}     日志的内容
%{pid}         打印日志的程序的PID(QCoreApplication::applicationPid())
%{threadid}    打印日志的线程ID
%{qthreadptr}  打印日志的线程指针
%{type}        日志级别("debug", "warning", "critical" or "fatal")
%{time process}日志发生时程序启动了多久
%{time boot}   日志发生时系统启动了多久
%{time [format]}以固定时间格式输出日志打印的时间,默认为QISODate格式

普通格式化

格式化日志方法如下:

#include <QApplication>
#include <QDebug>int main(int argc, char *argv[])
{QApplication a(argc, argv);qSetMessagePattern("%{time yyyy-MM-dd hh:mm:ss} [%{type}] %{file} [%{function}(%{line})]  %{message}");qInfo()<<"info";qDebug()<<"debug";qWarning()<<"warning";qCritical()<<"Critical";return a.exec();
}

输出的日志内容如下:

2024-09-19 10:35:25 [info] ..\..\main.cpp [qMain(9)]  info
2024-09-19 10:35:25 [debug] ..\..\main.cpp [qMain(10)]  debug
2024-09-19 10:35:25 [warning] ..\..\main.cpp [qMain(11)]  warning
2024-09-19 10:35:25 [critical] ..\..\main.cpp [qMain(12)]  Critical

注意:在Release模式下,文件名、函数名、行号获取不到,需要添加编译时宏QT_MESSAGELOGCONTEXT

条件格式化

在消息参数中还可以使用条件,给不同级别的日志指定不同的格式,语法如下:

%{if-<debug | info | warning | critical | fatal>} ... %{endif}

比如,只想在debug级别下输出文件名、函数名以及行号,代码格式如下:

qSetMessagePattern("%{time yyyy-MM-dd hh:mm:ss} [%{type}] %{if-debug}%{file}%{endif} %{if-} [%{function}(%{line})]  %{message}");

环境变量设置格式化

格式也可以在运行时通过设置QT_MESSAGE_PATTERN环境变量来更改;

如果调用了qSetMessagePattern()并且设置了QT_MESSAGE_PATTERN,则环境变量优先。

qputenv("QT_MESSAGE_PATTERN", QByteArray("%{time yyyy-MM-dd hh:mm:ss} [%{type}] %{file} [%{function}(%{line})]  %{message}"));

日志输出位置

Qt 默认的日志内容是输出到终端的,不会输出到文件里面,如果需要将日志内容输出到文件中,需要通过qInstallMessageHandler设置日志信息处理函数。使用方法如下:

#include <QApplication>
#include <QFile>
#include <QDebug>
#include <QTextStream>// 日志消息的处理函数
void logMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &message)
{// 获取格式化的日志信息QString typeStr = qFormatLogMessage(type, context, message);// 可以根据日志的级别进行过滤(比如不想要 Debug 输出,可以直接 return)QString levelText;switch (type){case QtDebugMsg:levelText = "Debug";// return;	// 加上 return 之后就不会打印 debug 日志了break;case QtInfoMsg:levelText = "Info";break;case QtWarningMsg:levelText = "Warning";break;case QtCriticalMsg:levelText = "Critical";break;case QtFatalMsg:levelText = "Fatal";break;}QFile file("log.log");file.open(QIODevice::WriteOnly | QIODevice::Append);QTextStream textStream(&file);textStream << typeStr << "\n";
}int main(int argc, char *argv[])
{QCoreApplication app(argc, argv);qSetMessagePattern("%{time yyyy-MM-dd hh:mm:ss} [%{type}]%{if-warning}[%{function}]%{endif}%{if-fatal}[%{function}--%{line}]%{endif}:%{message}");qInstallMessageHandler(logMessageHandler);qDebug() << "debug info occurred";qInfo() << "call other function";qWarning() << "doesn't work";qFatal("fatal error");return app.exec();
}

如果需要关闭日志输出,取消之前注册的日志处理函数,可以调用qInstallMessageHandler(nullptr);

日志输出对象信息

在调试一些复杂对象的时候,需要输出对象的成员信息到日志当中。但是默认情况下 Qt 的日志库是不支持输出自定义对象的。这时候可以通过重写操作符实现对自定义对象的日志输出。使用方法如下:

class Person
{
public:QString name;quint8   age;inline friend QDebug operator<<(QDebug debug,const Person& person){debug<<"Person("<<person.name<<","<<person.age<<")";return debug;}
};int main(int argc,char*argv[])
{QCoreApplication app(argc, argv);Person person{"shayebushi",18};  // 输出:Person( "shayebushi" , 18 )qDebug()<<person;return app.exec();
}

禁用输出

在开发或者调试时,我们必须借助日志来进行判断,但是当程序需要发布时,调试的日志信息将不再需要,此时如果把代码删除,又不太方便,万一出bug了,又需要调试了呢?

所以Qt提供了禁用qInfoqWarningqDebug输出的宏,qCriticalqFatal是错误不能屏蔽!

CMakeLists.txt 文件中禁用日志输出

在CMakeLists.txt文件中添加如下三行,即可禁用qInfoqWarningqDebug的输出。

add_compile_definitions(QT_NO_INFO_OUTPUT)
add_compile_definitions(QT_NO_DEBUG_OUTPUT)
add_compile_definitions(QT_NO_WARNING_OUTPUT)
#或
add_compile_definitions(QT_NO_INFO_OUTPUTQT_NO_DEBUG_OUTPUTQT_NO_WARNING_OUTPUT)

.pro 文件中禁用日志输出

在 .pro 文件中添加如下三行,即可禁用 qInfoqWarningqDebug 的输出。

DEFINES += QT_NO_INFO_OUTPUT
DEFINES += QT_NO_DEBUG_OUTPUT
DEFINES += QT_NO_WARNING_OUTPUT

QsLog日志库

QsLog是一个基于Qt的QDebug类的易于使用的记录器。QsLog是在MIT许可下以开源形式发布的。

QsLog Github下载

QsLog的特征:

  • 六个日志级别(从跟踪到致命);
  • 运行时可配置的日志级别阈值;
  • 关闭日志记录时的最小开销;
  • 支持多个目标,附带文件和调试目标;
  • 线程安全;
  • 支持现成的常见Qt类型的日志记录;
  • 小依赖:直接把它放到你的项目中。

使用方法

1. 将QsLog目录添加到项目中

将QsLog目录直接拷贝到项目的根目录中,与CMakeLists.txt.pro文件同级。

QsLog目录

2. 配置CMakeLists.txt文件

打开项目的CMakeLists.txt文件,输入如下代码:

# 添加子目录
add_subdirectory(./QsLog)# 添加可执行文件
add_executable(QsLog_test main.cpp)# 把QsLog库链接到目标 QsLog_test
target_link_libraries(QsLog_test Qt${QT_VERSION_MAJOR}::Core QsLog)
3. 配置.pro文件

如果你使用的是qmake构建系统,打开项目的.pro文件,输入如下代码:

# 指定包含QsLog目录
include(QsLog/QsLog.pri)
4. 日志记录器的配置

在你的代码中进行日志记录器的配置:

#include <QCoreApplication>
#include "QsLog/QsLog.h"
#include "QsLog/QsLogDest.h"int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);using namespace QsLogging;// 1. 获取日志单例Logger &logger = Logger::instance();logger.setLoggingLevel(QsLogging::DebugLevel);// 2. 添加两个日志输出目的地DestinationPtr file_dest(DestinationFactory::MakeFileDestination("log.txt"));DestinationPtr console_dest(DestinationFactory::MakeDebugOutputDestination());logger.addDestination(file_dest);logger.addDestination(console_dest);// 3. 开始日志记录QLOG_DEBUG() << "Program started";return a.exec();
}
5. 运行程序

运行程序,控制台会输出日志,同时指定的文件也会记录日志内容。日志内容如下:

DEBUG 2024-09-19T18:07:04.434 Program started 
6. 启用行号和文件名

输出的日志记录默认是没有文件名和行号的,如果需要,在CMakeLists.txt.pro文件中添加宏定义即可。

CMakeLists.txt
# 开启行号
add_compile_definitions(QS_LOG_LINE_NUMBERS)
.pro 文件
# 开启行号
DEFINES += QS_LOG_LINE_NUMBERS
7. 禁用日志输出

如果要禁用日志输出,定义宏 QS_LOG_DISABLE 即可。

CMakeLists.txt
# 禁用日志输出
add_compile_definitions(QS_LOG_DISABLE)
.pro 文件
# 禁用日志输出
DEFINES += QS_LOG_DISABLE

http://www.ppmy.cn/news/1530143.html

相关文章

【计算机网络 - 基础问题】每日 3 题(二十)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏&…

性能监控之Python实战SkyWalking链路追踪

文章目录 一、介绍二、SkyWalking支持的语言三、SkyWalking安装3.1 前提准备3.2 先安装ElasticSearch7.X3.3 Skywalking-OAP 安装3.4 Skywalking-UI 界面安装3.5 访问页面检查SkyWalking是否可以访问 四、Python 项目接入SkyWalking4.1 演示项目代码4.2 验证 sw-python4.3 配置…

关于wordPress中的用户登录注册等问题

前言 大家在做类似的功能的时候&#xff0c;有没有相关的疑问。那就是我都已经选择好了相应的主题和模版&#xff0c;但是为什么都没有用户注册和用户登录的页面存在呢&#xff1f; WordPress默认情况下不提供用户注册和登录功能的原因是它最初是作为一个博客平台开发的&…

AjAX(简介以及一些用法)

AJAX 1. 简介 什么是 Ajax Ajax 的全称是 Asynchronous JavaScript And XML &#xff08;异步 JavaScript 和 XML &#xff09;我们可以理解为&#xff1a;在网页中 利用 XMLHttpRequest 对象和服务器进行数据交互的方式就是 Ajax &#xff0c;它可以帮助我们轻松实现网页…

Python画笔案例-059 绘制甩曲彩点动图

1、绘制甩曲彩点动图 通过 python 的turtle 库绘制 甩曲彩点动图,如下图: 2、实现代码 绘制甩曲彩点动图,以下为实现代码: """甩曲彩点动图.py """ import time import turtlecs = [red,orange,

优选算法之 分治-快排

目录 一、颜色分类 1. 题目链接&#xff1a;75. 颜色分类 2. 题目描述&#xff1a; 3. 解法&#xff08;快排思想 - 三指针法使数组分三块&#xff09; &#x1f334;算法思路&#xff1a; &#x1f334;算法流程&#xff1a; &#x1f334;算法代码&#xff1a; 二、快…

多级目录SQL分层查询

需求&#xff1a;有多级目录&#xff0c;而目录的层级是不固定的&#xff0c;如下图所示&#xff1a; 数据结构&#xff1a; sql语句&#xff1a; <select id"getList" resultType"com.hikvision.idatafusion.dhidata.bean.vo.knowledgebase.KnowledgeBaseT…

ubuntu内网穿透后在公网使用ssh登录

需求&#xff1a; 我有一台内网可以通过ssh 22端口访问的设备操作系统是ubuntu server我还有1台拥有公网IP的服务器&#xff0c;IP地址是 6.66.666.6666我想随时从其他网段通过ssh访问我的ubuntu server设备 实现&#xff1a; 工具准备&#xff1a;frp 网址&#xff1a;https…