logrotate 的 daily 选项需配合 dateext、dateyesterday、create 和 postrotate 中的 USR1 信号才能实现 Nginx 日志按天归档;配置必须置于 /etc/logrotate.d/nginx,权限 644,属主 root:root,并启用 missingok、notifempty 等防错参数。

直接用 logrotate 的 daily 选项本身不会让 Nginx 实际切换日志文件——因为 Nginx 进程仍往旧文件句柄里写,切割只是“改名”,新日志还在老文件里追加。必须配合信号通知 Nginx 重新打开日志,才能真正按天生成新文件。
配置文件必须放在 /etc/logrotate.d/nginx
logrotate 默认只加载 /etc/logrotate.d/ 目录下的配置文件,系统每天通过 /etc/cron.daily/logrotate 自动执行。放错路径(比如 /root/nginx.logrotate)即使手动测试成功,cron 也永远不会运行它。
- 用
sudo tee /etc/logrotate.d/nginx写入配置,避免权限问题 - 文件名就是
nginx,不要加.conf后缀 - 确认权限为
644,属主属组是root:root
关键参数要配全:daily + dateext + dateyesterday + create
只写 daily 不够,得配合日期后缀和权限控制,才能生成像 access.log-2026-07-28 这样带昨日日期的归档文件,并确保新日志可写。
-
daily:每天触发轮转 -
dateext:启用日期后缀(否则是access.log.1这种编号) -
dateyesterday:让归档文件名显示“昨天”的日期,语义更准确 -
dateformat -%Y-%m-%d:指定日期格式,和dateext配套使用 -
create 0644 nginx nginx:轮转后新建日志文件,设好权限和属主(根据你实际运行 Nginx 的用户调整)
postrotate 里必须发 USR1 信号,不能 reload 或 restart
这是最易出错的一环。Nginx 收到 USR1 会原子性地重新打开日志文件,不中断连接、不丢请求;而 systemctl reload 或 restart 会重启 worker 进程,有风险且不必要。
- 推荐写法:
kill -USR1 $(cat /var/run/nginx.pid 2>/dev/null) - 更健壮写法:先查 PID 文件路径
pidfile=$(nginx -t 2>&1 | grep "pid" | awk '{print $NF}'),再判断是否存在并发送信号 - 加上
sharedscripts,确保多个日志文件(如 access.log 和 error.log)只触发一次信号 - 别写
systemctl reload nginx—— 它和日志切割无关,还可能在无 systemd 环境下失败
其他防坑细节
看似小配置,漏了就可能轮转失败或日志丢失。
-
missingok:日志文件当天为空也不报错,避免中断后续轮转 -
notifempty:空文件不轮转,节省空间 -
rotate 30:保留最近 30 份归档,超期自动删 -
compress+delaycompress:压缩旧日志,但最新一轮暂不压,方便排查 - 测试时用
logrotate -d /etc/logrotate.d/nginx先看模拟结果,再用-vf强制执行一次验证


















