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(&currentLogFile);// 写入当前日期时间、事件类型和文件路径信息到日志文件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"

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

力扣-Mysql-3328-查找每个州的城市 II(中等)

一、题目来源 3328. 查找每个州的城市 II - 力扣&#xff08;LeetCode&#xff09; 二、数据表结构 表&#xff1a;cities ---------------------- | Column Name | Type | ---------------------- | state | varchar | | city | varchar | ----------------…

Vue2:组件

Vue2&#xff1a;组件 非单文件组件定义注册使用 单文件组件 组件是Vue中最核心的内容&#xff0c;在编写页面时&#xff0c;将整个页面视为一个个组件&#xff0c;再把组件拼接起来&#xff0c;这样每个组件之间相互独立&#xff0c;有自己的结构样式&#xff0c;使页面编写思…

力扣 LeetCode 28. 找出字符串中第一个匹配项的下标(Day4:字符串)

解题思路&#xff1a; KMP算法 需要先求得最长相等前后缀&#xff0c;并记录在next数组中&#xff0c;也就是前缀表&#xff0c;前缀表是用来回退的&#xff0c;它记录了模式串与主串(文本串)不匹配的时候&#xff0c;模式串应该从哪里开始重新匹配。 next[ j - 1 ] 记录了 …

计算机网络 (1)互联网的组成

一、互联网的边缘部分 互联网的边缘部分由所有连接在互联网上的主机组成&#xff0c;这些主机又称为端系统&#xff08;end system&#xff09;。端系统可以是各种类型的计算机设备&#xff0c;如个人电脑、智能手机、网络摄像头等&#xff0c;也可以是大型计算机或服务器。端系…

智慧军营安防方案

1. 引言 智慧安防方案集成高清视频监控、智能分析与大数据管理&#xff0c;打造全方位安全防护体系。通过先进技术&#xff0c;提升预警与应急响应能力&#xff0c;确保安全无死角。 2. 视频监控技术 采用高清摄像设备与智能识别算法&#xff0c;实现全景监控与细节跟踪&#…

ABAP开发学习——ST05 ABAP SQL跟踪工具

操作步骤 第一步使用ST05之前&#xff0c;将要查的程序停留想要看的操作的前一步&#xff0c;这里想看到取数操作&#xff0c;所以停留在选择界面 第二步进入ST05 选择SQL Trace 然后激活 第三步去执行程序 第四步ST05取消激活 第五步查看操作 选完时间直接执行

AtCoder ABC378 A-D题解

比赛链接:ABC378 比较简单的一次 ABC。 Problem A: Code #include <bits/stdc.h> using namespace std; int main(){cin>>A[1]>>A[2]>>A[3]>>A[4];sort(A1,A5);if(A[1]A[2] && A[3]A[4])cout<<2<<endl;else{if(A[1]A[2]…

Windows上安装专业版IDEA2024并激活

1、IDEA官方下载 搜索IDEA官网点击进入&#xff0c;点击Download&#xff08;目前这个激活脚本只能激活2024.1.7&#xff0c;2024.2.x的版本都不能激活&#xff0c;2024.1.7版本已上传资源&#xff09;&#xff0c;如图&#xff1a; 2、开始安装 1&#xff09;、双击下载的.…

表达式求值问题(中缀转后缀,对后缀求值)详解

目录 实验题目 理解中缀和后缀表达式 问题分析 1转化为中缀表达式 2计算后缀表达式 完整代码 运行结果 实验题目 实验题目&#xff1a;表达式求值问题。这里限定的表达式求值问题是&#xff1a; 用户输入一个包含“”、“-”、“*”、“/”、正整数和圆括号的合法数学表…

AD22怎么按照板子形状铺铜

如何按照板子形状来铺铜&#xff1f; 选择铺铜管理器 选择板外形 我这里图里VCC没画就选择VCC&#xff0c; 你选什么层&#xff0c;就勾什么层 死铜移除勾选 效果如下&#xff1a;

