Qslog开源库使用

Qslog源码下载地址:https://github.com/victronenergy/QsLog

1.QSLOG使用方式

(1)源码集成

在你的工程中,直接包含QsLog.pri文件,进行源码集成。当然你也可以包含QsLog.pri后,编译为xx.dll,在应用工程中去调用xx.dll。

(2)动态库集成

编译QsLogSharedLibrary.pro,生成动态链接库QsLog2.dll,在你的工程中进行调用。

2.日志级别

支持六个日志级别,优先级从低到高依次为:Trace、Debug、Info、Warn、Error、Fatal、Off。如下:

enum Level
{TraceLevel = 0,DebugLevel,InfoLevel,WarnLevel,ErrorLevel,FatalLevel,OffLevel
};
  • Trace:跟踪,最低等级的,用于打开所有日志记录。
  • Debug:调试,打印一些细粒度调试运行信息。
  • Info:信息,打印粗粒度信息,突出强调程序的运行过程。打印一些感兴趣或者重要的信息,可用于环境中输出程序运行的一些重要信息,但不能滥用,避免打印过多日志。
  • Warn:警告,表明会出现潜在错误的情形,有些信息不是错误信息,但是也要给程序员的一些提示。
  • Error:错误,指出虽然发生错误,但仍然不影响系统的继续运行。打印错误和异常信息。
  • Fatal:致命的,发生严重错误,将导致应用程序的退出。这个级别比较高,程序直接停止运行了。
  • Off:最高等级的,用于关闭所有日志记录。

可以通过setLoggingLevel()设置记录日志的级别。

void setLoggingLevel(Level newLevel)

注意:

一般我们可以将日志级别保存到配置文件,以便程序发布后,可通过修改配置来改变记录日志级别。

3.日志输出目的地

QsLog的使用很简单,在我们自己的工程中直接include它的QsLog.pri文件,然后源文件中包含QsLog.h就可以使用了。

(1)输出到文件(支持文件分割)

// 测试文件为目的地
void test_output_file()
{// 初始化日志机制Logger& logger = Logger::instance();logger.setLoggingLevel(QsLogging::TraceLevel);// 添加文件为目的地const QString sLogPath(QDir(QApplication::applicationDirPath()).filePath("log.txt"));DestinationPtr fileDestination(DestinationFactory::MakeFileDestination(sLogPath, EnableLogRotation, MaxSizeBytes(512*1024), MaxOldLogCount(5)));logger.addDestination(fileDestination);// 打印日志QLOG_TRACE() << "1-trace msg";QLOG_DEBUG() << "2-debug msg";QLOG_INFO() << "3-info msg";QLOG_WARN() << "4-warn msg";QLOG_ERROR() << "5-error msg";QLOG_FATAL()  << "6-fatal msg";QsLogging::Logger::destroyInstance();
}
  • 代码很简单,setLoggingLevel()设置记录的日志级别;

目前为TraceLevel,则日志级别比TraceLevel高的都会输出到文件;

若为ErrorLevel,则只有"5-error msg"和"6-fatal msg"这2条会输出。

  • 然后设置文件名和输出目的地。其中目的地是由DestinationFactory::MakeFileDestination()函数进行构造的,其原型为:
static DestinationPtr MakeFileDestination(const QString& filePath,LogRotationOption rotation = DisableLogRotation,const MaxSizeBytes &sizeInBytesToRotateAfter = MaxSizeBytes(),const MaxOldLogCount &oldLogsToKeep = MaxOldLogCount()
);

函数参数含义:

  • filePath: 日志文件名
  • rotation: 取值DisableLogRotation和EnableLogRotation,

前者表示禁止日志文件分割,即日志始终往一个文件中写入。

后者表示启用日志文件分割,此时sizeInBytesToRotateAfter和oldLogsToKeep参数才有意义。

  • sizeInBytesToRotateAfter: 每个日志文件的字节数大小限制,即到达此大小后,自动新建文件,在新文件中进行写入。
  • oldLogsToKeep: 旧日志文件保留(备份)个数,超过此数量,自动删除最久远文件,备份文件最多支持10个。
  • 若为2,则如下三个文件中内容,按照时间先后顺序排列为:log.txt.2->log.txt.1->log.txt,在log.txt中为最新日志,log.txt.1为次新,log.txt.2为最久远日志。
  • 若此时log.txt超过sizeInBytesToRotateAfter限制,则会发生log.txt.2被删除,log.txt.1被改名log.txt.2,log.txt被改名log.txt.1,新建log.txt。

