日志悄悄把磁盘写满之前:journalctl 与 logrotate 的日常管理
服务器磁盘告警里,日志写满是最常见、也最容易被忽视的一种。服务跑得好好的,日志一天天涨,直到磁盘 100%,数据库写不进去、程序开始报一堆看不懂的错,才回头发现 /var/log 已经几个 G。日志管理不复杂,关键是分清两套体系:systemd 的 journald 管系统和服务日志,传统文本日志靠 logrotate 轮转。两边都设好上限,磁盘就不会被日志偷袭。
一、先定位:到底是谁在涨
动手清理之前先看数。df -h 看分区整体水位;journalctl --disk-usage 看 journald 日志占了多少;再用 du -sh /var/log/* 排个序,找出最大的那几个文件或目录。很多时候结论很直接:不是某个应用疯了,而是所有日志都从来没轮转过,几个月攒下来的总量而已。
还要分清日志的类型:journald 的日志是二进制格式,存在 /var/log/journal/,要用 journalctl 查看和清理;应用自己写的 .log 文本文件是另一套,归 logrotate 管。两套的清理命令不通用,搞混了只清一边,磁盘还是满的。
二、journald:用 vacuum 清理,用配置定上限
journalctl 的 --vacuum 系列就是官方的清理方式:–vacuum-size=500M 表示把归档日志删到总量低于 500M;–vacuum-time=2weeks 表示只保留最近两周;–vacuum-files=5 表示只留最近 5 个归档文件。可以组合使用。
有一个细节很多人会踩:vacuum 只删已经归档(轮转过)的日志文件,正在写入的那个活动文件它不动。如果清理完发现“怎么没释放多少”,先执行一次 journalctl --rotate 把活动文件转成归档,再 vacuum,就能清下去了。
临时清理只是救急,长久之计是在 /etc/systemd/journald.conf 里把上限写死:SystemMaxUse 限制日志总量,SystemKeepFree 保证分区至少留多少空闲,MaxRetentionSec 限制最长保留时间。改完重启 systemd-journald 生效。设好之后 journald 会自己维持水位,不用人再惦记。
三、文本日志:logrotate 负责轮转、压缩和过期删除
logrotate 是专门管文本日志的工具:按天或按大小把旧日志改名归档、压缩、只保留指定份数、再新建空文件继续写。全局配置在 /etc/logrotate.conf,各应用的单独规则放在 /etc/logrotate.d/ 目录下,一个应用一个文件,互不干扰。
给自己的应用写规则时,常用的几项是:daily 或 weekly 决定轮转周期,rotate 后面的数字决定保留几份,compress 让旧日志压缩存放(能省下大半空间),missingok 保证日志文件不存在时不报错,notifempty 避免空文件也轮转。如果应用打开着日志文件不放,轮转后它还往旧文件里写,就要用 copytruncate 模式,或者在 postrotate 里通知应用重新打开日志。
调试规则有个稳妥办法:logrotate -d 加配置文件,先 dry-run 打印它打算做什么,确认无误再用 -f 强制执行一次。直接上手改正式配置又不验证,是把自己日志删错的常见原因。
四、几个要避开的粗暴操作
磁盘满了着急,但有几件事别做。第一,不要直接 rm 正在被进程写入的日志文件——文件删了,进程还握着句柄,空间不会释放,df 看还是满的,要等进程重启才回收;真要立刻腾空间,对文件做 truncate 清空,空间马上回来。第二,不要 rm -rf 整个日志目录,排障时最需要的历史记录就是它,而且有些服务目录没了就不自己重建。第三,清理完一定要回头看 df 确认空间真的回来了,没回来就说明还有已删除但被占用的文件,用 lsof 查持有者再处理。
小结
日志管理的思路就是分工加设限:journald 用 vacuum 救急、用 journald.conf 定总量上限;文本日志交给 logrotate 定时轮转、压缩、过期删除。平时花十分钟把上限配好,比磁盘写满那天凌晨爬起来救火要划算得多。
(本文为个人运维实践记录。)
- 点赞
- 收藏
- 关注作者
评论(0)