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.rhkb.cn/news/471947.html

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

相关文章

前端(3)——快速入门JaveScript

参考&#xff1a; 罗大富 JavaScript 教程 | 菜鸟教程 JavaScript 教程 1. JaveScript JavaScript 简称 JS JavaScript 是一种轻量级、解释型、面向对象的脚本语言。它主要被设计用于在网页上实现动态效果&#xff0c;增加用户与网页的交互性。作为一种客户端脚本语言&#…

使用阿里云快速搭建 DataLight 平台

使用阿里云快速搭建 DataLight 平台 本篇文章由用户 “闫哥大数据” 分享&#xff0c;B 站账号&#xff1a;https://space.bilibili.com/357944741?spm_id_from333.999.0.0 注意&#xff1a;因每个人操作顺序可能略有区别&#xff0c;整个部署流程如果出现出入&#xff0c;以…

H.265流媒体播放器EasyPlayer.js H.264/H.265播放器chrome无法访问更私有的地址是什么原因

EasyPlayer.js H5播放器&#xff0c;是一款能够同时支持HTTP、HTTP-FLV、HLS&#xff08;m3u8&#xff09;、WS、WEBRTC、FMP4视频直播与视频点播等多种协议&#xff0c;支持H.264、H.265、AAC、G711A、MP3等多种音视频编码格式&#xff0c;支持MSE、WASM、WebCodec等多种解码方…

QT_CONFIG宏使用

时常在Qt代码中看到QT_CONFIG宏&#xff0c;之前以为和#define、DEFINES 差不多&#xff0c;看了定义才发现不是那么回事&#xff0c;定义如下&#xff1a; 看注释就知道了QT_CONFIG宏&#xff0c;其实是&#xff1a;实现了一个在编译时期安全检查&#xff0c;检查指定的Qt特性…

centos7安装Chrome使用selenium-wire

背景&#xff1a;在centos7中运行selenium-wire爬虫&#xff0c;系统自带的Firefox浏览器不兼容&#xff0c;运行报错no attribute ‘set_preference’&#xff0c;应该是selenium-wire和Firefox的驱动不兼容 查了半天不知道怎么解决&#xff0c;就想在centos7上安装Chrome来跑…

医院信息化与智能化系统(21)

医院信息化与智能化系统(21) 这里只描述对应过程&#xff0c;和可能遇到的问题及解决办法以及对应的参考链接&#xff0c;并不会直接每一步详细配置 如果你想通过文字描述或代码画流程图&#xff0c;可以试试PlantUML&#xff0c;告诉GPT你的文件结构&#xff0c;让他给你对应…

《FreeRTOS任务控制块篇》

Task control block, 即任务控制块。任务控制块&#xff08;TCB&#xff09;是一个结构体&#xff0c;它会分配给每个任务&#xff0c;其中存储着任务的状态信息&#xff0c;包括指向任务上下文&#xff08;任务的运行时环境&#xff0c;包括寄存器值&#xff09;的指针。任务控…

Queuing 表(buffer表)的优化实践 | OceanBase 性能优化实践

案例问题描述 该案例来自一个金融行业客户的问题&#xff1a;他们发现某个应用对一个数据量相对较小的表&#xff08;仅包含数千条记录&#xff09;访问时&#xff0c;频繁遇到性能下降的情况。为解决此问题&#xff0c;客户向我们求助进行分析。我们发现这张表有频繁的批量插…

ssh登陆服务器后支持Tab键命令补全

在服务器上新建了用户后&#xff0c;通过ssh登录到服务器后发现不能使用Tab键来进行命令补全 截图如下&#xff1a; 以为没有配置.bashrc 此时输入 source 发现无此命令 细心的可以发现 -sh 于是输入命令echo $SHELL 确认此时的shell为sh&#xff0c; 只要输入命令bash即可切…

[白月黑羽]关于仿写类postman功能软件题目的解答

原题&#xff1a; 答&#xff1a; python文件如下 from PySide6.QtWidgets import QApplication, QMessageBox,QTableWidgetItem,QHeaderView,QWidget,QTableWidget from PySide6.QtCore import QEvent,QObject from PySide6.QtUiTools import QUiLoader import time import …

