c++如何实现简单的日志滚动轮转功能_按文件大小自动切分【实战】

张开发
2026/4/11 0:17:34 15 分钟阅读

分享文章

c++如何实现简单的日志滚动轮转功能_按文件大小自动切分【实战】
日志轮转需手动在每次写入前检查文件大小用stat()跨平台获取尺寸倒序重命名旧文件如.log→.1、.1→.2并用互斥锁原子变量保证多线程安全Windows下须先close再rename。用 std::ofstream 检查文件大小并触发轮转核心逻辑不是靠库自动做而是每次写日志前手动判断当前日志文件是否超限。C 标准库没内置滚动功能得自己读 std::filesystem::file_size()C17 起或用 stat()跨 C 版本更稳。常见错误是只在程序启动时检查一次大小结果日志越写越大正确做法是在每次调用 log() 函数写入前检查。推荐用 stat()兼容性好Windows 用 _stat()Linux/macOS 用 stat()封装一层就行阈值别设太小如 1KB频繁打开关闭文件影响性能也别太大如 1GB排查问题时难加载注意文件句柄未关闭导致 stat() 返回旧大小——写完必须 flush()且轮转后要确保旧 std::ofstream 对象已析构或 close()轮转时怎么重命名旧文件access.log → access.log.1不能直接用 std::filesystem::rename() 简单覆盖因为已有 .1 时再轮转要变成 .2还得把原来的 .1 变成 .2依此类推——本质是个倒序移动过程。容易踩的坑是循环重命名时顺序错了比如先重命名 .1 → .2再 current → .1结果 .1 被覆盖丢失。立即学习“C免费学习笔记深入”从最大编号开始倒着移先 access.log.9 → access.log.10再 .8 → .9……最后 access.log → access.log.1最大保留份数建议设为 510太多磁盘占满太少查不到历史Windows 下对正在写的文件调用 rename() 会失败权限拒绝需确保 std::ofstream 已 close()多线程写日志时如何避免轮转冲突多个线程同时判断“该不该轮转”可能一起执行重命名清空导致部分日志丢失或文件损坏。这不是加个 std::mutex 就能全解决的——锁粒度太粗会卡住所有日志写入。 Mokker AI AI产品图添加背景

更多文章