nginx需借助外部脚本实现按小时日志切割,核心是重命名旧日志、touch新建空文件、发送kill -usr1信号;脚本须加锁防并发、预检磁盘空间、验证写入生效,并支持多域名日志路径自动识别与处理。

Nginx 本身不内置按小时自动切割日志的功能,必须依赖外部脚本或工具协同实现。要应对超大流量突发场景(如 QPS 突增至千级、单小时日志达 GB 级),关键不是“能不能切”,而是“切得准、写得稳、查得快”。核心逻辑是:重命名旧日志 + 通知 Nginx 重建文件描述符 + 防并发与磁盘风险。
按小时切割的核心动作链
每到整点,脚本需完成三步闭环:
- 将当前
/var/log/nginx/access.log重命名为带时间戳的归档文件,例如access.log.20260729-13 - 用
touch /var/log/nginx/access.log创建空文件,确保 Nginx 后续写入不失败(Linux 文件系统靠 inode 不靠路径名) - 向 Nginx 主进程发送
kill -USR1,触发其重新打开所有access_log指令指定的文件
脚本必须包含的容错机制
生产环境不能只跑通命令,要防住真实故障点:
-
加锁防止并发:同一时刻多个 cron 实例或手动触发会导致重命名冲突,用
flock -n /tmp/nginx-cut.lock包裹主逻辑 -
磁盘空间预检:执行前检查
/var/log分区使用率,df /var/log | awk 'NR==2 {print $5}' | sed 's/%//'> 90 就跳过并记录告警 -
验证写入生效:切割后立即
ls -lt /var/log/nginx/access*确认新access.log修改时间是否为当前小时;再tail -1 /var/log/nginx/access.log看是否有新请求写入
定时任务配置(精确到小时)
在 crontab -e 中添加:
0 * * * * /usr/local/bin/nginx-cut-hourly.sh
注意:该时间表示“每小时第 0 分钟”,即整点触发。不要用 * * * * * 或 */60——cron 不支持秒级且 */60 实际等效于 0。
脚本路径建议放在 /usr/local/bin/ 并赋予执行权限:chmod +x /usr/local/bin/nginx-cut-hourly.sh
多域名站点的扩展处理
若 Nginx 配置了多个 server 块且各自指定了 access_log /var/log/nginx/site-a.com.log 和 site-b.com.log:
- 脚本需先提取所有日志路径:
nginx -T 2>/dev/null | grep 'access_log' | awk '{print $2}' | sort -u - 对每个路径单独执行重命名(如
mv site-a.com.log site-a.com.log.20260729-13)、touch 原路径、最后统一发一次kill -USR1 - 文件名可强化标识:
site-a.com.access.log.20260729-13,便于后续按域名+时间快速筛选











