nginx本身不支持按日期自动滚动日志,需借助logrotate或cron脚本实现;推荐使用logrotate配置daily轮转、usr1重载,并设置rotate 30、compress等策略确保日志按天归档与清理。

Nginx 本身不支持按日期自动滚动日志(如 access.log.20240520),它只提供 access_log 指令将日志写入固定文件或 syslog。要实现按日期滚动,需借助外部工具配合定时任务完成日志切割和归档。
使用 logrotate 管理 Nginx 日志(推荐)
logrotate 是 Linux 下最常用、稳定且灵活的日志轮转工具,支持按天、大小、周等策略,并能自动重载服务让 Nginx 切换到新日志文件。
- 编辑配置文件:
/etc/logrotate.d/nginx(若不存在可新建) - 写入以下内容(适配你的日志路径):
/var/log/nginx/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 0644 www-data www-data
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}-
daily:每天轮转一次,生成类似access.log.20240520的归档文件 -
rotate 30:保留最近 30 个归档 -
postrotate ... kill -USR1:通知 Nginx 重新打开日志文件(关键步骤,否则新日志仍写入旧文件) - 确保 Nginx 主进程有权限读取
/var/run/nginx.pid,且用户为www-data(Ubuntu/Debian)或nginx(CentOS/RHEL)
手动脚本 + cron 定时切换(轻量替代方案)
若无法安装 logrotate(如某些容器环境),可用 shell 脚本配合 cron 实现基本按日切割。
- 新建脚本
/usr/local/bin/nginx-rotate.sh:
#!/bin/bash LOG_DIR="/var/log/nginx" DATE=$(date -d "yesterday" +%Y%m%d) mv "$LOG_DIR/access.log" "$LOG_DIR/access.log.$DATE" mv "$LOG_DIR/error.log" "$LOG_DIR/error.log.$DATE" # 通知 Nginx 重开日志 kill -USR1 $(cat /var/run/nginx.pid 2>/dev/null)
- 赋予执行权限:
chmod +x /usr/local/bin/nginx-rotate.sh - 添加 crontab(每天凌晨 00:01 执行):
1 0 * * * /usr/local/bin/nginx-rotate.sh
- 注意:该方式不处理日志压缩、过期清理,需额外补充逻辑
验证日志是否成功按日期滚动
运行后检查:
- 当前日志文件时间戳是否为当天:
ls -lh /var/log/nginx/access.log - 是否存在昨日命名的归档:
ls /var/log/nginx/access.log.* - Nginx 进程是否仍在运行,且无“open() failed”类错误(
nginx -t && systemctl status nginx) - 查看 Nginx 错误日志确认重载成功:
tail -n 5 /var/log/nginx/error.log,正常应无 USR1 相关报错
注意事项与常见问题
-
USR1 信号是关键:Nginx 收到
SIGUSR1后会关闭旧文件句柄并重新打开access_log指定的文件。若未发送,日志仍会追加到已重命名的旧文件中 -
权限一致:移动后的日志文件属主应与 Nginx 工作用户一致(如
www-data),否则重载后可能因权限不足无法写入新日志 -
容器环境处理:Docker 中建议用
logrotate镜像或挂载宿主机日志目录,在宿主机统一管理;避免在容器内跑 cron -
不建议用 access_log 变量动态路径:例如
access_log /var/log/nginx/access_$(date +%Y%m%d).log是无效的——Nginx 不解析 shell 变量,该写法会导致启动失败