(2)输出到控制台STDOUT

// 测试stdout为目的地
void test_output_stdout()
{// 初始化日志机制Logger& logger = Logger::instance();logger.setLoggingLevel(QsLogging::TraceLevel);// 添加stdout为目的地DestinationPtr debugDestination(DestinationFactory::MakeDebugOutputDestination());logger.addDestination(debugDestination);// 打印日志QLOG_TRACE() << "1-trace msg";QLOG_DEBUG() << "2-debug msg";QLOG_INFO() << "3-info msg";QLOG_WARN() << "4-warn msg";QLOG_ERROR() << "5-error msg";QLOG_FATAL()  << "6-fatal msg";QsLogging::Logger::destroyInstance();
}

(3) 输出到处理函数

void logFunction(const QString &message, QsLogging::Level level)
{qDebug() << "From log function: " << qPrintable(message) << " " << static_cast<int>(level);
}// 测试函数为目的地
void test_output_function()
{// 初始化日志机制Logger& logger = Logger::instance();logger.setLoggingLevel(QsLogging::TraceLevel);// 添加函数为目的地DestinationPtr functorDestination(DestinationFactory::MakeFunctorDestination(&logFunction));logger.addDestination(functorDestination);// 打印日志QLOG_TRACE() << "1-trace msg";QLOG_DEBUG() << "2-debug msg";QLOG_INFO() << "3-info msg";QLOG_WARN() << "4-warn msg";QLOG_ERROR() << "5-error msg";QLOG_FATAL()  << "6-fatal msg";QsLogging::Logger::destroyInstance();
}

输出到函数,该函数需要定义为如下类型:

typedef void (*LogFunction)(const QString &message, Level level);

(4)输出到QTEXTEDIT控件

除了上面的输出方式,还可以输出到一个QObject对象上,主要是通过信号槽机制,将打印日志发送到QObject的槽函数进行处理。

void MainWindow::writeLog(const QString &message, int level)
{ui->textEdit->append(message + " " + QString::number(level));
}
// 测试QObject为目的地
void test_output_qobject(MainWindow* window)
{// 初始化日志机制Logger& logger = Logger::instance();logger.setLoggingLevel(QsLogging::TraceLevel);// 添加QObject为目的地DestinationPtr objectDestination(DestinationFactory::MakeFunctorDestination(window, SLOT(writeLog(QString,int))));logger.addDestination(objectDestination);// 打印日志QLOG_TRACE() << "1-trace msg";QLOG_DEBUG() << "2-debug msg";QLOG_INFO() << "3-info msg";QLOG_WARN() << "4-warn msg";QLOG_ERROR() << "5-error msg";QLOG_FATAL()  << "6-fatal msg";QsLogging::Logger::destroyInstance();
}

输出到QObject时,需要定义其槽函数,为如下类型:

void xxxx(const QString &message, int level)

写本例子时,发现TRACE信息不能输出到QObject,是因为QsLogDestFunctor.cpp文件中,write函数有个bug,如下:

void QsLogging::FunctorDestination::write(const QString &message, QsLogging::Level level)
{if (mLogFunction)mLogFunction(message, level);if (level > QsLogging::TraceLevel)emit logMessageReady(message, static_cast<int>(level));
}

应将>改为>=,修改后即可解决,如下:

void QsLogging::FunctorDestination::write(const QString &message, QsLogging::Level level)
{if (mLogFunction)mLogFunction(message, level);if (level >= QsLogging::TraceLevel)emit logMessageReady(message, static_cast<int>(level));
}
4.打印源文件名称和行号

在QsLog.pri文件中

DEFINES += QS_LOG_LINE_NUMBERS

打开此宏定义,重新编译,即可打印带源文件名称和行号的日志。如下:

5.禁止日志记录

禁用日志记录,有时候关闭日志记录是有必要的。可以通过3种方式实现:

  • 全局地,在编译时,通过在QsLog.pri文件,打开DEFINES += QS_LOG_DISABLE宏定义。
  • 全局地,在运行时,通过将日志级别设置为关闭,即setLoggingLevel(QsLogging::OffLevel)。
  • 在编译时,通过在目标文件中包含QsLogDisableForThisFile.h,为每个文件创建一个。
