当前位置: 首页 > news >正文

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"

相关文章:

Qt 日志文件的滚动写入

Qt 日志文件的滚动写入 flyfish 日志文件的滚动写入功能。在日志文件达到10MB时创建新的日志文件&#xff0c;并且在总日志文件大小达到10GB时开始覆盖最早的日志文件 以监控一个文件夹的写日志为例 日志文件创建与管理 初始化日志文件&#xff1a;在FileMonitor类的构造函…...

【c语言】数据包捕获和分析工具

请解释一下数据包捕获和分析工具&#xff08;如Wireshark&#xff09;的工作原理和用途。 数据包捕获和分析工具&#xff0c;如Wireshark&#xff08;前身为Ethereal&#xff09;&#xff0c;是一种网络协议分析软件&#xff0c;它允许用户实时监控、抓取并分析计算机网络中的网…...

移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——14.哈希(2)(模拟实现)

1.概念介绍 1.1开散列 开散列&#xff08;Open Hashing&#xff09;&#xff0c;也叫链地址法&#xff0c;是一种解决哈希冲突的方法。每个哈希表槽位保存一个链表&#xff0c;所有散列到同一位置的元素都存储在该链表中。当插入元素发生冲突时&#xff0c;将新元素添加到相应…...

请描述一下JVM(Java虚拟机)的生命周期及其对应用程序性能的影响

1、请描述一下JVM&#xff08;Java虚拟机&#xff09;的生命周期及其对应用程序性能的影响。 JVM&#xff08;Java虚拟机&#xff09;的生命周期主要涉及以下几个阶段&#xff1a;加载、验证、准备、解析、执行、卸载。每个阶段都有其特定的作用和影响。 加载&#xff1a;JVM…...

展会邀约|加速科技与您相约IC China 2024!

第二十一届中国国际半导体博览会&#xff08; IC China 2024&#xff09;将于 2024 年11月18日—11月20日在北京国家会议中心举行。加速科技将携高性能测试机ST2500EX、ST2500E、eATE及全系测试解决方案亮相E2馆B150展位。博览会期间&#xff0c;将同期举办"半导体产业前沿…...

鸿蒙中服务卡片数据的获取和渲染

1. 2.在卡片中使用LocalStorageProp接受传递的数据 LocalStorageProp("configNewsHead") configNewsHeadLocal: ConfigNewsHeadInfoItem[] [] 注意&#xff1a;LocalStorageProp括号中的为第一步图片2中的键 3.第一次在服务卡片的第一个卡片中可能会获取不到数据…...

运维篇-修复centos7无法下载docker问题

修复centos7无法下载docker问题 1、安装docker时报错2、docker无法下载镜像 1、安装docker时报错 linux的centos系统&#xff0c;安装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. 字符串&#xff08;String&#xff09;&#xff1a; • 简介&#xff1a;最基础的数据类型&#xff0c;可以存储任何形式的字符串&#xff0c;包括文本数据和数字数据。 • 常用操作&#xff1a;SET、GET、INCR、DECR等。 2. 列表&#xff08;List&#xff09;&#xff1a; …...

kubernetes如何配置默认存储

如果不想每次都创建PV&#xff0c;希望k8s集群中能够配置号默认存储&#xff0c;然后根据你的PVC自动创建PV&#xff0c;就需要安装一个默认存储&#xff0c;也就是storageclass 什么是storageclass Kubernetes提供了一套可以自动创建PV的机制&#xff0c;即&#xff1a;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 驱动包 第一种 通过链接下载&#xff1a;下载 第二种【特指 window 安装包】 在达梦安装包 iso 文件里面 source/drivers/jdbc 将驱动添加进 DataGrip 选中 jdbc 驱动包&#xff0c;然后选…...

数据库监控工具DBdoctor v3.2.4.3版本发布,新增对openGauss、Vastbase G100的支持!

新引擎扩展 新增对openGauss数据库的支持&#xff1a;支持对openGauss数据库的SQL审核、实例巡检、性能洞察、锁透视、根因诊断、基础监控、索引推荐、存储分析&#xff1b; 新增对Vastbase G100数据库的支持&#xff1a;支持对Vastbase G100数据库的SQL审核、实例巡检、性能洞…...

Git 常用命令大全与详解

Git 是一种广泛使用的分布式版本控制系统。无论是管理个人项目还是进行团队协作&#xff0c;掌握 Git 的常用命令都是开发者必备的技能之一。本文将介绍一些常用的 Git 命令&#xff0c;并对其进行详细说明。 1. 基础命令 初始化仓库 git init&#xff1a;在当前目录下初始化…...

执行flink sql连接clickhouse库

手把手教学&#xff0c;flink connector打通clickhouse大数据库&#xff0c;通过下发flink sql&#xff0c;来使用ck。 组件版本jdk1.8flink1.17.2clickhouse23.12.2.59 1.背景 flink官方不支持clickhouse连接器&#xff0c;工作中难免会用到。 2.方案 利用GitHub大佬提供…...

什么是C++中的友元函数和友元类?

友元函数&#xff08;Friend Function&#xff09;和 友元类&#xff08;Friend Class&#xff09;是用于控制类的访问权限的机制。这允许特定的函数或类访问另一个类的私有成员和保护成员&#xff0c;打破了 C 的封装性规则。 友元函数 定义 友元提供了不同类的成员函数之间…...

基于Spring Boot+Vue的多媒体素材管理系统的设计与实现

