logrotate 不支持自动 MD5 校验,需通过 postrotate 脚本调用 md5sum 实现;须根据 compress 和 delaycompress 配置判断校验文件(.1 或 .1.gz),并检查文件存在性,MD5 值应存于独立位置。

logrotate 本身不支持自动 MD5 校验
logrotate 是一个纯文件管理工具,它只负责重命名、压缩、删除和创建新日志,不生成也不验证任何哈希值。如果你在 /etc/logrotate.d/myapp 里写了 md5sum 相关配置,logrotate 会直接忽略——它根本不认识这个指令。
想实现“切割后自动校验”,必须靠外部机制介入,最常用且可靠的方式是利用 postrotate 脚本,在日志完成切割、归档、压缩(如有)之后,立即对刚生成的归档文件计算并保存 MD5。
在 postrotate 中调用 md5sum 保存校验值
以每日切割 Nginx 访问日志为例,假设你希望每次切割出的 access.log.1(或压缩后的 access.log.1.gz)都有对应 MD5 记录:
- 如果未启用压缩(
compress关闭),归档文件是明文,直接对access.log.1运行md5sum - 如果启用了压缩(默认行为),logrotate 会先重命名成
access.log.1,再调用gzip压成access.log.1.gz,此时应校验access.log.1.gz -
postrotate脚本执行时,access.log.1(或.gz)已存在,但access.log已被清空或重建,时机刚好
示例配置片段(/etc/logrotate.d/nginx):
"/var/log/nginx/access.log" {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 0644 www-data www-data
sharedscripts
postrotate
# 校验刚生成的压缩归档(注意:delaycompress 下 .1.gz 尚未生成,要用 .1)
if [ -f /var/log/nginx/access.log.1 ]; then
md5sum /var/log/nginx/access.log.1 > /var/log/nginx/access.log.1.md5
elif [ -f /var/log/nginx/access.log.1.gz ]; then
md5sum /var/log/nginx/access.log.1.gz > /var/log/nginx/access.log.1.gz.md5
fi
endscript
}校验脚本需区分压缩状态与文件存在性
很多人卡在这一环:脚本写了 md5sum access.log.1.gz,但实际生成的是 access.log.1(因为用了 delaycompress),结果校验失败或报错 No such file。
关键点在于理解 logrotate 的压缩时机:
-
compress+delaycompress:本次切割的.1不压缩,等下次轮转时才把当时的.1压成.2.gz→ 此时应校验.1 -
compress但无delaycompress:切割后立刻压缩.1→ 应校验.1.gz - 务必用
[ -f ... ]检查文件是否存在,避免脚本因路径错误中断整个 logrotate 流程
更稳妥的做法是统一用 ls -t /var/log/nginx/access.log.* | head -n1 找最新归档,但要注意通配符可能匹配到 .md5 文件,建议加 | grep -v '\.md5$' 过滤。
验证时别直接比对原始日志内容
MD5 校验对象必须是切割后存档的文件本身,不是原始 access.log。常见误区是拿 md5sum access.log 和 access.log.1.md5 里的值比——这毫无意义,因为两者内容完全不同。
正确验证流程只有两种场景:
- 确认归档文件传输后是否损坏:在目标机器上运行
md5sum access.log.1,与源端access.log.1.md5内容逐字比对 - 确认 logrotate 切割过程未引入数据截断:用
cat access.log.1 access.log.2 access.log.3 | md5sum和切割前原始日志的 MD5 对比(仅适用于未压缩、且所有归档都保留的场景)
最后一句提醒:MD5 值本身要存放在独立位置(比如专用校验目录或远程存储),否则磁盘故障时 .md5 和归档文件一起丢,校验就失去意义。

















