Linux 日志文件无限增长的治理方案

13次阅读

logrotate配置不生效主因是定时任务未触发,需检查配置路径、include语句及cron或systemd定时器;按大小切割用size参数并配copytruncate;journald爆满应设SystemMaxUse和MaxRetentionSec;应用直写日志须用轮转库或prerotate通知重开。

Linux 日志文件无限增长的治理方案

logrotate 配置不生效的典型表现

日志文件持续膨胀却没被切割,logrotate 手动运行又正常——这基本说明配置没被定时任务触发。常见原因有:配置文件没放进 /etc/logrotate.d/ 目录;主配置 /etc/logrotate.conf 里漏了 include /etc/logrotate.d;或者 cron 里的 logrotate 任务被注释或删掉了。

检查方法:systemctl list-timers | grep logrotate 看是否注册了定时器(新版 systemd 默认启用);ls -l /etc/logrotate.d/ 确认你的规则文件存在且权限为 644;grep -r "include" /etc/logrotate.conf 确保包含路径正确。

按大小而非时间切割日志的关键参数

默认 logrotate 按天轮转,但服务日志写入不均时,一天可能只几 KB,也可能突增几个 GB。用 size 替代 daily 更可靠,比如限制单个日志不超过 100MB:

/var/log/myapp/*.log {     size 100M     rotate 7     compress     missingok     notifempty     copytruncate }

copytruncate 是关键:先复制再清空原文件,避免服务因文件句柄失效而报错;notifempty 防止空文件也被轮转;missingok 避免日志路径临时不存在时报错中断。

注意:sizedaily/weekly 不能共存,否则以时间策略为准,大小限制失效。

systemd-journald 日志爆满的快速压制

如果 /var/log/journal/ 占用几十 GB,说明 journald 没设上限。直接改 /etc/systemd/journald.conf

  • 取消注释并设 SystemMaxUse=512M(建议 256–1024M 区间)
  • MaxRetentionSec=2week 控制保留时长
  • 执行 sudo systemctl restart systemd-journald 生效

立即释放空间可手动清理:journalctl --vacuum-size=512M--vacuum-time=2d。别用 rm -rf /var/log/journal/*,journald 不认,下次启动仍会加载旧索引。

应用自身日志未走 syslog 的绕过风险

很多 Go/python 服务直接往 /var/log/app/app.log 写,绕过 syslog 和 logrotate 管理。这时仅靠系统级配置无效。

必须在应用层配合:

  • 用支持轮转的库:Go 推荐 lumberjack,Python 用 RotatingFileHandler
  • 禁用应用内“无限追加”逻辑,明确设 MaxSizeMaxBackups
  • 若无法改代码,可用 logrotateprerotate 脚本发信号通知进程 reopen 日志文件(需应用支持 SIGHUP)

最危险的是:误以为 logrotate 配好了就万事大吉,结果应用自己开个 fd 往老文件写,copytruncate 也救不了——文件虽被清空,但 inode 没变,应用还在往同一位置写。

text=ZqhQzanResources