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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在DevEco开发工具中,使用Previewer预览界面中的UI组件

1、在DevEco工具中&#xff0c;点击并展开PreViewer预览器 2、在PreViewer预览器中&#xff0c;点击Tt按钮&#xff08;Inspector&#xff09;切换至组件查看模式 3、在组件查看模式下选择组件&#xff0c;代码呈现选中状态&#xff0c;右侧呈现组件树&#xff0c;右下方呈现组…

三、node,mongoose实现用户登录token生成、鉴权

用户Schema和密码加密 首先&#xff0c;我们使用Mongoose定义用户数据模型。这里包含用户名&#xff08;username&#xff09;和密码&#xff08;password&#xff09;&#xff0c;并且在密码字段上设置了一个预保存钩子&#xff08;pre-save hook&#xff09;&#xff0c;用于…

用ASM HEMT模型提取GaN器件的参数

标题&#xff1a;Physics-Based Multi-Bias RF Large-Signal GaNHEMT Modeling and Parameter Extraction Flow (JEDS 17年) 模型描述 该模型的核心是对表面势&#xff08;ψ&#xff09;及其随施加的栅极电压&#xff08;Vg&#xff09;和漏极电压&#xff08;Vd&#xff09…

1分钟内生成美妙歌曲:Suno AI的音乐魔法

1分钟内生成美妙歌曲&#xff1a;Suno AI的音乐魔法 Suno AI是一款人工智能工具&#xff0c;让创作者能够生成超现实的音乐、语音和音效&#xff0c;可以根据用户的指令生成音乐、语音和其他音频内容。它可以帮助创作者快速生成高质量的音乐作品&#xff0c;并且可以根据不同的…

【Qt无门槛入门】信号以及信号机制及其常用控件(1)

信号与信号槽 信号源&#xff1a;由哪个控件发出的信号。 信号的类型&#xff1a;用户进行不同的操作&#xff0c;就可能出发不同的信号。 信号处理的方式:槽&#xff08;slot&#xff09;某个对象接收到这个信号之后&#xff0c;就会做一些相关的处理动作。但是Qt对象不会无故…

02-Linux入门

说明&#xff1a;01-VMware还没有写笔记&#xff0c;因为这个VMware我很久之前就装好了&#xff0c;先给自己挖个坑&#xff0c;回头有空了补一下01-VMware&#xff08;包括安装、使用、xshell的操作等 说明&#xff09;的笔记吧。 下面关于Linux的笔记是根据黑马的视频所写的&…

Notepad 将多行转换成字符串,合并成一行

notepad 将多行转换成字符串&#xff0c;合并成一行 (1) 快捷键 ctrl H &#xff0c;选择 【替换】&#xff0c; (2) 【查找目标】&#xff0c;输入 \r\n &#xff0c; 这个正则表达式的含义是 换行回到行首&#xff0c;相当于 windows的 enter 键&#xff1a; \r&#xff…

十分钟搭建本地Linux开发运行环境

十分钟搭建本地开运行环境 linux环境请参考&#xff1a;5分钟搭建本地linux开发环境 环境&#xff1a;宝塔、Jdk、Mysql、Redis 1、宝塔&#xff1a; 官网地址&#xff1a;宝塔官网 yum install -y wget && wget -O install.sh https://download.bt.cn/install/in…

【labVIEW】学习记录

【labVIEW】学习记录 一、简介二、安装及激活三、使用 回到目录 一、简介 labVIEW&#xff08;Laboratory Virtual Instrument Engineering Workbench&#xff09;是一款由美国国家仪器公司&#xff08;National Instruments&#xff09;开发的可视化编程环境和开发平台。LabV…

scrapy框架核心知识Spider,Middleware,Item Pipeline,scrapy项目创建与启动,Scrapy-redis与分布式

scrapy项目创建与启动 创建项目 在你的工作目录下直接使用命令: scrapy startproject scrapytutorial运行后创建了一个名为scrapytutorial的爬虫工程 创建spider 在爬虫工程文件内&#xff0c;运行以下命令&#xff1a; scrapy genspider quotes创建了名为quotes的爬虫 …

