logrotate 的 size 和 daily 互斥,需据日志增长特性选择:daily 适合稳定日志按天归档,size 适合突发流量防单文件过大;postrotate 必须 reload 服务以确保写入新日志,不可省略。

logrotate 的 size 和 daily 是两种互斥的轮转触发条件,不能同时生效;选择哪个取决于日志增长特性和运维目标。postrotate 脚本不是“可有可无”的附加项,而是确保服务持续写入新日志的关键环节,尤其在使用 copytruncate 之外的场景下必须正确 reload 或 reopen 日志句柄。
size vs daily:如何选?关键看日志写入节奏
daily 表示每天固定时间(默认由 cron 触发)检查并轮转,不管当天日志是否写满;size 则只关注单个日志文件体积,达到阈值立即轮转,与时间无关。二者不可共存——logrotate 遇到 size 就忽略 daily,反之亦然。
- 选 daily:适用于日志量稳定、按天归档便于审计或备份的场景(如 Nginx access.log、系统 audit 日志);需配合
dateext和dateformat保证文件名可读 - 选 size:适用于突发流量导致日志暴增的服务(如调试中的应用、高频 API 网关);推荐设为
size 100M或size 500M,避免单文件过大影响 grep 或传输 - 慎用
hourly或weekly:hourly 依赖 cron 每小时执行一次,但 logrotate 默认不自带 hourly 任务,需手动添加;weekly 可能导致周中日志堆积过多
postrotate 脚本必须做三件事:通知服务、验证成功、避免竞态
postrotate 执行时机是旧日志已重命名、新日志尚未创建时。此时若服务仍向原文件路径写入,就会写进已轮转的旧文件(除非用了 copytruncate),导致日志丢失。
-
必须发送信号或调用 reload:例如
systemctl reload nginx、kill -USR1 `cat /var/run/nginx.pid`、/usr/bin/pkill -USR1 rsyslogd;不要用restart,会中断服务 -
加简单校验逻辑:比如轮转后
ls -l /var/log/nginx/access.log应返回“no such file”,或检查systemctl is-active nginx是否仍为 active -
避免脚本失败导致后续轮转卡住:在 postrotate 开头加
set +e(允许错误继续),或用|| true包裹非关键命令;但 reload 类操作失败应保留退出码,方便排查
常见陷阱与绕过方案
很多问题不是配置写错,而是没理解 logrotate 的执行上下文和权限模型。
-
权限不足:logrotate 默认以 root 运行,但 postrotate 中调用的 reload 命令可能依赖用户环境变量(如 PATH);建议写绝对路径:
/bin/systemctl reload nginx,而非仅systemctl - copytruncate 不是万能解:它通过截断原文件实现“无感知”轮转,但存在微小窗口期——截断后、写入前,部分日志可能丢失;高可靠性场景仍应优先走 signal/reload 方式
-
多个配置匹配同一文件:logrotate 按配置文件字典序加载,后加载的规则会覆盖先加载的;用
logrotate -d /etc/logrotate.conf查看实际生效规则,确认无冲突
一个生产可用的 Nginx 示例
兼顾大小控制、时间归档和安全 reload:
/var/log/nginx/*.log {
size 200M
rotate 30
compress
delaycompress
missingok
notifempty
create 0644 www-data www-data
sharedscripts
postrotate
if systemctl is-active --quiet nginx; then
systemctl reload nginx 2>/dev/null || true
fi
endscript
}
注意:这里用 size 主控,但保留 rotate 30 防止单日突增撑爆磁盘;sharedscripts 确保多个日志文件共用一个 postrotate,避免重复 reload。










