日志暴涨需先溯源再处置:三步定位(查增长最快文件、看实时写入进程、读最新错误模式),按服务类型选切割策略(信号重载 / copytruncate / 行数阈值),分三层限流(应用层开关、中间件拦截、内核级防护),并落实验证与兜底(状态检查、加锁、自动清理、ERROR 日志保底)。

日志暴涨往往不是孤立现象,而是系统异常、配置错误或业务突增的外在表现。单纯切日志只能缓解磁盘压力,不解决根源反而可能掩盖真实问题。排查要“先看因、再动手”,切割和限流是控制手段,不是替代诊断的捷径。
快速定位暴涨源头
别急着写脚本或改 logrotate,先用三步锁定元凶:
- 查增长最快的文件 :运行
find /var/log -type f -mmin -60 -ls | sort -k7nr | head -10,找出最近一小时内体积变化最大的日志 - 看实时写入进程 :执行
lsof +D /var/log 2>/dev/null | awk '$5 ~ /REG/ && $9 ~ /.log$/ {print $2,$9}' | sort | uniq -c | sort -nr,列出正在往日志写入的 PID 和文件名 - 读最新错误模式 :对疑似日志用
tail -n 200 /path/to/log | grep -E "(error|ERROR|Exception|panic|fail)" | head -10,高频重复报错大概率就是诱因(比如数据库连接池耗尽导致每秒重试打满日志)
按场景选切割策略
没有万能方案,匹配实际约束才能稳住局面:
- 服务支持信号重载(Nginx、rsyslog 等):优先用 logrotate 配置
postrotate kill -USR1 $(cat /var/run/xxx.pid),安全无丢失 - Java 类服务(Tomcat、Spring Boot)无法重载日志句柄 :必须启用
copytruncate,但要接受极小概率的几行日志丢失风险 - 内存紧张时被动触发 :用 Shell 脚本监控
free | awk '/Mem:/ {printf"%.0f", $3/$2*100}',超 85% 即切关键日志,避免 OOM 杀进程 - 访问量驱动型日志(如 access.log):不依赖时间,改用行数阈值,配合
wc -l统计 + 临时计数文件,每 50 万行切一次
限流不是堵死,而是有策略地降级
日志本身是调试资产,盲目关闭等于自断后路。真正有效的限流分三层:
- 应用层开关 :Spring Boot 可动态设置
logging.level.root=WARN;Log4j2 支持ThresholdFilter按级别过滤,把 DEBUG 日志直接丢弃 - 中间件拦截 :Nginx 中用
log_not_found off;关闭 404 记录,access_log /dev/null;临时停写访问日志(慎用) - 内核级防护 :通过
runit或systemd限制服务日志输出速率,例如SystemMaxUse=100M+MaxLevelStore=warning(适用于 journald 管理的服务)
验证与兜底机制
所有改动必须可观察、可回退:
- 每次 logrotate 后检查
/var/lib/logrotate/status中对应日志的最后轮转时间 - 自定义脚本务必加锁(
flock -n /tmp/logcut.lock -c "your_script"),防止 cron 并发冲突 - 为归档目录设置硬性清理:每天凌晨执行
find /var/log/archive -name "*.log.*" -mtime +3 -delete,防切割失控 - 保留一份“最小可用日志”:即使限流,也要确保 ERROR 级别日志完整,这是故障复盘底线