nginx 本身不支持按天自动切割日志,需借助 logrotate 实现:配置 /etc/logrotate.d/nginx,含 daily、rotate 30、compress、delaycompress、missingok、create 0644 nginx nginx 及 postrotate 段发送 kill -usr1 重载日志,再通过 logrotate -f 手动验证。

Nginx 本身不支持按天自动切割日志,需借助系统工具 logrotate 实现。关键在于配置 logrotate 规则、确保 Nginx 在日志轮转后使用新文件写入(即重载日志缓冲区),并避免权限或路径问题导致失败。
logrotate 基础配置示例
在 /etc/logrotate.d/nginx 中创建配置文件,内容如下:
- /var/log/nginx/*.log:指定要轮转的日志路径(如 access.log、error.log)
- daily:每天执行一次轮转
- missingok:日志文件不存在时不报错
- rotate 30:保留最近 30 个归档文件(如 access.log.1、access.log.2…)
- compress:用 gzip 压缩旧日志(生成 .gz 文件)
- delaycompress:延迟压缩,最新一轮不压,便于排查
- notifempty:日志为空时不轮转
- create 0644 nginx nginx:轮转后新建日志文件,并设属主、属组和权限
必须配置 postrotate 段重载日志
logrotate 默认只改名/压缩日志,Nginx 进程仍往旧文件句柄写入,会导致磁盘空间不释放。必须通知 Nginx 关闭旧文件、打开新文件:
- 在配置中添加 postrotate … endscript 块
- 典型写法:
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript - USR1 信号是 Nginx 的“重新打开日志文件”指令,安全且不中断服务
- 若用 systemctl 管理,也可写成 systemctl reload nginx,但 reload 会轻微中断连接;USR1 更轻量
验证与排错要点
配置完成后不能直接等明天,应主动测试:
- 手动触发:运行 logrotate -f /etc/logrotate.d/nginx(-f 强制执行)
- 检查:ls -lt /var/log/nginx/ 是否生成了 access.log.1.gz,原 access.log 是否变为空文件
- 确认 Nginx 进程仍在写新日志:tail -f /var/log/nginx/access.log 应有实时请求输出
- 常见问题:
– 权限不对:logrotate 以 root 运行,但 create 指令中用户/组名(如 nginx)必须真实存在
– PID 文件路径错误:USR1 发送前先确认 cat /var/run/nginx.pid 能读取且内容有效
– SELinux 或 AppArmor 限制:某些系统需额外策略允许 logrotate 向 Nginx 进程发信号
补充建议
为避免多实例或容器环境出错,可进一步加固:
- 在 logrotate 配置开头加 sharedscripts:多个日志文件共用一个 postrotate,避免重复发信号
- 加 dateext 和 dateformat -%Y%m%d:归档名带日期(如 access.log-20241025.gz),比数字序号更直观
- 定期检查 logrotate 执行日志:/var/lib/logrotate/status 记录上次轮转时间,或查看 /var/log/messages | grep logrotate











