logrotate 的 size 与 daily 是“或”关系而非“且”关系,任一满足即轮转;daily 提供保底节奏,size 实现弹性响应,二者共存但不协同。

logrotate 不支持真正意义上的 “Size + Daily 组合策略” —— 它不是同时满足两个条件才触发,而是「任一条件满足即轮转」。所谓“Size + Daily”,本质是设置双重触发机制:既每天检查一次(由 cron 驱动),又实时监控文件大小;只要当天日志达到 size 阈值,立刻轮转,不必等到凌晨。
为什么 daily 和 size 能“共存”但不“协同”
logrotate 的设计逻辑是“条件或触发”。例如配置:
/var/log/app/app.log {
daily
size 100M
rotate 7
compress
missingok
notifempty
create 0644 app app
postrotate
systemctl kill --signal=USR1 app || true
endscript
}
它的实际行为是:
- 每天系统 cron(通常是 /etc/cron.daily/logrotate)执行一次 logrotate,此时若文件存在且未空,就按 daily 规则检查是否该轮转(不管大小)
- 同时,logrotate 在每次运行时都会读取当前文件大小;一旦发现 ≥ 100M,立即执行轮转,哪怕距离上次轮转才过了2小时
- 也就是说:daily 提供保底节奏,size 提供弹性响应;二者不冲突,也不需要互斥开关
如何实现“固定时间内多频次轮转”
目标是让日志在一天内被切多次(比如每2小时一次),但又不想改系统 cron 频率(因为全局影响大)。可行路径只有一条:用 size 控制高频切割,再配合合理阈值和保留策略。
- 估算平均写入速率:比如服务峰值时每分钟写 5MB,则 2 小时约 600MB → 设 size 600M 可大致达成 2 小时一割
- 避免过小的 size(如 10M):会导致频繁调用 postrotate,加重 reload 压力,还可能因脚本竞态引发日志丢失
- 配合 rotate 数值加大:比如设 rotate 24,确保一天最多存 24 份,防止磁盘撑爆
- 务必启用 dateext:否则同一天内多次轮转会生成
app.log.1、app.log.2这类无时间标识的文件,难以区分顺序
关键注意事项:postrotate 必须适配高频场景
轮转变频繁,postrotate 脚本的健壮性就更关键。常见问题和对策:
- 服务不支持快速连续 USR1:某些老版本 Nginx 或自研服务 reload 有最小间隔要求 → 改用 copytruncate(但要接受极短窗口丢日志风险)
- pid 文件临时缺失导致 kill 失败:在 postrotate 中加判断,如
[ -s /var/run/app.pid ] && kill -USR1 "$(cat /var/run/app.pid)" - 脚本执行超时或卡住:在 postrotate 开头加
set -o pipefail; set +e,非核心命令失败不中断,但 reload 类操作应保留退出码 - 避免 sharedscripts 误用:如果一个配置匹配多个日志文件(如
/var/log/app/*.log),且用了 sharedscripts,postrotate 只执行一次 —— 这对高频轮转是安全的;但若每个文件需独立通知,就不要加 sharedscripts
验证与调试建议
上线前务必手动测试,别依赖 cron 自动跑:
- 用
logrotate -d /etc/logrotate.d/app查看模拟输出(-d 是 debug 模式,不真实执行) - 用
logrotate -f /etc/logrotate.d/app强制执行一次,观察日志是否重命名、新文件是否生成、服务是否仍在写新文件 - 轮转后立刻检查:
ls -lt /var/log/app/*.log*看时间戳和文件名,tail -f /var/log/app/app.log确认新日志有内容写入 - 压测写入:用
yes "test log" | head -n 1000000 >> /var/log/app/app.log快速灌满,验证 size 是否及时触发


