【视觉SLAM】2-三维空间刚体运动的数学表示

读书笔记&#xff1a;学习空间变换的三种数学表达形式。 文章目录 1. 旋转矩阵1.1 向量运算1.2 坐标系空间变换1.3 变换矩阵与齐次坐标 2. 旋转向量和欧拉角2.1 旋转向量2.2 欧拉角 3. 四元数 1. 旋转矩阵 1.1 向量运算 对于三维空间中的两个向量 a , b ∈ R 3 a,b \in \R^3 …

研发费用资本化的意义

1.更真实地反映企业价值&#xff1a;研发费用是企业为创造未来经济利益而进行的投资&#xff0c;通过将其资本化并作为无形资产计入资产负债表&#xff0c;可以更真实地反映企业的资产总额和长期投资价值。这有助于投资者、债权人和其他利益相关者更准确地评估企业的财务状况、…

Ubuntu24.04安装Anaconda3+Pycharm

一、引言 重装系统已经过去一段时间了&#xff0c;现在安装一下 Anaconda 和 Pycharm。 参考连接&#xff1a; Ubuntu中安装Anaconda3和Pycharm 及其环境搭建Ubuntu18.04安装Pycharm教程ubuntu系统安装Anaconda及Pycharm在移动硬盘上搭建Ubuntu24.04深度学习环境&#xff08;…

稀疏矩阵(Sparse Matrix)及其存储格式详解

稀疏矩阵&#xff08;Sparse Matrix&#xff09;是线性代数和计算机科学中的一个重要概念&#xff0c;广泛应用于科学计算、工程模拟、图像处理、机器学习等多个领域。与稠密矩阵&#xff08;Dense Matrix&#xff09;相比&#xff0c;稀疏矩阵大部分元素为零&#xff0c;仅有少…

操作系统:页表中的页表项

操作系统&#xff1a;页表中的页表项 页表是操作系统用于跟踪进程使用的虚拟地址与系统内存中相应物理地址之间映射的数据结构。 页表项&#xff08;Page Table Entry&#xff0c;PTE&#xff09;是页表中的一个条目&#xff0c;用于存储有关特定内存页的信息。每个页表项包含…

Docker部署Kafka SASL_SSL认证,并集成到Spring Boot

1&#xff0c;创建证书和密钥 需要openssl环境&#xff0c;如果是Window下&#xff0c;下载openssl Win32/Win64 OpenSSL Installer for Windows - Shining Light Productions 还需要keytool环境&#xff0c;此环境是在jdk环境下 本案例所使用的账号密码均为&#xff1a; ka…

文章解读与仿真程序复现思路——电力系统自动化EI\CSCD\北大核心《基于改进容积卡尔曼滤波的含光伏配电网动态状态估计》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

jenkins使用cli发行uni-app到h5

官网文档HBuilderX 文档 首先确定是否存在环境变量 正常情况cmd中执行cli 如果提示 cli 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。请先配置环境变量 Freestyle Project项目在Build Steps中增加Execute Windows batch command命令如下 d: cd D:\devsof…

FMEA 在新兴技术领域(如量子计算、人工智能芯片等)的应用挑战与机遇

【大家好&#xff0c;我是唐Sun&#xff0c;唐Sun的唐&#xff0c;唐Sun的Sun。】 摘要&#xff1a; 本文深入探讨了 FMEA&#xff08;失效模式及后果分析&#xff09;在如量子计算、人工智能芯片等新兴技术领域的应用所面临的挑战与机遇。随着科技的飞速进步&#xff0c;新兴技…

websocket身份验证

websocket身份验证 前言 上一集我们就完成了websocket初始化的任务&#xff0c;那么我们完成这个内容之后就应该完成一个任务&#xff0c;当客户端与服务端连接成功之后&#xff0c;客户端应该主动发起一个身份认证的消息。 身份认证proto 我们看一眼proto文件的内容。 我…