linux下nginx日志按天轮转推荐logrotate+usr1方案:配置daily、dateext、dateyesterday等参数,配合sharedscripts和postrotate中kill -usr1;按小时轮转不推荐,需cron脚本手动mv并发信号。

Linux 下 Nginx 本身不支持原生按天或按小时自动分割日志,必须借助外部机制。最稳妥、生产环境广泛采用的方式是 logrotate + USR1 信号,它不中断服务、不丢日志、可精确控制归档语义。按小时切分虽可行,但需谨慎评估必要性——多数场景按天已足够,且 logrotate 原生不直接支持“每小时”,需配合 cron 绕行实现。
按天归档:标准配置(推荐)
这是最常用、最稳定的方案,确保每天生成一个带昨日日期的归档文件(如 access.log-2026-09-23),并让 Nginx 立即写入新文件:
- 配置文件必须放在
/etc/logrotate.d/nginx(不能加.conf后缀,权限644,属主root:root) - 核心参数缺一不可:
daily(触发频率)、dateext(启用日期后缀)、dateyesterday(让文件名显示“昨天”而非“今天”,语义准确)、create 0644 nginx nginx(轮转后新建日志,权限和属主按你实际运行 Nginx 的用户调整) -
sharedscripts必须启用,避免对access.log和error.log分别发两次 USR1 -
postrotate中必须用kill -USR1安全通知 Nginx 重开日志句柄,例如:if [ -f /var/run/nginx.pid ]; then kill -USR1 $(cat /var/run/nginx.pid); fi - 建议加上
missingok(日志不存在不报错)、notifempty(空文件不轮转),防止 cron 执行中断
按小时归档:可行但不推荐常规使用
logrotate 本身没有 hourly 选项,强行每小时轮转会显著增加系统负担,且易因高频信号导致不稳定。若确有需要(如调试高并发瞬时流量),可采用以下折中方式:
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
- 不修改 logrotate 配置,改用
cron每小时执行一次脚本 - 脚本内容示例:
#!/bin/bash<br>LOG_DIR="/var/log/nginx"<br>TIMESTAMP=$(date -d "1 hour ago" +\%Y-\%m-\%d_\%H)<br>mv "$LOG_DIR/access.log" "$LOG_DIR/access_$TIMESTAMP.log"<br>kill -USR1 $(cat /var/run/nginx.pid)
- 注意:需确保
access.log当前可被 mv,且新文件名不冲突;date -d "1 hour ago"可避免因 cron 延迟导致时间错位 - 该方式绕过 logrotate 的压缩、保留策略,需自行管理旧文件生命周期(如用
find删除 72 小时前的文件)
验证与上线前必做步骤
配置写完绝不能直接扔进生产环境,必须手动验证:
- 先用
logrotate -d /etc/logrotate.d/nginx查看模拟执行流程,确认路径、PID 文件读取、信号发送逻辑无误 - 再用
logrotate -vf /etc/logrotate.d/nginx强制执行一次,检查:
– 归档文件名是否含昨日日期(如access.log-2026-09-23)
–access.log是否变为空文件且可写
–ps aux | grep nginx确认 worker 进程未重启(仍是原 PID) - 观察几分钟,确认新访问请求仍正常写入
access.log,无丢失、无双写
常见踩坑点提醒
这些细节错一处,日志就可能堆积或中断:
- 配置文件放错位置(如
/root/nginx或/etc/logrotate.d/nginx.conf)→ cron 完全忽略 - 只写
daily不配dateext→ 生成access.log.1编号式文件,无法按日期定位 - 漏掉
sharedscripts→ 多个日志文件触发多次 USR1,Nginx 可能异常 - 用
nginx -s reload或systemctl reload nginx替代kill -USR1→ 触发 worker 平滑重启,有丢请求风险,且非所有环境都支持 - 未确认 Nginx 实际 PID 文件路径(可能是
/usr/local/nginx/logs/nginx.pid)→kill命令失败,日志继续写入旧文件










