CentOS 中 Nginx 日志切割最佳实践
一 推荐方案与标准配置
- 使用系统自带的 logrotate 管理 Nginx 日志,稳定、可审计、与系统定时任务集成。将配置放入 /etc/logrotate.d/nginx,针对常见路径 /var/log/nginx/*.log 的标准配置如下:
/var/log/nginx/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 0640 nginx nginx
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
endscript
}
- 关键参数说明:
- daily / weekly / monthly:切割频率;业务高峰建议按天,超大日志可按小时(见下文进阶)。
- rotate N:保留最近 N 个归档,结合频率即保留天数/周数/月数。
- compress / delaycompress:压缩旧日志,delaycompress 便于最近一份便于 tail。
- missingok / notifempty:日志缺失或为空时不报错/不切割。
- create 0640 nginx nginx:切割后重建日志文件并设置权限与属主,确保 Nginx worker 可写。
- postrotate … endscript:向 Nginx 发送 USR1 信号,通知其重新打开日志文件,避免日志句柄指向旧文件。
- sharedscripts:多个日志共享一次 postrotate 脚本,避免重复执行。
二 验证与运行
sudo logrotate -d /etc/logrotate.d/nginx # 调试模式,不真正执行
sudo logrotate -vf /etc/logrotate.d/nginx # 强制执行一次并输出详情
- 定时执行机制:
- logrotate 默认由 /etc/cron.daily/logrotate 每日触发,系统通常在每日 03:05–03:50 间随机延迟执行(由 /etc/crontab 或 /etc/anacrontab 控制)。
- 自定义切割时间(可选):
- 推荐做法:在 /etc/logrotate.d/ 之外放置自定义配置,并用 crontab 精确控制时间,避免与系统默认任务重复执行。
# 每天 23:59 执行自定义配置
sudo crontab -e
59 23 * * * /usr/sbin/logrotate -f /etc/logrotate_mytime/nginx >>/var/log/logrotate-nginx.log 2>&1
- 运行记录与排查:
- 查看状态:cat /var/lib/logrotate/logrotate.status
- 查看定时任务日志:cat /var/log/cron
- 强制立即切割用于验证:/usr/sbin/logrotate -f /etc/logrotate.d/nginx。
三 进阶场景与配置要点
/var/log/nginx/*.log {
daily
size 100M
rotate 30
compress
delaycompress
missingok
notifempty
create 0640 nginx nginx
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
endscript
}
/var/log/nginx/*.log {
daily
rotate 30
dateext
dateyesterday
dateformat -%Y-%m-%d
compress
delaycompress
missingok
notifempty
create 0640 nginx nginx
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
endscript
}
- 按小时切割(高频场景):
- 在配置中设置 hourly,并将 /etc/cron.daily/logrotate 复制到 /etc/cron.hourly/,使系统每小时调用一次 logrotate;或在自定义目录配置并通过 crontab 每小时执行。
- create 与 copytruncate 取舍:
- create:重命名原文件并重建新文件,信号通知(USR1)后无缝衔接,推荐默认使用。
- copytruncate:先拷贝再清空原文件,存在极小窗口期可能丢日志,且大文件拷贝开销高,仅在无法发信号或特殊场景使用。
四 常见问题与排查清单
- 权限与属主:确保 /var/log/nginx 及归档目录对 nginx 用户可写;使用 create 0640 nginx nginx 保证新建日志权限正确。
- PID 路径:不同安装方式 PID 路径可能不同,常见有 /var/run/nginx.pid、/usr/local/nginx/logs/nginx.pid,请在 postrotate 中按实际路径读取。
- SELinux 拦截:
- 现象:切割失败或归档后无法写入新日志。
- 处理:不建议直接关闭 SELinux;使用 semanage 为日志目录设置正确的类型,例如:
sudo semanage fcontext -a -t var_log_t "/usr/local/nginx/logs(/.*)?"
sudo restorecon -Rv /usr/local/nginx/logs
- 临时方案(不推荐生产):setenforce 0。
- 重复执行与冲突:避免同一配置被系统 cron.daily 与自定义 crontab 同时触发;自定义时建议将配置放在 /etc/logrotate.d/ 之外并单独定时。
- 验证与观测:
- 观察归档文件是否生成且命名符合预期(如 access.log-2025-12-07.gz 或 access-2025-12-07.log.gz)。
- 查看 /var/lib/logrotate/logrotate.status 与 /var/log/cron,确认执行时间与结果。