nginx日志切割需借助外部脚本+cron实现:先原子移动日志文件,再执行nginx -s reopen重载句柄,确保服务不中断;脚本须用绝对路径、指定运行用户,并记录日志;推荐优先使用logrotate,因其更健壮且原生支持压缩、权限创建与postrotate信号通知。

在 Nginx 中,日志切割本身不内置自动轮转功能,需借助外部脚本 + 系统定时任务(如 cron)来实现自动化。核心思路是:用脚本移动当前日志文件、通知 Nginx 重新打开日志句柄(避免中断写入),再由 cron 定期触发该脚本。
日志切割脚本怎么写(含关键细节)
一个安全可靠的切割脚本需满足三点:原子性移动日志、正确重载 Nginx、保留历史可追溯性。示例脚本(保存为 /usr/local/bin/nginx-log-rotate.sh):
- 定义日志路径(如 /var/log/nginx/access.log 和 /var/log/nginx/error.log)
- 用 date +%Y%m%d_%H%M%S 生成带时间戳的归档名,避免并发冲突
- 用 mv 原子移动日志(不使用 cp + truncate,防止写入丢失)
- 执行 nginx -s reopen —— 这会令 worker 进程重新打开 access.log/error.log,继续写入新文件;主进程不重启,服务零中断
- 可选:用 find /var/log/nginx -name "access.log.*" -mtime +30 -delete 清理 30 天前日志
cron 定时任务怎么配置才稳定
建议用系统级 cron(/etc/crontab 或 /etc/cron.d/ 下独立文件),避免用户环境变量缺失导致脚本失败:
- 每天凌晨 0 点执行:0 0 * * * root /usr/local/bin/nginx-log-rotate.sh
- 每小时切一次(适合高流量站):0 * * * * root /usr/local/bin/nginx-log-rotate.sh
- 务必指定运行用户(如 root),确保有权限移动日志和执行 nginx -s reopen
- 加日志记录便于排错:0 0 * * * root /usr/local/bin/nginx-log-rotate.sh >> /var/log/nginx-rotate.log 2>&1
为什么不用 logrotate?它其实更常用
logrotate 是 Linux 标准日志轮转工具,比自写脚本更健壮,且原生支持 Nginx 场景:
- 配置文件(如 /etc/logrotate.d/nginx)中设置 create 644 nginx nginx 自动重建日志文件权限
- 用 postrotate /usr/sbin/nginx -s reopen endscript 替代手动 reload,语义清晰
- 自带压缩(compress)、按大小轮转(size 100M)、邮件告警等能力
- logrotate 本身由 cron 每天调用(/etc/cron.daily/logrotate),无需额外配定时任务
验证是否生效的三个动作
脚本或 logrotate 配置后,必须验证闭环是否完整:
- 手动运行一次脚本或 logrotate -f /etc/logrotate.d/nginx,检查是否有新命名日志生成
- 执行 ps aux | grep nginx,确认无异常重启;用 lsof -p $(cat /var/run/nginx.pid) | grep log 查看 worker 进程是否已指向新日志文件
- 持续写入测试:curl 访问站点后,检查新日志文件是否有新增条目,原切割文件是否不再增长











