rotate 和 maxage 不冲突,logrotate 同时检查二者,任一不满足即删除;rotate 按数量保留归档,maxage 按时间统一清理。

logrotate 配置文件里 rotate 和 maxage 同时设了,哪个优先?
两者不冲突,但作用完全不同:rotate 控制保留多少个归档文件(按数量),maxage 控制文件最多保留多少天(按时间)。logrotate 会同时检查这两个条件,**只要任一条件不满足,对应日志就立刻被删掉**。
常见错误是以为设了 rotate 7 就够了,结果日志生成不规律,某天没写日志,过了 30 天才又写,这时 maxage 30 就会把那个“老但合法”的归档干掉——而 rotate 根本管不到它。
-
rotate 7:只管“最近生成的 7 个归档”,不管它们多老 -
maxage 30:对所有匹配的日志归档统一检查“创建时间是否超 30 天” - 真实场景建议两个都设,尤其监控类服务日志,避免磁盘被长期静默的日志占满
用 dateext 时为什么 dateformat 不能随便写?
dateext 开启后,logrotate 默认用 -%Y%m%d 命名归档(如 access.log-20241015)。想改格式必须配 dateformat,但注意:它只支持 strftime 的有限子集,且不同 logrotate 版本支持程度不同。
常见坑:用 %s(秒级时间戳)或 %N(纳秒)会导致配置加载失败,报错 error: bad dateformat;某些旧版(如 CentOS 7 自带的 3.8.x)甚至不认 %Y,只认 %y(两位年份)。
- 安全写法:
dateformat -%Y%m%d或dateformat -%y%m%d - 避免用:
%s、%F(部分版本不支持)、%Z(时区,易出错) - 验证方法:运行
logrotate -d /etc/logrotate.conf看 debug 输出里归档名是否符合预期
脚本里执行 systemctl reload nginx 失败,但手动跑却 OK
logrotate 默认以 root 身份运行,但它的环境变量极简(几乎没 $PATH),也**不读取 shell profile**。所以你在终端能直接敲 systemctl,logrotate 却找不到命令,报 /bin/sh: systemctl: not found。
更隐蔽的问题是:某些 systemd 版本要求 systemctl 必须在特定 cgroup 或 dbus 上下文里调用,而 logrotate 的子 shell 不提供这些。
- 绝对路径必写:
postrotate里用/usr/bin/systemctl reload nginx,别省略 - 加环境兜底:
postrotate开头加export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - 如果 reload 还失败,改用
kill -USR1 $(cat /var/run/nginx.pid)(前提是 nginx 支持该信号重载配置)
多个配置文件里定义同一日志路径,谁生效?
logrotate 按字母顺序读取 /etc/logrotate.d/ 下的文件,**后加载的配置会覆盖先加载的同名路径规则**。比如 /etc/logrotate.d/nginx 和 /etc/logrotate.d/myapp 都写了 /var/log/nginx/access.log,那 myapp 里的配置最终生效。
这很容易导致线上行为和预期不符——你以为改的是 nginx 配置,实际被另一个文件覆盖了。debug 时仅看单个文件根本发现不了问题。
- 查加载顺序:
ls -1 /etc/logrotate.d/ | sort - 查最终生效规则:
logrotate -d /etc/logrotate.conf 2>&1 | grep "considering log file" -A 10 - 最佳实践:一个日志路径只在一个配置文件里定义,用注释标明归属,别图省事复用
最麻烦的不是语法写错,是配置散落在不同文件里,还靠字母序隐式覆盖——这种问题得翻完整目录才能定位。










