nginx 本身不支持按日期自动切割访问日志,需借助 logrotate(推荐)或 shell 脚本 + cron 实现;logrotate 通过 daily、postrotate kill -usr1 等配置实现每日轮转并通知 nginx 重开日志文件。

在 Nginx 中,本身不内置按日期自动切割访问日志的功能(比如每天生成 access.log.2024-04-05 这样的文件),需要借助外部工具或脚本配合实现。最常用、最稳妥的方式是使用 logrotate 工具 —— 它是 Linux 系统中专为日志轮转设计的标准方案,支持按天、按大小、按周等策略,并能自动重载 Nginx 以切换到新日志文件。
用 logrotate 按日期轮转 Nginx 日志(推荐)
logrotate 默认通常已安装(CentOS/RHEL/Fedora 自带,Ubuntu/Debian 可通过 apt install logrotate 安装)。配置步骤如下:
- 创建或编辑 Nginx 的 logrotate 配置文件,例如:
/etc/logrotate.d/nginx - 写入以下内容(适配你的实际日志路径):
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.2024-04-05) - rotate 30:保留最近 30 个归档日志(超过则删除最旧的)
- compress + delaycompress:压缩旧日志,但最新一轮不立即压缩(方便排查)
-
create:轮转后新建原始日志文件,权限和属主设为
www-data:www-data(根据你 Nginx 运行用户调整,如 CentOS 常用nginx:nginx) -
postrotate … kill -USR1 …:这是关键!Nginx 收到
USR1信号后会重新打开日志文件,从而写入新的access.log,旧文件交由 logrotate 处理
验证与手动触发
配置完成后建议测试:
- 检查语法是否正确:
logrotate -d /etc/logrotate.d/nginx(-d 表示 debug 模式,不实际执行) - 手动强制执行一次轮转:
logrotate -f /etc/logrotate.d/nginx - 确认新日志文件已生成、原日志被重命名、Nginx 进程仍在写入
access.log(可用ls -lt /var/log/nginx/和tail -f /var/log/nginx/access.log观察)
替代方案:用 shell 脚本 + cron(适合轻量或定制需求)
如果因环境限制无法用 logrotate,可写简单脚本配合 crontab:
- 新建脚本
/usr/local/bin/rotate-nginx-log.sh:
LOG_DIR="/var/log/nginx"
DATE=$(date +%Y-%m-%d)
mv "$LOG_DIR/access.log" "$LOG_DIR/access.log.$DATE"
mv "$LOG_DIR/error.log" "$LOG_DIR/error.log.$DATE"
kill -USR1 $(cat /var/run/nginx.pid 2>/dev/null)
- 赋予执行权限:
chmod +x /usr/local/bin/rotate-nginx-log.sh - 添加定时任务(每天凌晨 0 点执行):
0 0 * * * /usr/local/bin/rotate-nginx-log.sh
⚠️ 注意:该方式需自行处理日志清理、压缩、权限等问题,不如 logrotate 稳健,仅作补充方案。
重要提醒
- Nginx 必须以 master process 模式运行(默认即如此),才能响应
USR1信号重新打开日志;若用daemon off;或容器中前台运行,此机制不生效 - 确保
pid文件路径与配置中pid /var/run/nginx.pid;一致(查看nginx.conf) - 日志路径要和
nginx.conf中access_log /var/log/nginx/access.log;完全匹配