6.线程安全

使用日志宏进行打印日志是线程安全的,日志宏如下:

QLOG_TRACE() << "1-trace msg";
QLOG_DEBUG() << "2-debug msg";
QLOG_INFO() << "3-info msg";
QLOG_WARN() << "4-warn msg";
QLOG_ERROR() << "5-error msg";
QLOG_FATAL()  << "6-fatal msg";

这在前面我们已经使用过了。

如setLoggingLevel()、addDestination()函数不是线程安全的。

7.日志的异步打印

所谓的异步打印,其实就是单独开一个线程来专门写日志。

在QsLog.pri文件中

DEFINES += QS_LOG_SEPARATE_THREAD

打开此宏定义,重新编译,日志内容就会在单独的线程中排队并写入

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/652375.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MVCC原理讲解(深入浅出)

目录 一、什么是MVCC 二、当前读、快照读都是什么鬼 三、当前读 四、快照读 五、数据库的并发场景 六、MVCC解决并发的哪些问题 1.解决问题如下&#xff1a; 七、MVCC的实现原理 1.版本链 八、undo日志 1.undo log 的用途 2.undo log主要分为两种 九、Read View…

简洁思路推理 KMP 算法——子字符串匹配

例题 28. 找出字符串中第一个匹配项的下标 暴力遍历解法 枚举原串 ss 中的每个字符作为「发起点」&#xff0c;每次从原串的「发起点」和匹配串的「首位」开始尝试匹配&#xff1a; 匹配成功&#xff1a;返回本次匹配的原串「发起点」。 匹配失败&#xff1a;枚举原串的下一个…

UI自动化搭建背景及优劣势分析

经常有人会问&#xff0c;什么样的项目才适合进行UI自动化测试呢&#xff1f;UI自动化测试相当于模拟手工测试&#xff0c;通过程序去操作页面上的控件。而在实际测试过程中&#xff0c;经常会遇到无法找到控件&#xff0c;或者因控件定义变更而带来的维护成本等问题。 哪些场…

Docker—入门及Centos7安装

1、Docker入门 1.1、Docker是什么&#xff1f; Docker是基于Go语言实现的云开源项目。 Docker的主要目标是“Build&#xff0c;Ship&#xff0c;and Run Any App,Anywhere”&#xff0c;也就是通过对应组件的封装、分发、部署、运行等生命周期的管理&#xff0c;使用户的APP&…

docker环境搭建及其安装常用软件

centos安装docker Install Docker Engine on CentOS | Docker Docs 下载docker sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo yum install -y docker-ce docker-ce-cli containerd.io…

MongoDB本地部署并结合内网穿透实现公网访问本地数据库

文章目录 前言1. 安装数据库2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射2.3 测试随机公网地址远程连接 3. 配置固定TCP端口地址3.1 保留一个固定的公网TCP端口地址3.2 配置固定公网TCP端口地址3.3 测试固定地址公网远程访问 4. 结语 前言 MongoDB是一个基于分布式文件…

TCP 三次握手 四次挥手以及滑动窗口

TCP 三次握手 简介&#xff1a; TCP 是一种面向连接的单播协议&#xff0c;在发送数据前&#xff0c;通信双方必须在彼此间建立一条连接。所谓的 “ 连接” &#xff0c;其实是客户端和服务器的内存里保存的一份关于对方的信息&#xff0c;如 IP 地址、端口号等。 TCP 可以…

【c语言】详解操作符(下)

前言&#xff1a; 在上文中&#xff0c;我们已经学习了 原码、反码、补码、移位 操作符、移位操作符、位操作符、逗号表达式、下标访问[ ]、函数调用&#xff08; &#xff09;&#xff0c;接下来我们将继续学习剩下的操作符。 1. 结构成员访问操作符 1.1 结构体成员的直接访…

台式电脑的ip地址在哪里找

在网络连接方面&#xff0c;IP地址是非常重要的信息&#xff0c;它是用于标识网络设备的唯一地址。对于台式电脑用户来说&#xff0c;了解自己设备的IP地址是非常有必要的&#xff0c;因为它可以帮助解决网络连接问题&#xff0c;进行远程访问和共享文件等功能。本文将指导读者…

深度学习知识

