logrotate 是首选,因其提供日志生命周期管理(检测增长、切分、权限设置、服务重载、延迟压缩、自动清理),而 cron+gzip 易导致损坏压缩、服务不重开、通配路径不支持等问题。

直接用 logrotate 配置,别自己写 cron + gzip 脚本——后者容易漏掉轮转、权限、空文件、服务重载等关键环节,出问题时连日志都没法查。
为什么 logrotate 是首选而不是 cron + gzip
logrotate 不只是“压缩”,它是一整套日志生命周期管理:检测增长、切分旧文件、设权限、通知服务重开日志、延迟压缩、自动清理。而 cron + gzip /var/log/syslog 这类做法会直接压缩正在写的文件,导致:
- 压缩时日志还在被 syslogd 写入,
gzip可能压出损坏或不完整的内容 - 原始文件被删,新日志继续写进同名文件,但没触发轮转,下次再压就压错对象
- 没有
postrotate机制,Nginx/MySQL 等服务不会重开日志文件,导致磁盘空间不释放 - 无法处理
/var/log/nginx/*.log这种通配路径,也不能按大小(size 100M)触发
/etc/logrotate.d/ 下的配置怎么写才不踩坑
以压缩 /var/log/syslog 为例,新建 /etc/logrotate.d/syslog,内容必须包含这些关键项:
"/var/log/syslog" {
daily
missingok
rotate 7
compress
delaycompress
notifempty
create 0640 root adm
sharedscripts
postrotate
/usr/bin/systemctl kill --signal=USR1 --kill-who=main syslog.service > /dev/null 2>&1 || true
endscript
}
注意点:
- 路径加英文双引号:防止路径含空格或特殊字符时报错
- 必须写
missingok:syslog 服务未启动时日志文件不存在,否则整个 logrotate 会中断 -
delaycompress和compress要一起用:避免copytruncate场景下压到空文件;第一次切完不压,第二次切时才压上一轮 -
sharedscripts+postrotate:确保所有匹配文件轮转完再执行一次重载命令,不是每个文件都 reload 一遍 - systemctl kill --signal=USR1:比
service rsyslog reload更可靠,兼容 systemd 所有发行版
如何验证配置是否生效且无语法错误
别等第二天看效果。立刻做三件事:
- 运行
logrotate -d /etc/logrotate.d/syslog:只打印将要执行的动作,不真实改动文件,检查输出里有没有 “compressing log”、“running postrotate script” - 手动强制执行一次:
logrotate -f /etc/logrotate.d/syslog,然后检查:ls -l /var/log/syslog*是否出现syslog.1和syslog.1.gz - 确认 cron 是否真在跑:
grep logrotate /etc/cron.daily/应该返回/usr/sbin/logrotate /etc/logrotate.conf;再查最近执行记录:sudo grep "logrotate" /var/log/syslog | tail -3
压缩工具和参数影响实际效果
logrotate 默认用 gzip,但你可以换更快或更高压缩率的工具:
- 改用 zstd(快且高压缩):
compresscmd /usr/bin/zstd+compressext .zst - 禁用压缩(仅轮转):
nocompress,适合调试期或 SSD 小容量设备 - 慎用
compress配合高频小日志:比如每秒写几行的 debug 日志,压缩反而增加 I/O 压力,建议关掉或改用delaycompress - 不要在配置里写绝对路径如
/bin/gzip:logrotate 内部调用的是 PATH 下的命令,确保which gzip有输出即可
真正容易被忽略的是 delaycompress 和 sharedscripts 的组合逻辑——它们不是可选项,而是保障原子性和服务连续性的必要设计。没配对,压缩可能成功,但服务日志就断了。











