logrotate日志轮转:磁盘满的病根在日常,一次配置管三年

来源:互联网 时间:2026-09-12

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,定位大文件与日志轮转》的定位流程管“真满了怎么救”。三层下来,磁盘满这个站长最常见的病,从预防到兜底就都齐了。

相关阅读:日志轮转是运营例行里最省心的一项,配一次管三年。《从零建站第一步:技术栈选型总纲,别一上来就纠结框架》的运营组篇目按省心程度排,总纲照着排期即可。

相关文章

A5创业网 版权所有

返回顶部