journalctl 占了几个 G:systemd-journald 的清理、限额与转发配置
先看清日志到底占了多少
/var/log/journal 下是一堆二进制文件,不能用 du 之外的方式直接读。journalctl --disk-usage 给出的数字才是 journald 自己统计的占用:
journalctl --disk-usage
# Archived and active journals take up 3.6G in the file system.
再按时间和来源看看分布,确认是不是某个服务在刷日志:
journalctl --since "1 day ago" --no-pager | wc -l
journalctl --since today -o json --no-pager | jq -r '.SYSLOG_IDENTIFIER' | sort | uniq -c | sort -rn | head
如果某一行是几十万条,问题不在 journald 本身,而在那个服务。先修源头,再谈清理。
为什么不建议直接删文件
journald 通过文件描述符持有当前的活动日志文件。直接 rm /var/log/journal/**/*.journal 之后,磁盘空间不会释放,因为进程还开着这些 fd;更糟的是 journald 可能继续往已删除的文件里写,直到重启。正确做法是让 journald 自己回收:
journalctl --vacuum-time=7d
journalctl --vacuum-size=500M
两条命令分别按时间和总体积清理归档文件,正在写的活动文件不会被删。清理后立刻用 --disk-usage 复核。
让限额长期生效
手动 vacuum 只是临时救火,配置写进 /etc/systemd/journald.conf 才会一直生效:
[Journal]
Storage=persistent
SystemMaxUse=500M
SystemKeepFree=1G
SystemMaxFileSize=50M
MaxRetentionSec=2week
MaxFileSec=1day
几个参数的分工要分清:SystemMaxUse 是 journal 目录的总上限,SystemKeepFree 是给磁盘保留的空闲空间,两者取更严格的那个;MaxRetentionSec 按时间淘汰;MaxFileSec 控制单个文件切换周期,太大不利于按时间清理。
改完执行 systemctl restart systemd-journald。注意 Storage=persistent 会在 /var/log/journal 建持久目录,volatile 则只在内存里,重启就没了。
日志转发:什么时候需要 rsyslog
journald 默认只写本地。如果已有集中式日志平台,可以开 ForwardToSyslog=yes 交给 rsyslog 再发远端,或者直接用 systemd-journal-upload:
[Journal]
ForwardToSyslog=yes
ForwardToWall=no
ForwardToWall 建议关掉,否则每条日志都可能弹到所有登录终端,排查时非常吵。
容器场景要额外注意:Docker 的 json-file 日志驱动会绕过 journald,单独把 /var/lib/docker/containers 撑大。这时要配置 log-opts 的 max-size 和 max-file,而不是只调 journald。
排查清单
按顺序做一遍,基本能覆盖绝大多数情况:先用 journalctl --disk-usage 确认占用,再按来源统计找出刷屏服务,然后 --vacuum-time 应急清理,接着把 SystemMaxUse 和保留时间写进配置,最后确认是否需要转发以及容器日志是否另有去处。
一个容易被忽略的细节:磁盘满的时候 journald 自己也会写不进去,journalctl 可能只显示到某个时间点就断了。这时候不要以为日志被清了,先看 df -h 和 dmesg,把空间腾出来再继续查。
- 点赞
- 收藏
- 关注作者
评论(0)