context阶段和generation阶段的不同 context阶段&#xff08;又称 Encoder&#xff09;主要对输入编码&#xff0c;产生 CacheKV(CacheKV 实际上记录的是 Transformer 中 Attention 模块中 Key 和 Value 的值&#xff09;&#xff0c;在计算完 logits 之后会接一个Sampling 采…

幻兽帕鲁服务器多少钱?4核16G支持32人在线吗?

4核16G服务器是幻兽帕鲁Palworld推荐的配置&#xff0c;阿里云和腾讯云均推出针对幻兽帕鲁的4核16G服务器&#xff0c;阿里云4核16G幻兽帕鲁专属服务器32元1个月、66元3个月&#xff0c;腾讯云4核16G14M服务器66元1个月、277元3个月、1584元一年。云服务器吧yunfuwuqiba.com分享…

vue笔记(一):部署

首 文档 安装 1、安装nodejs&#xff08;链接&#xff09;&#xff0c;18.0以上版本。 2、在想要创建项目的目录下执行命令 npm create vuelatest 按提示创建项目&#xff0c;其中vue router是实现路由功能&#xff0c;pinia实现组件之间共享数据。如果项目需要两个功能建…

python-自动化篇-运维-监控-简单实例-道出如何使⽤Python进⾏网络监控?

如何使⽤Python进⾏⽹络监控&#xff1f; 使⽤Python进⾏⽹络监控可以帮助实时监视⽹络设备、流量和服务的状态&#xff0c;以便及时识别和解决问题。 以下是⼀般步骤&#xff0c;说明如何使⽤Python进⾏⽹络监控&#xff1a; 选择监控⼯具和库&#xff1a;选择适合⽹络监控需…

蓝桥杯省赛无忧 课件49 DFS-剪枝

01 数字王国之军训排队 02 特殊的三角形 03 特殊的多边形

优雅的python(二)

&#x1f308;个人主页&#xff1a;小田爱学编程 &#x1f525; 系列专栏&#xff1a;c语言从基础到进阶 &#x1f3c6;&#x1f3c6;关注博主&#xff0c;随时获取更多关于c语言的优质内容&#xff01;&#x1f3c6;&#x1f3c6; &#x1f600;欢迎来到小田代码世界~ &#x…

【docker】linux系统docker的安装及使用

一、docker应用的安装 1.1 安装方式 Docker的自动化安装&#xff0c;即使用提供的一键安装的脚本&#xff0c;进行安装。 官方的一键安装方式&#xff1a;curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun 国内 daocloud一键安装命令&#xff1a;curl -s…

二刷代码随想录|Java版|回溯算法1|回溯基础理论+组合问题

理论 写链表之类的真的很痛苦&#xff0c;赶紧跳到回溯&#xff01;这次我想结合算法设计这本书&#xff0c;把java版写出来。放在第三部分吧。希望能够在研一完成这项工作&#xff01; 从一刷总结以下的几个要点&#xff1a; 回溯方法模板性非常强&#xff01;&#xff01;可…

企业虚拟机服务器中了lockbit3.0勒索病毒怎么办,lockbit3.0勒索病毒解密处理流程

对于企业来说&#xff0c;企业的数据是企业的核心命脉&#xff0c;关乎着企业的生产与运营的所有工作。随着网络技术的不断发展&#xff0c;网络安全威胁也在不断增加。近期&#xff0c;云天数据恢复中心接到了很多企业的求助&#xff0c;企业的虚拟机服务器遭到了lockbit3.0勒…

Unity MonoBehaviour 生成dll

dllllllllllllll&#x1f953; &#x1f959;vs创建类库项目&#x1f9c0;添加UnityEngine、UnityEditor引用&#x1f355;添加MonoBehaviour类&#x1f9aa;设置dll生成路径&#x1f37f;生成dll&#x1f354;使用dll中的Mono类 &#x1f959;vs创建类库项目 &#x1f9c0;添加…

Nginx进阶篇【五】

Nginx进阶篇【五】 八、Nginx实现服务器端集群搭建8.1.Nginx与Tomcat部署8.1.1.环境准备(Tomcat)8.1.1.1.浏览器访问:8.1.1.2.获取动态资源的链接地址:8.1.1.3.在Centos上准备一个Tomcat作为后台web服务器8.1.1.4.准备一个web项目&#xff0c;将其打包为war8.1.1.5.启动tomcat进…