Linux 日志轮转 logrotate:别让日志文件吃满磁盘的实用配置
很多服务器第一次磁盘告警,根因不是业务数据暴涨,而是日志没有轮转。/var/log 下的 messages、secure、nginx 的 access.log 一天能长几百兆,几个月下来就能把根分区吃满,服务随之写日志失败,甚至无法启动。logrotate 是系统自带的日志管家,理解它,比定期手动删日志可靠得多。
一、logrotate 是怎么工作的
logrotate 本身不常驻后台,它靠 cron 每天触发一次(/etc/cron.daily/logrotate),按 /etc/logrotate.conf 和 /etc/logrotate.d/ 下的规则逐个处理日志:重命名当前文件、压缩旧文件、按数量或时间删除最旧的一份,最后通知应用重新打开日志文件。应用不停写日志时,关键一步是让它放开旧文件句柄,常用两种办法:对 syslog、nginx 这类支持信号的服务,在 postrotate 里发信号;对不支持信号的应用用 copytruncate,先复制再截断原文件,文件不移动、句柄不断,但截断瞬间可能丢少量日志。
二、一份可直接用的配置
/etc/logrotate.d/myapp 示例:
/var/log/myapp/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 appuser appgroup
sharedscripts
postrotate
/bin/kill -USR1 $(cat /var/run/myapp.pid) 2>/dev/null || true
endscript
}
daily 表示每天轮转一次;rotate 14 保留最近 14 份;compress 用 gzip 压缩,delaycompress 让昨天的日志晚一天再压,方便当天排错时直接 grep;missingok 是日志还没生成也不报错;notifempty 是空文件不轮转;create 指定新文件的权限和属主,避免应用因权限不足写不进新日志。
三、排错时先看这三处
第一,规则没生效:先跑 logrotate -d /etc/logrotate.d/myapp 看模拟输出,-d 只演练不改动,常见原因是配置文件里混了 Tab、路径通配写错,或者两个规则同时匹配同一个文件,logrotate 会直接跳过并报错。
第二,轮转后应用还在往旧文件写:用 lsof 查进程打开的文件句柄,对照看旧文件是否仍在增长,若是,说明 postrotate 的信号没发对,或应用根本不支持信号,改用 copytruncate。
第三,磁盘还是满:rotate 数量乘以单文件大小就是保留上限,先估算一下总量;再用 du -sh /var/log/* 排序,看是不是某个没进规则的日志在偷偷长大,漏网的日志要补一条规则。
四、容易踩的坑
不要对正在被多个进程写、且没有信号机制的日志用默认的 rename 方式;不要把 rotate 设得过大,压缩包同样占空间;生产环境改规则后先用 -d 演练一次,再观察第二天实际轮转结果。把日志轮转纳入巡检清单,和磁盘使用率告警一起看,磁盘告警才不会总在半夜出现。
- 点赞
- 收藏
- 关注作者
评论(0)