logrotate 配合 Nginx USR1 信号可安全轮转日志,需正确配置路径、权限、sharedscripts 和 delaycompress,并手动测试及验证定时任务。

直接用系统自带的 logrotate 配合 Nginx 的信号机制,就能稳住日志体积、避免磁盘打满或服务卡死。关键不是“能不能切”,而是切得及时、压缩得合理、通知 Nginx 重开文件不丢日志。
确认你的日志路径和 Nginx 进程文件位置
不同安装方式路径可能不同,别直接抄模板:
- 查日志实际路径:
nginx -T | grep "access_log\|error_log" - 查 PID 文件位置:
nginx -t -c /etc/nginx/nginx.conf后看配置里pid指令,或试这几个常见路径:/var/run/nginx.pid、/run/nginx.pid、/usr/local/nginx/logs/nginx.pid - 如果用 systemd 管理,也可运行
systemctl show --property=MainPID nginx辅助验证
写一个安全可用的 logrotate 配置
推荐保存为 /etc/logrotate.d/nginx,内容示例如下(请按你的真实路径调整):
/var/log/nginx/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 $(cat /var/run/nginx.pid)
fi
endscript
}
重点说明几个防坑参数:
- delaycompress:避免刚轮转完就压缩,确保当天日志仍可被 tail 或分析工具读取
- sharedscripts:多个日志(如 access.log + error.log)共用一次 postrotate,防止重复发信号
- create 0640 www-data adm:新日志文件权限和属主属组要匹配 Nginx 工作进程,否则会写入失败
- 不用
dateext也行,但加了后归档名带日期(如access.log-20260501),排查更直观
手动测试 + 定时触发必须做两件事
光配完不验证,等于没配:
- 先手动跑一次:
logrotate -f /etc/logrotate.d/nginx,检查/var/log/nginx/下是否生成access.log.1、error.log.1,且新日志能继续写入 - 确认系统级定时任务已启用:
ls /etc/cron.daily/logrotate存在即表示每天自动执行;若无,logrotate 默认依赖此脚本,无需额外加 crontab - 如需精确到小时或自定义时间(比如避开业务高峰),可单独加 crontab:
59 23 * * * /usr/sbin/logrotate /etc/logrotate.d/nginx
常见阻塞问题快速定位与修复
如果日志还在涨、磁盘还是满,优先排查这几处:
- Nginx 没收到 USR1 信号 → 检查
postrotate里 PID 路径是否正确、文件是否存在、Nginx 是否以 root 启动(否则普通用户无法 kill) - 轮转后新日志为空 → 查
create权限是否和 Nginx worker 进程用户一致(如用www-data,但 create 写成root:root就会失败) - 压缩没生效 → 确认系统装了 gzip:
gzip --version;nocompress或compress写反了也会失效 - 磁盘仍报警 → 旧归档没删干净,检查
rotate 30是否生效:ls -lt /var/log/nginx/*.gz | head -10,看最老的是否超过 30 天