Logistics 逻辑回归概念

1. sigmoid函数 逻辑回归算法的拟合函数&#xff0c;叫做sigmoid函数&#xff1a; 函数图像如下&#xff08;百度图片搜到的图&#xff09;&#xff1a; sigmoid函数是一个s形曲线&#xff0c;就像是阶跃函数的温和版&#xff0c;阶跃函数在0和1之间是突然的起跳&#xff0c;…

Unity中URP下额外灯角度衰减

文章目录 前言一、额外灯中聚光灯的角度衰减二、AngleAttenuation函数的传入参数1、参数&#xff1a;spotDirection.xyz2、_AdditionalLightsSpotDir3、参数&#xff1a;lightDirection4、参数&#xff1a;distanceAndSpotAttenuation.zw5、_AdditionalLightsAttenuation 三、A…

【Git】windows系统安装git教程和配置

一、何为Git Git(读音为/gɪt/)是一个开源的分布式版本控制系统&#xff0c;可以有效、高速地处理从很小到非常大的项目版本管理。 二、git安装包 有2种版本&#xff0c;Git for Windows Setup和Git for Windows Portable(便携版)两个版本都可以。 三、Git for Windows Por…

【服务器】宝塔面板的使用手册

目录 &#x1f337;概述 &#x1f33c;1. 绑定域名 &#x1f33c;2. 添加端口 &#x1f33c;3. 安装docker配置docker​​​​​​​ &#x1f33c;4. 软件商店 &#x1f33c;5. 首页 &#x1f337;概述 宝塔面板的安装教程&#xff1a;【服务器】安装宝塔面板 &#x1f…

[BJDCTF2020]The mystery of ip

hint 猜测ip和XFF有关 加一个XFF 下面这一步是看了wp出来的&#xff1a;存在ssti 这里尝试用jinja的注入方法&#xff0c;页面回显了是php的smarty框架 查了一下smarty的注入方法&#xff0c;发现可以直接执行php命令 在根目录找到flag

SpringBoot深入解析:掌握自动装配机制及其定制化原理

推荐一款我一直在用的ChatGPT4.0国内站点&#xff0c;每日有免费使用额度&#xff0c;支持PC、APP、VScode插件同步使用 SpringBoot篇&#xff1a;SpringBoot的自动装配原理 SpringBoot是一个旨在简化Spring应用初始搭建以及开发过程的框架。它利用了Spring框架的依赖注入特性…

(免费分享)基于springboot,vue疗养中心管理系统

前端&#xff1a;vueelementUI 技术&#xff1a;springbootmybatisredis 数据库&#xff1a;mysql 功能&#xff1a;系统管理、信息管理、膳食管理、护理管理、床位管理、后勤管理、费用管理等 获取完整源码&#xff1a; 大家点赞、收藏、关注、评论啦 、查看 &#x1f447;…

Java实现木马文件检测系统 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 木马分类模块2.3 木马软件模块2.4 安全资讯模块2.5 脆弱点模块2.6 软件检测模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 木马分类表3.2.2 木马软件表3.2.3 资讯表3.2.4 脆弱点表3.2.5 软件检测表…

「 典型安全漏洞系列 」07.OS命令注入详解

引言&#xff1a;什么是操作系统命令注入&#xff0c;如何防御和利用漏洞&#xff1f; 1. 简介 操作系统命令注入&#xff08;OS command injection&#xff09;是一种Web安全漏洞&#xff0c;允许攻击者在运行应用程序的服务器上执行任意操作系统&#xff08;OS&#xff09;命…

静态分析Golang语言生成函数调用关系的利器——go-callvis

目录 升级go删除旧版本安装新版本配置环境变量载入环境修改当前环境修改之后进入的环境 分析安装go-callvis分析其他包总结 导出文件总结 清晰主体脉络总结 其他 参考资料 不同于之前分析C语言项目的工具&#xff0c;go-callvis还是很方便使用。只要把两项工作做好就能顺利的使…