Nginx日志自动化切割关键在精准与实效:按小时切需重命名+kill -USR1,文件名含时间戳;按域名切需遍历各access_log路径分别处理;须加锁、磁盘检查、定期清理并验证新旧文件写入状态。

用脚本自动化切割 Nginx 日志,关键不在“能不能”,而在于“切得准不准、管不管用”。按小时或按域名切,本质是让日志文件名带时间戳或域名标识,并确保 Nginx 在切换后写入新文件——这需要脚本完成两件事:重命名旧日志 + 通知 Nginx 重新打开日志文件(kill -USR1)。
按小时切割:时间驱动,结构清晰
适合需要高频分析、排查短时异常的场景。核心是生成形如 access.log.20240520-14 的文件名。
- 用
date +\%Y\%m\%d-\%H获取当前小时标识,避免跨小时重复或遗漏 - 先移动原日志(如
mv /var/log/nginx/access.log /var/log/nginx/access.log.$(date +\%Y\%m\%d-\%H)),再用touch创建空日志防止写入失败 - 执行
kill -USR1 $(cat /var/run/nginx.pid)让 Nginx 重新打开access.log,确保后续请求不丢失 - 建议配合 cron 每小时执行一次:
0 * * * * /path/to/cut-by-hour.sh
按域名切割:一个站点一份日志,隔离性强
适用于多站点共用一台 Nginx 的情况,每个 server 块已配置独立 access_log /var/log/nginx/example.com.log。
- 脚本遍历所有域名日志路径(可从
nginx -T | grep access_log提取,或维护白名单文件) - 对每个日志文件单独处理:重命名加时间戳(如
example.com.log.20240520-14),再touch对应原始文件名 - 统一发一次
kill -USR1即可,Nginx 会按各access_log指令分别打开对应文件 - 若需按小时+域名双维度切割,文件名可组合为
example.com.access.log.20240520-14
安全与容错:别让脚本变成事故源头
生产环境脚本必须考虑异常情况,否则可能造成日志丢失或 Nginx 写入失败。
- 加锁机制:用
flock防止同一时间多个实例并发执行(flock -n /tmp/nginx-cut.lock -c "your commands") - 检查磁盘空间:切割前用
df /var/log | awk 'NR==2 {print $5}' | sed 's/%//'判断是否超 90%,超限则跳过并告警 - 保留最近 7 天或 24 小时的日志:用
find /var/log/nginx -name "*.log.*" -mtime +7 -delete定期清理 - 记录操作日志:每次切割后
echo "$(date): cut $(ls -t /var/log/nginx/*.log.* | head -1)" >> /var/log/nginx/cut.log
验证是否生效:别只看脚本有没有报错
真正有效 = 文件名符合预期 + Nginx 写入新文件 + 旧文件不再增长。
- 执行脚本后,运行
ls -lt /var/log/nginx/ | head -5确认新文件已生成且时间戳正确 - 查 Nginx 当前写入的 inode:
lsof -p $(cat /var/run/nginx.pid) | grep log | grep access,对比文件名和 inode 号是否匹配新文件 - 手动触发一次请求(
curl -I http://your-domain.com),再看新日志文件 size 是否增加 - 观察
tail -f /var/log/nginx/access.log是否继续输出——正常情况下它应为空,新日志在access.log.20240520-14中











