logrotate 配置文件位于 /etc/logrotate.conf(主配置)和 /etc/logrotate.d/ 下非隐藏文件;修改后需等待 cron 每日执行或手动运行 logrotate -f,调试用 -d;新增服务配置应放入 /etc/logrotate.d/;rotate 与 maxage 独立生效;sharedscripts 下 postrotate 不可用 $1;路径须用绝对路径,不支持 shell 展开;未匹配日志文件时整个配置块被跳过;无原子性保障,建议对不支持 reopen 的程序使用 copytruncate。

logrotate 配置文件写在哪、怎么加载
logrotate 不会自动扫描任意路径下的配置,它只认固定位置:/etc/logrotate.conf 是主配置,/etc/logrotate.d/ 目录下所有非隐藏文件会被 include 进来。改完配置后不会立即生效——logrotate 默认靠 cron 每天跑一次(通常是 /etc/cron.daily/logrotate),手动测试必须显式调用命令。
- 调试时用
logrotate -d /etc/logrotate.conf查看模拟执行过程(-d 是 debug,不实际轮转) - 强制立即执行用
logrotate -f /etc/logrotate.conf(-f 强制,但注意可能和 cron 冲突) - 新增服务日志配置,推荐放在
/etc/logrotate.d/myapp,别直接改主配置,方便维护和卸载
rotate 12 和 maxage 365 到底谁先触发
rotate 控制保留多少个归档文件,maxage 控制归档文件最多活几天,两者独立生效,不是“满足其一就删”。比如设了 rotate 12 和 maxage 30,某次轮转后发现已有 13 个归档,就会删最老那个;但如果某个归档已满 31 天,哪怕总共才 5 个文件,也会被立刻清理。
-
maxage只对已轮转出的.1、.2等压缩文件生效,不影响正在写的当前日志 - 时间判断基于文件 mtime,不是日志内容里的时间戳,所以不要手动 touch 归档文件
- 如果日志量极小、轮转频率低,
maxage可能长期不触发,此时rotate是主要控制手段
sharedscripts 和 postrotate 里不能用 $1
sharedscripts 的作用是让 postrotate 脚本在整个匹配块内只执行一次(而不是每个日志文件都执行一遍),但它同时导致脚本里无法用 获取当前处理的文件路径——因为“当前文件”在 shared 模式下已不明确。
- 需要知道具体文件名?去掉
sharedscripts,改用普通模式,然后postrotate中$1就是本次轮转的旧日志路径(如/var/log/myapp.log.1) - 只想 reload 一次 nginx?用
sharedscripts,但postrotate里只能写systemctl reload nginx这种不依赖路径的操作 - 常见错误:
sharedscripts开着却在postrotate里写gzip -d $1,结果 $1 为空或报错
日志路径含通配符时的匹配陷阱
logrotate 支持 /var/log/app/*.log 这种 glob,但注意:它只在首次读取配置时展开一次,且不支持递归(** 不行)。更关键的是,如果某次运行时没有匹配到任何文件,整个配置块会被跳过——postrotate 不执行,rotate 计数也不增加。
- 确认是否匹配成功,加
logrotate -d看 debug 输出里有没有 “considering log file” 行 - 路径中避免用 ~ 或 $HOME,logrotate 不做 shell 展开,必须写绝对路径
- 如果日志按日期命名如
app-2024-04-01.log,别指望app-*.log能自动覆盖新文件——每次新增文件都要等下次 cron 扫描才纳入轮转范围
最常被忽略的一点:logrotate 本身不保证原子性。如果应用持续写日志,而你又没配 copytruncate 或 create,轮转瞬间可能出现写入失败或丢日志。尤其对不支持 reopen 的老程序,copytruncate 是保底方案,但要注意它和磁盘空间竞争的风险。