Postman接口测试(断言、关联、参数化、输出测试报告)

基本界面展示 Get、Post请求 Postman断言 使用postman来判断预期结果与实际结果是否一致 响应状态码断言 响应包含字符串 断言判断字符串的格式 关联 用于解决http请求之间存在依赖关系 依赖&#xff1a;一个http请求的响应结果中的数据&#xff0c;被另一个请求使用 登…

【卡尔曼滤波】数据融合Fusion的应用 C语言、Python实现(Kalman Filter)

【卡尔曼滤波】数据融合Fusion的应用 C语言、Python实现&#xff08;Kalman Filter&#xff09; 更新以gitee为准&#xff1a; gitee地址 文章目录 卡尔曼滤波数据融合Python实现C语言实现多个数据如何融合附录&#xff1a;压缩字符串、大小端格式转换压缩字符串浮点数压缩Pac…

网络原理-网络层和数据链路层

一、网络层 1、IP协议完成的工作 地址管理&#xff1a;使用一套地址体系来描述所没备的位置 路由选择&#xff1a;一个数据包如何从网络的某个地址传到另一个地址 2、IP报头 4 位版本号&#xff1a;取值为4或6 (IPv4/IPv6) 4 位首部长度&#xff1a;IP报头&#xff0c;单位…

【Three.js基础学习】22.New project structure

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 这里将使用全新的项目结构&#xff0c;将不同工具分层&#xff0c;区分开使用。 一、结构目录 二、对应文件 1.script.js 获取画布&#xff0c;引入样式和功能。 /* 课…

AI风向标|算力与通信的完美融合,SRM6690解锁端侧AI的智能密码

当前&#xff0c;5G技术已经成为推动数字经济和实体经济深度融合的关键驱动力&#xff0c;进入5G发展的下半场&#xff0c;5G与AI的融合正推动诸多行业的数字化转型和创新发展&#xff0c;终端侧AI和端云混合式AI将广泛应用于各类消费终端和各行各业。 在推动5G和AI与各行业场…

【WPF】Prism学习(二)

Prism Commands 1.命令&#xff08;Commanding&#xff09; 1.1. ViewModel的作用&#xff1a; ViewModel不仅提供在视图中显示或编辑的数据&#xff0c;还可能定义一个或多个用户可以执行的动作或操作。这些用户可以通过用户界面&#xff08;UI&#xff09;执行的动作或操作…

智慧建造-运用Trimble技术将梦幻水族馆变为现实【上海沪敖3D】

项目概述 西雅图水族馆耗资1.6亿美元对海洋馆进行扩建。该项目包括建造三个大型栖息地&#xff0c;每个建筑物几乎都没有直边&#xff0c;其中一个主栖息地由520立方米混凝土和355吨钢筋组成。特纳建筑公司的混凝土团队通过强大的贸易合作伙伴和创新的数字制造技术&#xff0c;…

kubesphere环境-本地Harbor仓库+k8s集群(单master 多master)+Prometheus监控平台部署

前言&#xff1a;半月前在公司生产环境上离线部署了k8s集群Victoria Metrics(二开版)自研版夜莺 监控平台的搭建&#xff0c;下面我租用3台华为云服务器演示部署kubesphere环境-本地Harbor仓库k8s集群&#xff08;单master节点 & 单master节点&#xff09;Prometheus监控部…

java 随机生成验证码

1.需求 实现随机生成验证码&#xff0c;验证码可能是大小写字母和数字 2.实现 写一个getCode方法实现 public static String getCode(int n){//1. 定义一个字符串&#xff0c;字符串中包含大小写字母和数字String str "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrs…

Unity图形学之Blend指令

1.渲染流程&#xff1a;Blend 决定了要渲染的像素和Gbuffer里像素到底怎么取舍 2.Blend 公式&#xff1a; 3.factor可以取值的内容有&#xff1a; One 1 Zero :0 SrcColor : 要渲染的像素 SrcAlpha : 要渲染像素的 a 通道。 DstColor &#xff1a; 已经渲染在gbuffer…