feat: 日志轮转(保留 14 天)

main.log 无轮转、已涨到 34MB,且每晚任务都会继续追加。

- logrotate/xwlb 模板 + scripts/install_logrotate.sh(幂等,装到 /etc/logrotate.d/xwlb)
- 每天轮转、保留 14 份、立即压缩 → main.log-YYYYMMDD.gz
- 必须用 copytruncate:脚本以 >>main.log 长开句柄,改名式轮转会
  让当晚日志写进归档、新文件空着
- journald 同步设 MaxRetentionSec=14day + SystemMaxUse=500M
- 安装脚本自带 logrotate -d 校验(这条立刻抓到"指令行尾注释"被当成参数值的错误)
- tests/test_logrotate.py 19 项,锁住保留天数、行尾注释、占位符替换

实测:34MB → 2.9MB,归档 32453 行与轮转前完全一致
This commit is contained in:
2026-09-25 12:50:11 +08:00
parent b996b444c4
commit 1d3ba02703
7 changed files with 226 additions and 5 deletions
+35
View File
@@ -0,0 +1,35 @@
# 《新闻联播》抓取入库 —— 项目日志轮转
#
# 安装:bash scripts/install_logrotate.sh
# (会把 @PROJECT_DIR@ / @OWNER@ 替换成实际路径与用户后装到 /etc/logrotate.d/xwlb)
#
# 为什么用 copytruncate 而不是默认的"改名+新建":
# 脚本以 >>main.log 的方式持续写入,一次任务可能跑几十分钟,文件句柄一直开着。
# 改名式轮转会让**运行中的进程继续写旧文件**(新 main.log 要到下次任务才有内容),
# 当晚的日志会被切进归档里。copytruncate 是"先复制再原地截断",句柄始终有效。
# 代价是复制与截断之间若有写入,那几行会丢(微秒级窗口),日志可接受。
#
# 未用 delaycompress:归档立即压缩(34MB → 约 2MB),磁盘马上回收;
# 需要看归档内容用 zcat main.log-YYYYMMDD.gz。
#
# 注意:logrotate 不支持行尾注释(会把它当成参数值),注释只能单独成行。
@PROJECT_DIR@/main.log {
# 每天轮转
daily
# 保留 14 份,即 14 天
rotate 14
# 文件不存在不报错
missingok
# 空文件不轮转
notifempty
# 压缩归档
compress
# 见上文:不打断正在写入的进程
copytruncate
# 归档名带日期 → main.log-20260925.gz
dateext
dateformat -%Y%m%d
# logrotate 以 root 运行,切到日志属主操作(避免权限告警)
su @OWNER@ @GROUP@
}