很多使用Nginx部署网站的朋友都有类似经历:刚上线时access.log只有几十K,等过上半年再看,日志文件已经涨到了好几G。日志无限增长不仅白白占用磁盘空间,还会让后续的日志分析、故障排查变得又慢又难。要解决这个问题,核心思路就八个字:定期切割、定时清理。

为什么Nginx日志会越涨越大
只要网站有访问,Nginx就会在access.log里按行记录每一次请求,包括访问时间、客户端IP、请求路径、状态码、响应字节数等。图片站、下载站或接口服务一天的请求量可能高达数十万次,日志自然飞速膨胀。而error.log记录的是错误与告警信息,平时增长不快,但一旦程序异常,也可能在短时间内塞满磁盘。
方案一:使用logrotate自动切割(推荐)
logrotate是Linux系统自带的日志轮转工具,配置好后由cron定时执行,无需自己写脚本。以CentOS为例,先确认logrotate已安装:
rpm -qa | grep logrotate # CentOS
which logrotate # 通用检查
然后在 /etc/logrotate.d/ 下新建配置文件,比如 nginx,内容大致如下。daily表示每天切割一次,rotate 30表示保留最近30份,compress表示对旧日志进行压缩:
/var/log/nginx/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}
注意配置里的 postrotate 部分:切割后需要通过 kill -USR1 向Nginx发送重开日志文件的信号,让新的日志写入新文件。不要用 kill -HUP 强制重载,那样可能瞬间中断正在处理的连接。配置完成后可以用下面的命令手动测试一次:
logrotate -d /etc/logrotate.d/nginx # 调试模式,只演示不执行
logrotate -f /etc/logrotate.d/nginx # 强制执行一次
方案二:crontab配合shell脚本自定义清理
如果对切割时机、保留周期有特殊要求,也可以自己写一个简单的清理脚本,比如保留最近7天的日志,删除更早的压缩文件:
#!/bin/bash
# /usr/local/bin/nginx-log-clean.sh
LOG_DIR=/var/log/nginx
find $LOG_DIR -name "*.log.*" -type f -mtime +7 -delete
find $LOG_DIR -name "*.gz" -type f -mtime +30 -delete
脚本保存后添加执行权限,并加入crontab,每天凌晨4点执行一次(此时访问量低,对业务影响最小):
chmod +x /usr/local/bin/nginx-log-clean.sh
crontab -e
# 添加下面一行
0 4 * * * /usr/local/bin/nginx-log-clean.sh >/dev/null 2>&1
清理前后的注意事项
- 不要在Nginx运行期间直接 rm 正在写入的日志文件,否则磁盘空间不会立即释放,Nginx会继续往已删除文件的句柄里写数据;
- 如果要清空当前日志,优先使用 > /var/log/nginx/access.log 这样的方式,而不是删除文件;
- 先确认磁盘占用情况:du -sh /var/log/nginx,再决定保留周期,避免误删后无法追溯历史访问记录;
- 日志切割周期要根据访问量灵活调整,访问量大的站点建议按天甚至按小时切割。
相关问答FAQs
- 问:logrotate默认什么时候执行?答:由系统cron调度,通常在每天凌晨的 logrotate 任务里执行,具体时间因发行版而异。
- 问:切割后访问日志还在写旧文件怎么办?答:检查postrotate是否生效,或手动执行 kill -USR1 $(cat /var/run/nginx.pid) 让Nginx重新打开日志文件。
- 问:除了access.log,还有哪些日志需要清理?答:error.log、慢请求日志以及Nginx的临时缓存目录都值得关注,可一并纳入轮转策略。
最后提醒一句:日志既是排障的重要依据,也是潜在的数据资产,切割清理前一定要明确保留策略。把logrotate配置好,再配合磁盘告警监控,Nginx日志就能保持在一个健康的大小,既不影响业务,也不会拖累排障效率。
【版权声明】:本站所有内容均来自网络,若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!