Qt 日志文件的滚动写入
Qt 日志文件的滚动写入
flyfish
日志文件的滚动写入功能。在日志文件达到10MB时创建新的日志文件,并且在总日志文件大小达到10GB时开始覆盖最早的日志文件
以监控一个文件夹的写日志为例
日志文件创建与管理
初始化日志文件:在FileMonitor类的构造函数中,会创建第一个日志文件。日志文件的命名格式为 “file_monitor_序号.log”,初始序号为 0。
滚动写入机制:
单个日志文件大小限制:当向当前日志文件写入内容使得其大小达到 10MB(通过logFileSizeLimit变量设定,值为10 * 1024 * 1024字节)时,会关闭当前日志文件,增加日志文件索引,然后创建新的日志文件用于后续的日志记录。
总日志文件大小限制:
同时,会监控所有日志文件的总体大小,当总大小达到 10GB(通过totalLogSizeLimit变量设定,值为10 * 1024 * 1024 * 1024字节)时,会删除最早创建的日志文件(通过计算最早日志文件的文件名并判断其是否存在,若存在则删除),以确保总日志文件大小不会无限制增长。
日志内容记录:
对于文件创建、删除、修改等事件,会将事件发生的当前日期时间(格式为 “yyyy-MM-dd hh:mm:ss”)、事件类型(如 “File created”、“File deleted”、“File modified”)以及相关文件的路径信息,按照特定格式写入到当前正在使用的日志文件中。并且每次写入后会立即刷新缓冲区,确保日志内容及时写入文件。同时,会实时更新当前日志文件的大小信息,以便判断是否达到单个日志文件大小限制。
#include <QCoreApplication>
#include <QFileSystemWatcher>
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QDir>
#include <QFileInfo>
#include <QSet>
#include <iostream>// FileMonitor类继承自QObject,用于监控指定文件夹的文件变化并记录相关日志
class FileMonitor : public QObject {Q_OBJECTpublic:// 构造函数,用于初始化文件监控器相关参数explicit FileMonitor(const QString &path, QObject *parent = nullptr): QObject(parent),// 创建文件系统监控器对象,并将其作为当前对象的子对象watcher(new QFileSystemWatcher(this)),rootPath(path),// 设置单个日志文件的大小限制为10MB,这里将10MB转换为字节数logFileSizeLimit(static_cast<quint64>(10) * 1024 * 1024),// 设置总日志文件大小限制为10GB,同样转换为字节数totalLogSizeLimit(static_cast<quint64>(10) * 1024 * 1024 * 1024),currentLogFileIndex(0),currentLogFileSize(0) {// 将指定的监控路径添加到文件系统监控器中watcher->addPath(rootPath);// 获取监控路径下初始的文件列表QDir dir(rootPath);initialFiles = dir.entryList(QDir::Files);// 连接文件系统监控器的目录变化信号到对应的槽函数connect(watcher, &QFileSystemWatcher::directoryChanged, this, &FileMonitor::onDirectoryChanged);// 连接文件系统监控器的文件变化信号到对应的槽函数connect(watcher, &QFileSystemWatcher::fileChanged, this, &FileMonitor::onFileChanged);// 初始化日志文件,创建第一个日志文件createNewLogFile();}private slots:// 当监控的目录发生变化时调用的槽函数void onDirectoryChanged(const QString &path) {std::cout << "Directory changed: " << qPrintable(path) << std::endl;// 获取当前监控目录下的文件列表QDir dir(rootPath);QStringList currentFiles = dir.entryList(QDir::Files);// 找出新增的文件,通过集合运算实现QSet<QString> newFiles = QSet<QString>(currentFiles.begin(), currentFiles.end()).subtract(QSet<QString>(initialFiles.begin(), initialFiles.end()));// 遍历新增的文件,记录文件创建事件到日志for (const QString &file : newFiles) {logEvent("File created", dir.absoluteFilePath(file));}// 找出被删除的文件,同样通过集合运算QSet<QString> deletedFiles = QSet<QString>(initialFiles.begin(), initialFiles.end()).subtract(QSet<QString>(currentFiles.begin(), currentFiles.end()));// 遍历被删除的文件,记录文件删除事件到日志for (const QString &file : deletedFiles) {logEvent("File deleted", dir.absoluteFilePath(file));}// 更新初始文件列表,使其为当前的文件列表,以便下次检测文件变化initialFiles = currentFiles;}// 当监控的文件发生变化时调用的槽函数void onFileChanged(const QString &path) {std::cout << "File changed: " << qPrintable(path) << std::endl;// 记录文件修改事件到日志logEvent("File modified", path);}private:// 创建新的日志文件的函数void createNewLogFile() {// 构造新的日志文件名,格式为:file_monitor_序号.logQString logFileName = "file_monitor_" + QString::number(currentLogFileIndex) + ".log";currentLogFile.setFileName(logFileName);// 如果日志文件已经存在,获取其大小并更新当前日志文件大小变量if (currentLogFile.exists()) {currentLogFileSize = currentLogFile.size();} else {currentLogFileSize = 0;}// 打开或创建日志文件,如果失败则输出错误信息if (!currentLogFile.open(QIODevice::Append | QIODevice::Text)) {std::cerr << "Failed to open/create log file: " << qPrintable(logFileName) << std::endl;}}// 记录日志事件的函数void logEvent(const QString &event, const QString &path) {// 创建文本流对象,用于向当前日志文件写入内容QTextStream out(¤tLogFile);// 写入当前日期时间、事件类型和文件路径信息到日志文件out << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")<< " - " << event << ": " << path << "\n";currentLogFile.flush();// 计算刚写入的日志字符串的大小,先读取文本流中的内容QString logString = out.readAll();// 如果读取为空,说明可能是因为刚刚写入还未缓存,重新构造日志字符串if (logString.isEmpty()) {logString = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")+ " - " + event + ": " + path + "\n";}// 更新当前日志文件的大小,将日志字符串转换为UTF-8编码后计算其字节数并累加到当前日志文件大小变量currentLogFileSize += logString.toUtf8().size();// 检查当前日志文件大小是否达到单个日志文件大小限制if (currentLogFileSize >= logFileSizeLimit) {// 关闭当前日志文件currentLogFile.close();// 增加日志文件索引,用于创建下一个新的日志文件++currentLogFileIndex;// 检查是否超过了总日志文件大小限制,如果超过则删除最早的日志文件if (currentLogFileIndex * logFileSizeLimit > totalLogSizeLimit) {QString oldestLogFileName = "file_monitor_" + QString::number(currentLogFileIndex - totalLogSizeLimit / logFileSizeLimit) + ".doc";if (QFile::exists(oldestLogFileName)) {QFile::remove(oldestLogFileName);}}// 创建新的日志文件createNewLogFile();}}// 文件系统监控器对象,用于监控指定路径下的文件和目录变化QFileSystemWatcher *watcher;// 监控的根路径QString rootPath;// 初始的文件列表,用于对比检测文件的新增和删除情况QStringList initialFiles;// 以下是新增的日志管理相关成员变量// 当前正在使用的日志文件对象QFile currentLogFile;// 单个日志文件的大小限制,单位为字节quint64 logFileSizeLimit;// 总日志文件大小限制,单位为字节quint64 totalLogSizeLimit;// 当前日志文件的索引,用于区分不同的日志文件quint64 currentLogFileIndex;// 当前日志文件的大小,单位为字节,用于实时监控文件大小是否达到限制quint64 currentLogFileSize;
};int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);// 获取命令行参数,如果有参数则将其作为监控路径,否则默认监控根目录QString watchPath = (argc > 1)? QString::fromLocal8Bit(argv[1]) : "/";// 创建文件监控对象,传入监控路径FileMonitor monitor(watchPath);// 运行应用程序的事件循环,开始监控文件和目录变化并记录日志return a.exec();
}#include "main.moc"
相关文章:
Qt 日志文件的滚动写入
Qt 日志文件的滚动写入 flyfish 日志文件的滚动写入功能。在日志文件达到10MB时创建新的日志文件,并且在总日志文件大小达到10GB时开始覆盖最早的日志文件 以监控一个文件夹的写日志为例 日志文件创建与管理 初始化日志文件:在FileMonitor类的构造函…...
【c语言】数据包捕获和分析工具
请解释一下数据包捕获和分析工具(如Wireshark)的工作原理和用途。 数据包捕获和分析工具,如Wireshark(前身为Ethereal),是一种网络协议分析软件,它允许用户实时监控、抓取并分析计算机网络中的网…...
移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——14.哈希(2)(模拟实现)
1.概念介绍 1.1开散列 开散列(Open Hashing),也叫链地址法,是一种解决哈希冲突的方法。每个哈希表槽位保存一个链表,所有散列到同一位置的元素都存储在该链表中。当插入元素发生冲突时,将新元素添加到相应…...
请描述一下JVM(Java虚拟机)的生命周期及其对应用程序性能的影响
1、请描述一下JVM(Java虚拟机)的生命周期及其对应用程序性能的影响。 JVM(Java虚拟机)的生命周期主要涉及以下几个阶段:加载、验证、准备、解析、执行、卸载。每个阶段都有其特定的作用和影响。 加载:JVM…...
展会邀约|加速科技与您相约IC China 2024!
第二十一届中国国际半导体博览会( IC China 2024)将于 2024 年11月18日—11月20日在北京国家会议中心举行。加速科技将携高性能测试机ST2500EX、ST2500E、eATE及全系测试解决方案亮相E2馆B150展位。博览会期间,将同期举办"半导体产业前沿…...
鸿蒙中服务卡片数据的获取和渲染
1. 2.在卡片中使用LocalStorageProp接受传递的数据 LocalStorageProp("configNewsHead") configNewsHeadLocal: ConfigNewsHeadInfoItem[] [] 注意:LocalStorageProp括号中的为第一步图片2中的键 3.第一次在服务卡片的第一个卡片中可能会获取不到数据…...
运维篇-修复centos7无法下载docker问题
修复centos7无法下载docker问题 1、安装docker时报错2、docker无法下载镜像 1、安装docker时报错 linux的centos系统,安装docker时会报错 –> Finished Dependency Resolution Error: Package: glibc-2.17-307.el7.1.i686 (base) Requires: glibc-common 2.17…...
【论文阅读】WaDec: Decompiling WebAssembly Using Large Language Model
论文阅读笔记:WaDec: Decompiling WebAssembly Using Large Language Model 1. 来源出处 论文标题: WaDec: Decompiling WebAssembly Using Large Language Model作者: Xinyu She, Yanjie Zhao, Haoyu Wang会议: 39th IEEE/ACM International Conference on Automated Softwar…...
redis类型介绍
1. 字符串(String): • 简介:最基础的数据类型,可以存储任何形式的字符串,包括文本数据和数字数据。 • 常用操作:SET、GET、INCR、DECR等。 2. 列表(List): …...
kubernetes如何配置默认存储
如果不想每次都创建PV,希望k8s集群中能够配置号默认存储,然后根据你的PVC自动创建PV,就需要安装一个默认存储,也就是storageclass 什么是storageclass Kubernetes提供了一套可以自动创建PV的机制,即:Dyna…...
【微服务】Spring AI 使用详解
目录 一、前言 二、Spring AI 概述 2.1 什么是Spring AI 2.2 Spring AI 特点 2.3 Spring AI 带来的便利 2.4 Spring AI 应用领域 2.4.1 聊天模型 2.4.2 文本到图像模型 2.4.3 音频转文本 2.4.4 嵌入大模型使用 2.4.5 矢量数据库支持 2.4.6 数据工程ETL框架 三、Sp…...
DataGrip 连接 dm
参考链接 使用DataGrip链接达梦数据库_datagrip连接达梦数据库-CSDN博客 下载 jdbc 驱动包 第一种 通过链接下载:下载 第二种【特指 window 安装包】 在达梦安装包 iso 文件里面 source/drivers/jdbc 将驱动添加进 DataGrip 选中 jdbc 驱动包,然后选…...
数据库监控工具DBdoctor v3.2.4.3版本发布,新增对openGauss、Vastbase G100的支持!
新引擎扩展 新增对openGauss数据库的支持:支持对openGauss数据库的SQL审核、实例巡检、性能洞察、锁透视、根因诊断、基础监控、索引推荐、存储分析; 新增对Vastbase G100数据库的支持:支持对Vastbase G100数据库的SQL审核、实例巡检、性能洞…...
Git 常用命令大全与详解
Git 是一种广泛使用的分布式版本控制系统。无论是管理个人项目还是进行团队协作,掌握 Git 的常用命令都是开发者必备的技能之一。本文将介绍一些常用的 Git 命令,并对其进行详细说明。 1. 基础命令 初始化仓库 git init:在当前目录下初始化…...
执行flink sql连接clickhouse库
手把手教学,flink connector打通clickhouse大数据库,通过下发flink sql,来使用ck。 组件版本jdk1.8flink1.17.2clickhouse23.12.2.59 1.背景 flink官方不支持clickhouse连接器,工作中难免会用到。 2.方案 利用GitHub大佬提供…...
什么是C++中的友元函数和友元类?
友元函数(Friend Function)和 友元类(Friend Class)是用于控制类的访问权限的机制。这允许特定的函数或类访问另一个类的私有成员和保护成员,打破了 C 的封装性规则。 友元函数 定义 友元提供了不同类的成员函数之间…...
基于Spring Boot+Vue的多媒体素材管理系统的设计与实现
一.系统开发工具与环境搭建 1.系统设计开发工具 后端使用Java编程语言的Spring boot框架 项目架构:B/S架构 运行环境:win10/win11、jdk17 前端: 技术:框架Vue.js;UI库:ElementUI; 开发工具&…...
Inpaint-Web:纯浏览器端实现的开源图像处理工具
之前在刷短视频的时候,经常看到一些情侣在景区拍照,结果被路人“抢镜”。有时男朋友会拿出手机,帮忙把那些路人“P”掉,简直是既贴心又有趣。最近我在逛 GitHub 时,发现了一个可以在浏览器端删除照片中部分内容的纯前端…...
商业物联网详细指南:优势与挑战
物联网是信息技术行业最具前景的领域之一。为什么它如此热门呢?原因在于全球连接性。设备可以像人群一样相互协作。正如我们所知,协作能显著提高生产力。 物联网对普通用户和企业都有益处。许多日常流程可以通过传感器、扫描仪、摄像头和其他设备实现自…...
如何在项目中用elementui实现分页器功能
1.在结构部分复制官网代码: <template> 标签: 这是 Vue 模板的根标签,包含所有的 HTML 元素和 Vue 组件。 <div> 标签: 这是一个普通的 HTML 元素,包裹了 el-pagination 组件。它没有特别的意义,只是为了确保 el-pagi…...
Nginx参数配置-笔记
文章目录 upstream实现后台应用服务负载均衡&高可用proxy_set_header参数 upstream实现后台应用服务负载均衡&高可用 角色IPnginx172.168.110.2后端应用服务1172.168.110.3后端应用服务2172.168.110.4后端应用服务3(备用)172.168.110.5 示例如下: upstre…...
衡量神经网络表征相似度
目录 1.中心核对齐技术(CKA)2.Hilbert-Schmidt independence criterion(HSIC)HSIC的计算步骤:HSIC的性质:应用:矩阵中心化操作对于单个数据集的中心化对于两个数据集的中心化(例如,用于HSIC)Python代码示例1.中心核对齐技术(CKA) CKA通过计算两个表征的Gram矩阵(即…...
Javascript高级:深度解析与多种实现方式数组扁平化
数组扁平化:深度解析与多种实现方式 在JavaScript编程中,数组扁平化是一个常见的操作,指的是将一个多维数组转换成一个一维数组。这个过程中,所有嵌套的数组元素都会被“拉平”到同一个层级。数组扁平化在处理嵌套数据结构时非常…...
SpringBoot Data Redis连接Redis-Cluster集群
使用SpringBoot Data Redis无法连接Redis-Cluster集群 最近在研究系统高并发下的缓存架构,因此自己在自己买的云服务器上搭建好Redis 5.0 版本的集群后,使用springboot的 RedisTemplate连接是发现总是访问不到集群节点。上网百度了发现没有好的解决办法&…...
计算机网络——TCP篇
TCP篇 基本认知 TCP和UDP的区别? TCP 和 UDP 可以使用同一个端口吗? 可以的 传输层中 TCP 和 UDP在内核中是两个完全独立的软件模块。可以根据协议字段来选择不同的模块来处理。 TCP 连接建立 TCP 三次握手过程是怎样的? 一次握手:客户端发送带有 …...
【网络安全面经】技术性问题3
11. 一次完整的 HTTP 请求过程 域名解析:通过 DNS 将域名转换为 IP 地址,如上述 DNS 的工作原理。建立 TCP 连接:客户端向服务器发送 SYN 报文段,经过三次握手建立 TCP 连接。发送 HTTP 请求:客户端向服务器发送 HTTP…...
前后端交互之动态列
一. 情景 在做项目时,有时候后会遇到后端使用了聚合函数,导致生成的对象的属性数量或数量不固定,因此无法建立一个与之对应的对象来向前端传递数据,这时可以采用NameDataListVO向前端传递数据。 Data Builder AllArgsConstructo…...
递归(3)----力扣40组合数2,力扣473火柴拼正方形
给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用 一次 。 注意:解集不能包含重复的组合。 示例 1: 输入: candidates [10,1,2,7,6,1…...
十一:HTTP 状态码详解:解读每一个响应背后的意义
HTTP(超文本传输协议)是网络通信的基石之一,主要用于客户端(例如浏览器)和服务器之间的通信。为了让服务器能准确地向客户端反馈请求的处理状态,HTTP设计了一套标准的状态码。每一个状态码代表了特定的含义,指示了请求的状态、潜在的问题或成功的信息。 1. 信息响应 (1…...
《译文》2024年11月数维杯国际大学生数学建模挑战赛题目
# 赛题正式发布 2024年第十届数维杯国际大学生数学建模挑战赛顺利开赛,竞赛开始时间为北京时间2024年11月15日09:00至北京时间2024年11月19日09:00,共计4天,竞赛题目正式发布,快来一起围观,你认为今年的哪个题目更具有…...
公众号开发是前端还是后端/北京seo结算
实验内容: 测试典型运算符的使用。将程序补充完整。获取实数的整数部分,并求出实数与整数部分的差。输入摄氏温度,计算华氏温度并输出。输入圆柱体的高和半径,求其体积。输入一个梯形的上底、下底、高&#x…...
网站建设后台管理流程/百度seo效果怎么样
ApcCache根据应用程序组件提供APC缓存。 要使用此应用程序组件,必须加载APC PHP扩展。或者,可以通过将useApcu设置为true来使用APCu PHP扩展。要为CLI启用APC或APCu,您应该在php.ini中添加“apc.enable_cli 1”。 有关ApcCache支持的常见缓…...
武汉网站建设武汉/百度搜索下载app
下面是小凰凰的简介,看下吧! 💗人生态度:珍惜时间,渴望学习,热爱音乐,把握命运,享受生活 💗学习技能:网络 -> 云计算运维 -> python全栈( 当前正在学习…...
wordpress新闻站自动采集器/色盲测试图及答案大全
前言 正常情况下,pytest 用例默认执行顺序是自上而下的,对于一些有上下文依赖关系的用例,我们可以通过 pytest-ordering 插件来控制用例执行顺序,也可以通过setup、teardown和fixture来解决 pytest-ordering 详解 (建议掌握程度…...
做的好的农产品网站/网页制作软件免费版
在Java中,字符串“abcd”与字符串“ab你好”的长度是一样,都是四个字符。 但对应的字节数不同,一个汉字占两个字节。 定义一个方法,按照指定的字节数来取子串。 如:对于“ab你好”,如果取三个字节ÿ…...
wordpress 表单 验证码/石家庄手机端seo
现如今,稍微懂点电脑的人,都不愿去购买整套的电脑,而是自己去单独购买一些配件,回家DIY组装电脑,但是在组装的过程中难免会要连接主板电源线,这对于许多新手朋友来说这些装机细节方面还是会存在一些问题&am…...