温馨提示×

nginx日志切割与归档策略

小樊
48
2025-10-02 22:55:34
栏目: 编程语言

Nginx日志切割与归档策略
Nginx默认不会自动切割日志文件,长期运行会导致日志文件过大,占用大量磁盘空间,影响系统性能和日志可管理性。因此,需要通过合理的切割与归档策略,将日志文件分割成小文件并妥善保存,以解决上述问题。

一、常用切割工具:logrotate(系统自带,推荐使用)

logrotate是Linux系统自带的日志管理工具,支持按时间(天、周、月、年)或大小切割日志,自动压缩、删除过期日志,并能通知Nginx重新打开日志文件(避免服务中断)。其核心优势是与系统集成度高,维护简单。

1. 配置文件路径

  • 主配置文件:/etc/logrotate.conf(全局默认参数)
  • 自定义配置:/etc/logrotate.d/nginx(推荐将Nginx日志配置放在此目录,会被主配置自动加载)。

2. 通用配置项说明

以下是Nginx日志切割的常用配置参数,需根据实际场景调整:

/usr/local/nginx/logs/*.log { # 监控的日志路径(可包含access.log、error.log等) daily # 切割频率:每天(可选:weekly周、monthly月、yearly年) missingok # 日志文件不存在时不报错 rotate 30 # 保留最近30个归档日志(超过则删除) compress # 使用gzip压缩旧日志(节省空间) delaycompress # 延迟压缩:当前切割的日志不立即压缩,下一次切割时再压缩(避免重复压缩) notifempty # 日志为空时不切割 create 0640 nginx nginx # 切割后创建新日志文件,权限640,属主nginx(需与Nginx运行用户一致) sharedscripts # 所有日志处理完成后执行一次postrotate脚本(避免多次重启Nginx) postrotate # 切割后执行的命令 if [ -f /usr/local/nginx/logs/nginx.pid ]; then kill -USR1 `cat /usr/local/nginx/logs/nginx.pid` # 发送USR1信号,通知Nginx重新打开日志文件 fi endscript } 

关键说明

  • postrotate脚本中的kill -USR1是核心命令,用于通知Nginx切换日志文件,不会中断服务;
  • create参数需确保新日志文件的属主和权限与Nginx运行用户一致(通常为nginx),否则Nginx无法写入新日志。

3. 不同场景的配置案例

根据日志量、保留需求和合规性要求,可选择不同的切割策略:

  • 按天轮转(中小型网站常用):适合日均日志量<1GB的场景,保留365天日志。
    /usr/local/nginx/logs/*.log { daily rotate 365 compress delaycompress notifempty create 0640 nginx nginx sharedscripts postrotate kill -USR1 `cat /usr/local/nginx/logs/nginx.pid` endscript } 
  • 按月轮转(大型网站归档):适合日志量巨大(日均>1GB)的场景,保留24个月(2年)日志,每月1号切割。
    /usr/local/nginx/logs/*.log { monthly rotate 24 compress missingok notifempty create 0640 nginx nginx sharedscripts postrotate kill -USR1 `cat /usr/local/nginx/logs/nginx.pid` endscript } 
  • 按大小轮转(突发流量应对):适合直播、秒杀等突发高并发场景,当日志文件超过100MB时立即切割,保留10个归档日志。
    /usr/local/nginx/logs/*.log { size 100M rotate 10 compress missingok notifempty create 0640 nginx nginx sharedscripts postrotate kill -USR1 `cat /usr/local/nginx/logs/nginx.pid` endscript } 

4. 测试与验证

  • 测试配置是否正确:使用logrotate -d /etc/logrotate.d/nginx命令(-d表示debug模式),查看切割流程是否符合预期,无报错则表示配置正确。
  • 强制执行切割:使用logrotate -f /etc/logrotate.d/nginx命令(-f表示强制),立即执行一次切割,验证日志是否按配置分割。
  • 查看切割结果:检查/usr/local/nginx/logs/目录,应生成类似access.log-20250405.gz的压缩文件(按天切割),并确认新日志文件(access.log)已创建。

二、备选方案:自定义脚本 + Crontab(灵活但维护成本高)

若不想使用logrotate,可通过编写Shell脚本实现日志切割,结合Crontab定时执行。

1. 脚本示例(按月归档)

#!/bin/bash LOG_DIR="/usr/local/nginx/logs" # 日志目录 DATE=$(date -d "yesterday" +%Y-%m) # 昨天日期(格式:YYYY-MM) LOG_MONTH_DIR="$LOG_DIR/$DATE" # 归档目录(按月创建) # 创建归档目录(不存在则创建) [ ! -d "$LOG_MONTH_DIR" ] && mkdir -p "$LOG_MONTH_DIR" # 切割access.log和error.log for LOG_FILE in "access.log" "error.log"; do if [ -f "$LOG_DIR/$LOG_FILE" ]; then mv "$LOG_DIR/$LOG_FILE" "$LOG_MONTH_DIR/${LOG_FILE}_$(date -d "yesterday" +%Y%m%d)" # 重命名(加日期后缀) fi done # 通知Nginx重新打开日志文件 kill -USR1 $(cat "$LOG_DIR/nginx.pid") # 清理3个月前的过期日志(可选) find "$LOG_DIR" -name "*.log.*" -mtime +90 -exec rm -f {} \; 

说明

  • 脚本按月创建归档目录(如/usr/local/nginx/logs/2025-04),并将日志文件重命名为access.log-20250405(带日期后缀);
  • 使用find命令清理3个月前的过期日志(可根据需求调整-mtime +90的天数)。

2. 设置Crontab定时任务

将脚本保存为/usr/local/sbin/nginx_log_cut.sh,赋予执行权限:

chmod +x /usr/local/sbin/nginx_log_cut.sh 

编辑Crontab(crontab -e),添加以下内容(每天凌晨0点执行):

0 0 * * * /usr/local/sbin/nginx_log_cut.sh >> /var/log/nginx_log_cut.log 2>&1 

说明

  • 0 0 * * *表示每天0点执行;
  • >> /var/log/nginx_log_cut.log 2>&1将脚本输出追加到/var/log/nginx_log_cut.log,便于排查问题。

三、最佳实践建议

  1. 中小站点:优先使用logrotate的daily + rotate 30 + compress配置,满足日常日志管理需求,无需额外维护。
  2. 大流量站点:结合size参数(如size 100M),防止单个日志文件过大导致磁盘空间耗尽,同时保留dailyweekly切割,平衡日志颗粒度和存储成本。
  3. 合规需求:对于需要长期保留原始日志的场景(如金融、医疗行业),使用monthlyyearly切割,保留5~10年的归档日志,并将日志同步到ELK、Splunk等集中式日志管理系统,便于后续审计和分析。
  4. 监控告警:通过Zabbix、Prometheus等工具监控/usr/local/nginx/logs/目录的大小,当磁盘使用率超过80%时触发告警,及时清理过期日志或扩容磁盘。

通过上述策略,可实现Nginx日志的自动化切割与归档,有效解决日志过大问题,提升系统稳定性和运维效率。

0