《Linux 磁盘满排查:df 到 du,定位大文件与日志轮转》讲过磁盘满了怎么一步步定位大文件,那篇解决的是“病发了怎么找”。这篇讲“病根怎么除”——磁盘被日志吃满这个病,绝大多数时候是日志没有轮转:Nginx 访问日志一个月写几十 GB、MySQL 错误日志里同一条堆栈刷了一百万遍、某个调试脚本输出永不停止。logrotate 就是干这个的系统级工具:按周期把旧日志改名归档、压缩、过期删除,并通知服务打开新日志文件。它是几乎所有发行版预装的标配,你缺的只是给它写对规则。
先看看机器上现有的轮转规则长什么样——学习格式最好的方式是读系统自带的范例:
ls /etc/logrotate.d/
# 常见:nginx(或apache2) mysql rsyslog apt
# 看nginx的规则做参考
cat /etc/logrotate.d/nginx
拿一个自建应用举例。假设你的站点每天生成 /var/www/example.com/logs/app.log,业务日志没进任何轮转体系,三个月后必满盘。写一条专属规则:
# /etc/logrotate.d/myapp
/var/www/example.com/logs/*.log {
daily # 每天轮转一次
rotate 14 # 保留最近14份,更早的删除
compress # 归档用gzip压缩
delaycompress # 最近一份先不压(防止还有进程在写)
missingok # 日志不存在不报错
notifempty # 空日志不轮转
dateext # 归档文件名带日期:app.log-20260904.gz
sharedscripts # 多个日志匹配时脚本只执行一次
postrotate
# 通知服务重新打开日志文件(重要!)
[ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
endscript
}
规则里最容易被忽略、也最容易出事故的是 postrotate 那一段。logrotate 轮转的本质是把旧文件改名(mv app.log app.log-20260904),但正在写日志的进程持有的还是旧文件描述符——改名之后它会继续往改名后的文件里写,新文件 app.log 永远是空的,你以为日志断了或者还在写,实际全写进了即将被删的归档。所以轮转后必须给服务发一个“重开日志文件”的信号:Nginx 是 USR1 信号,很多应用支持 USR1 或 SIGHUP,systemd 服务用 systemctl reload。这一步不做,轮转就是白转。
规则写完千万别等到半夜定时任务跑了才知道对不对,logrotate 自带调试手段:
# 干跑:模拟轮转过程,显示会做什么但不真正执行
sudo logrotate --debug /etc/logrotate.d/myapp
# 强制立即轮转一次(验证真实效果)
sudo logrotate -f /etc/logrotate.d/myapp
# 检查结果
ls -la /var/www/example.com/logs/
# 应该看到 app.log(新的空文件)和 app.log-20260904.gz(旧的归档)
# 看每个日志文件上次轮转时间(排查“为什么没轮转”先看它)
cat /var/lib/logrotate/status
验证轮转后服务还在正常写新日志:tail -f /var/www/example.com/logs/app.log,访问几下网站,确认有新内容进来。这一步过了,整套轮转才算闭环。搞坏过一次的人都会记住这个教训:只配了规则、忘了 postrotate,第二天 Nginx 日志“消失”,实际是全写进了旧文件句柄。
几个频率选择的实操建议。Nginx 访问日志用 daily 就够,配合《蜘蛛每天来抓了什么?GoAccess 把死日志变成实时面板》的 GoAccess 做每日统计正合适;MySQL 的慢查询日志按《MySQL起步调优四个参数:buffer_pool给足,慢查询日志先开》的配置开着,轮转规则记得加上,postrotate 里用 mysqladmin flush-logs;系统日志 rsyslog 默认规则已经是每周轮转,不用动。真正需要警惕的是两类漏网之鱼:一类是自己 crontab 里跑的脚本重定向输出(mysqldump.log 这种,没人管它),把输出路径放进 logrotate 规则或者脚本内部自己清;另一类是 Docker 容器日志——logrotate 管不到它,要在 /etc/docker/daemon.json 里配 max-size 和 max-file,装了 Docker 的机器务必检查这项。
收尾给一条组合拳:logrotate 管“日志无限增长”,《netdata一键装监控:每秒级仪表盘配告警,出事先于用户知道》的 netdata 磁盘告警管“万一还是满了提前知道”,《Linux 磁盘满排查:df 到 du,定位大文件与日志轮转》的定位流程管“真满了怎么救”。三层下来,磁盘满这个站长最常见的病,从预防到兜底就都齐了。
相关阅读:日志轮转是运营例行里最省心的一项,配一次管三年。《从零建站第一步:技术栈选型总纲,别一上来就纠结框架》的运营组篇目按省心程度排,总纲照着排期即可。
申请创业报道,分享创业好点子。点击此处,共同探讨创业新机遇!
