核心是建立“轮转+压缩+清理”三位一体的自动化机制并配合源头减量:用logrotate每日轮转、保留30天、自动压缩,通过postrotate reload避免句柄残留;额外用find清理90天前.gz文件;nginx配置中精简日志级别、关闭静态资源访问日志、启用缓冲写入;磁盘满时应清空文件内容而非删除,必要时nginx -s reopen重建日志。

核心是建立“轮转+压缩+清理”三位一体的自动化机制,再配合源头减量。直接清空或删除日志文件不仅治标不治本,还容易导致句柄未释放、磁盘空间不回收,甚至服务异常。
用 logrotate 实现自动轮转与压缩
这是最稳定、系统级支持的方案,无需改动 Nginx 主配置:
- 编辑 /etc/logrotate.d/nginx,写入标准配置(路径按实际调整):
/var/log/nginx/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 0640 www-data adm
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
nginx -s reload > /dev/null 2>&1 || true
fi
endscript
}
- daily:每天切割一次;rotate 30:保留最近30个归档;compress:自动 gzip 压缩旧日志
- postrotate 中的 nginx -s reload 确保 worker 进程切换到新日志文件,避免句柄残留
- 测试配置是否有效:
logrotate -d /etc/logrotate.d/nginx(调试模式)或logrotate -f /etc/logrotate.d/nginx(强制执行一次)
主动清理过期压缩日志
logrotate 压缩后的 .gz 文件仍会持续累积,需额外清理:
- 在 postrotate 后追加清理命令,或单独用
find定期清理: -
find /var/log/nginx -name "*.log.gz" -mtime +90 -delete(删除90天前的压缩包) - 建议将该命令加入 crontab,例如每天凌晨2点执行
从 Nginx 配置源头减少日志体积
轮转解决“怎么存”,优化解决“存什么”,可降低30%~60%写入量:
- 错误日志只记录必要级别:
error_log /var/log/nginx/error.log warn;(避免info或debug) - 静态资源(js/css/img)和健康检查接口禁用访问日志:
location ~* \.(js|css|png|jpg|gif|ico)$ { access_log off; } - 精简
log_format:去掉非排查必需字段,如$http_user_agent、$http_x_forwarded_for - 启用缓冲写入:
access_log /var/log/nginx/access.log main buffer=64k flush=5s;
磁盘已满时的应急处理
别删文件、别重启服务,先定位问题再操作:
- 查爆满分区:
df -h,重点关注 /var/log 和 /var/lib/nginx - 查被删但句柄未释放的日志:
lsof +L1 | grep nginx,若输出含 deleted,说明文件已删但进程还在写 - 安全清空内容:
echo "" > /var/log/nginx/access.log和echo "" > /var/log/nginx/error.log - 若已误删且句柄卡住,执行
nginx -s reopen或kill -USR1 $(cat /var/run/nginx.pid)让 Nginx 重建日志文件