一.系统开发工具与环境搭建 1.系统设计开发工具 后端使用Java编程语言的Spring boot框架 项目架构&#xff1a;B/S架构 运行环境&#xff1a;win10/win11、jdk17 前端&#xff1a; 技术&#xff1a;框架Vue.js&#xff1b;UI库&#xff1a;ElementUI&#xff1b; 开发工具&…...

Inpaint-Web:纯浏览器端实现的开源图像处理工具

之前在刷短视频的时候&#xff0c;经常看到一些情侣在景区拍照&#xff0c;结果被路人“抢镜”。有时男朋友会拿出手机&#xff0c;帮忙把那些路人“P”掉&#xff0c;简直是既贴心又有趣。最近我在逛 GitHub 时&#xff0c;发现了一个可以在浏览器端删除照片中部分内容的纯前端…...

商业物联网详细指南:优势与挑战

物联网是信息技术行业最具前景的领域之一。为什么它如此热门呢&#xff1f;原因在于全球连接性。设备可以像人群一样相互协作。正如我们所知&#xff0c;协作能显著提高生产力。 物联网对普通用户和企业都有益处。许多日常流程可以通过传感器、扫描仪、摄像头和其他设备实现自…...

如何在项目中用elementui实现分页器功能

1.在结构部分复制官网代码&#xff1a; <template> 标签: 这是 Vue 模板的根标签&#xff0c;包含所有的 HTML 元素和 Vue 组件。 <div> 标签: 这是一个普通的 HTML 元素&#xff0c;包裹了 el-pagination 组件。它没有特别的意义&#xff0c;只是为了确保 el-pagi…...

STM32F107单片机驱动Dp83848以太网芯片程序 项目开发用到了Dp83848这一个以...

STM32F107单片机驱动Dp83848以太网芯片程序 项目开发用到了Dp83848这一个以太网芯片&#xff0c;本人发现其配置起来比较麻烦&#xff0c;所以整理了一份STM32F107单片机驱动Dp83848的程序代码例程&#xff0c;方便大家学习相关代码的配置最近在项目里折腾STM32F107和DP83848这…...

全贴合工艺中Cover Lens Mura不良的关键影响因素与优化策略

1. 全贴合工艺中的Mura现象解析 第一次看到全贴合屏幕上出现发黄或发白的斑块时&#xff0c;我还以为是产品运输途中受了撞击。后来在产线蹲守三个月才发现&#xff0c;这些被称为"Mura"的光学缺陷&#xff0c;其实是贴合工艺中的隐形杀手。Mura这个词源自日语"…...

Android 14 ShellTransitions 实战:手把手教你理解 Transition 如何“抓取”动画参与者(WindowContainer 篇)

Android 14 ShellTransitions 深度解析&#xff1a;WindowContainer 动画参与者捕获机制实战指南 在 Android 14 的动画框架革新中&#xff0c;ShellTransitions 引入了一套精密的"参与者捕获"系统&#xff0c;其运作机制堪比特种部队的精准行动。本文将带您深入这套…...

云原生应用的微服务架构设计

云原生应用的微服务架构设计 引言&#xff1a;微服务架构的重要性 哥们&#xff0c;别整那些花里胡哨的&#xff01;作为一个前端开发兼摇滚鼓手&#xff0c;我最烦的就是单体应用的臃肿和难以维护。在云原生时代&#xff0c;微服务架构已经成为构建现代应用的最佳实践。今天&a…...

如何运用AI技术有效破解企业视觉检测难题

「本文已用流量券推广&#xff0c;欢迎收藏 关注」AI智能体视觉检测系统&#xff08;TVA&#xff09;的核心突破&#xff0c;在于实现了从“被动识别”到“主动决策”的历史性跨越。以汽车零部件制造车间的经典场景为例&#xff0c;螺母焊接点的质检曾是长期困扰各个企业多年的…...

解决 DVWA 联合注入报错:Illegal mix of collations for operation ‘UNION‘ 全指南

一、问题背景在 DVWA 靶场进行 SQL 联合注入测试时&#xff0c;很多小伙伴都会遇到一个经典报错&#xff1a;plaintextIllegal mix of collations for operation UNION这个报错的本质原因非常明确&#xff1a;执行UNION操作时&#xff0c;参与联合查询的多个结果集的字符集&…...

Genshin Impact 模型导入工具完全指南

Genshin Impact 模型导入工具完全指南 【免费下载链接】GI-Model-Importer Tools and instructions for importing custom models into a certain anime game 项目地址: https://gitcode.com/gh_mirrors/gi/GI-Model-Importer 一、模型导入工具核心功能解析 Genshin Im…...

Sunshine游戏串流革命:把你的高性能PC变成私人云游戏服务器

Sunshine游戏串流革命&#xff1a;把你的高性能PC变成私人云游戏服务器 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine 你是否曾经想过&#xff0c;能不能像Netflix一样随时随地玩…...

让经典游戏重获新生:d3d8to9如何终结Direct3D 8兼容性难题

让经典游戏重获新生&#xff1a;d3d8to9如何终结Direct3D 8兼容性难题 【免费下载链接】d3d8to9 A D3D8 pseudo-driver which converts API calls and bytecode shaders to equivalent D3D9 ones. 项目地址: https://gitcode.com/gh_mirrors/d3/d3d8to9 你是否还记得那些…...

Python从入门到精通(第17章):继承与多态——is-a关系彻底理解

开头导语 这是本系列第17章。继承和多态是面向对象最核心的概念,但也是被误解最多的概念。继承的本质是“复用”,而不是“is-a”的语言描述;多态的本质是“同一接口,不同实现”,而不是“子类Override父类方法”这个动作本身。本章会从实际场景出发,讲清楚继承的适用边界…...