7.6.2 日志切割与保留策略

日志切割与保留策略用于控制 Nginx 日志大小、降低磁盘占用并满足合规要求。常见触发方式为按时间/按大小切割,切割后通过信号让 Nginx 重新打开日志文件,结合压缩与保留周期完成生命周期管理。

原理草图(切割与重开日志)

flowchart TD
    A[业务请求] --> B[Nginx 写 access/error.log]
    B --> C{触发切割\n(logrotate/定时/大小)}
    C --> D[日志重命名/压缩]
    D --> E[postrotate 发送 USR1]
    E --> F[Nginx 重新打开日志]
    F --> B

工具与方式选择
- logrotate:系统级通用方案,支持按时间/大小切割、保留、压缩与后置命令。
- Nginx 信号切割USR1 重新打开日志文件,适合手动或脚本触发。
- 容器场景:优先 stdout + 日志采集(如 Fluent Bit/Logstash),避免容器内切割。


安装与启用(以 logrotate 为例)#

安装

# Debian/Ubuntu
apt-get update && apt-get install -y logrotate

# RHEL/CentOS
yum install -y logrotate

验证版本

logrotate --version

预期:输出 logrotate 版本号。


完整配置示例(可直接使用)#

文件:/etc/logrotate.d/nginx

/var/log/nginx/*.log {
    daily                 # 按天切割
    size 200M             # 达到 200M 也触发切割(与 daily 并存)
    rotate 14             # 保留 14 份
    compress              # 压缩旧日志
    delaycompress         # 延迟压缩最新的旧日志,便于短期检索
    missingok             # 日志不存在不报错
    notifempty            # 空文件不切
    create 0640 nginx adm # 新文件权限与属主
    sharedscripts
    postrotate
        # 关键:通知 Nginx 重新打开日志文件
        [ -s /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
    endscript
}

手动执行测试(不实际切割)

logrotate -d /etc/logrotate.d/nginx

预期:输出模拟切割动作,不产生新文件。

强制切割并观察效果

logrotate -f /etc/logrotate.d/nginx
ls -lh /var/log/nginx/

预期:出现 access.log.1(或 .1.gz),新 access.log 文件创建。


Nginx 信号切割(不依赖 logrotate)#

手动触发

kill -USR1 $(cat /var/run/nginx.pid)

验证日志句柄已重开

ls -l /proc/$(cat /var/run/nginx.pid)/fd | grep nginx | head

预期:出现指向新日志文件的 fd。


保留与压缩策略建议#

  • 保留周期:一般 7–30 天;合规场景 90–180 天。
  • 压缩格式:gzip 速度与压缩比均衡;可保留最近 1–3 天不压缩以便快速检索。
  • 磁盘阈值:配合监控设置告警,避免磁盘写满导致服务异常。

排错指南(常见问题与修复)#

1)切割后仍写入旧文件(日志不释放)
原因:未发送 USR1 或 PID 文件错误。
处理:

cat /var/run/nginx.pid
kill -USR1 $(cat /var/run/nginx.pid)

2)切割后权限错误,Nginx 无法写入
原因:create 权限或属主错误。
处理:确认 create 0640 nginx adm 与实际 Nginx 运行用户一致。

3)日志未切割
原因:logrotate 未被执行或条件未满足。
处理:

grep logrotate /var/log/syslog  # Debian/Ubuntu
grep logrotate /var/log/cron     # RHEL/CentOS
logrotate -d /etc/logrotate.d/nginx

练习(动手验证)#

  1. size 改为 1M,用压力测试生成日志:
ab -n 5000 -c 50 http://127.0.0.1/
  1. 强制切割并观察新旧文件变化:
logrotate -f /etc/logrotate.d/nginx
ls -lh /var/log/nginx/
  1. 修改 rotate 5,验证只保留 5 个历史文件。

多实例与目录规划建议#

  • 按域名/业务划分目录,如 /var/log/nginx/site1/,便于切割与权限隔离。
  • 生产与测试分离,防止误删或误切割。
  • 日志写入独立磁盘可降低 IO 对主业务的影响。