用crontab在午夜自动触发nginx日志切割,需编写含日期生成、日志重命名、kill -usr1通知及旧日志清理的脚本,并以root权限配置0 0 *定时任务执行。

用 crontab 在午夜自动触发 Nginx 日志切割,核心是写好切割脚本 + 设置定时任务。关键在于确保日志重命名、信号通知(kill -USR1)和旧日志归档三步可靠执行,避免丢失或重复写入。
准备日志切割脚本(推荐放 /opt/scripts/nginx_log_rotate.sh)
脚本需具备权限可执行,并处理日期格式、目录存在性、Nginx 主进程 ID 获取等细节:
- 用
date -d "yesterday" +%Y%m%d生成昨日日期,避免跨月/年误差 - 先
mv当前 access.log 和 error.log 为带日期的归档名(如access.log-20240520) - 再
kill -USR1 $(cat /usr/local/nginx/logs/nginx.pid)通知 Nginx 重新打开日志文件(前提是已配置pid文件路径) - 最后可选:用
find /usr/local/nginx/logs -name "access.log-*" -mtime +30 -delete清理 30 天前日志
给脚本添加执行权限并测试运行
确保脚本不报错且能实际完成切割:
chmod +x /opt/scripts/nginx_log_rotate.sh- 手动执行一次:
/opt/scripts/nginx_log_rotate.sh,检查 logs 目录是否生成新命名日志、原日志是否已归档、Nginx 是否仍在写入access.log(而非旧文件) - 确认
ps aux | grep nginx显示 master 进程在运行,且cat /usr/local/nginx/logs/nginx.pid能读出有效 PID
配置 crontab 在每日 00:00 执行
以 root 用户编辑定时任务(Nginx 通常需 root 权限操作日志和发送信号):
crontab -e- 添加一行:
0 0 * * * /opt/scripts/nginx_log_rotate.sh >/dev/null 2>&1 - 注意:不要用普通用户 crontab,否则可能因权限不足无法 kill 或重命名日志;
/dev/null 2>&1屏蔽输出,避免邮件堆积
验证与排错要点
第二天检查是否生效,常见问题有:
- 日志没切割 → 检查 cron 是否运行(
systemctl status cron)、脚本路径是否写错、nginx.pid路径是否匹配 nginx 配置中的pid指令 - 切割后新日志为空 → 很可能是
kill -USR1失败,确认 Nginx 是 master-worker 模式,且未被 systemd 的 private PID namespace 隔离(CentOS 8+/RHEL 8+ 可能需在 service 文件中加PrivatePID=no) - 出现两个进程同时写一个文件 → 脚本里漏了
sleep 1或未等 USR1 完全生效就继续操作(一般不需要 sleep,但确保 mv 在 kill 前完成)











