
你以为日志切割了就没事了。日志文件按日期切开了,但旧的还在。切了不删,等于没切。早晚会把磁盘撑爆。logrotate默认配置只切不删,或者只保留两份,根本不够用。你看了一眼/var/log,几十GB的旧日志躺在那里,没被清理,也没被压缩。工具给你了,你不会用。
今天把logrotate的配置讲透,让你真正掌控日志的生命周期。
先看一个数据
在排查磁盘空间不足的案例中,约40%的情况是由于日志文件未设置合理的轮转策略导致的。默认配置只保留4周日志,但实际上很多服务会产生大量日志,几周就能撑爆磁盘。不是因为工具不行,是因为你没告诉它该怎么做。
logrotate是什么
logrotate是Linux系统自带的日志管理工具,通过cron每天自动运行。它做的事情就是:旧的日志切出来、压缩、删除过期的。你不用手动去翻/var/log目录手动清理。
配置分两层:/etc/logrotate.conf是全局配置文件,定义默认规则;/etc/logrotate.d/目录下是各个服务的独立配置文件,每个服务自己管自己的日志。建议在/etc/logrotate.d/下为每个服务创建独立配置文件,比如nginx、mysql,方便管理和维护。
一个Nginx配置模板
先给一个可以直接用的Nginx日志配置:
text
/var/log/nginx/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 www-data adm
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}
逐行解释:
daily:每天轮转一次。可以换成weekly或monthly。rotate 14:保留14份旧日志。14天后自动删除。根据你的磁盘大小调整这个数字。compress:把旧日志压缩成.gz格式。Nginx日志通常能压到原来的20%。delaycompress:延迟压缩。当前轮转产生的日志先不压缩,等下一次轮转再压缩。这样如果Nginx还在往旧文件里写东西,不会写到压缩文件里。missingok:如果日志文件不存在,不报错,继续执行。notifempty:空文件不轮转。节省磁盘I/O。create 0640 www-data adm:轮转后用指定的权限和属主创建新的空日志文件。sharedscripts:如果通配符匹配了多个日志文件,postrotate脚本只执行一次,而不是每个文件执行一次。postrotate到endscript之间的命令在轮转完成后执行。这里给Nginx发了一个USR1信号,让它重新打开日志文件,停止往旧文件里写日志。
USR1是Nginx接收的信号,通知它重新打开日志文件。如果你用其他服务(如Apache),信号或命令可能不同。
按大小轮转
有的服务日志每天产生量不等。有时一天才几MB,有时一天几十GB。按天轮转就不够灵活。
用size参数:
text
/var/log/myapp/*.log {
size 100M
rotate 10
compress
missingok
notifempty
copytruncate
}
当日志文件超过100MB时触发轮转,而不是等到天结束。适合日志量不稳定的服务。
三个进阶技巧
1. 用dateext给文件名加日期
默认轮转后的文件名是access.log.1、access.log.2。加上dateext后变成access.log-20260616。方便按日期查找:
text
dateext dateformat -%Y%m%d
2. 用olddir把旧日志移走
把旧日志移动到别的目录,保持主目录干净:
text
olddir /var/log/archive
3. 用copytruncate解决“无法发信号”的问题
有些应用不支持重新打开日志文件,或者你没权限发信号。copytruncate先把日志内容复制一份,再把原文件清空。有极小的概率会丢几条日志,但比日志文件无限增长好。
text
copytruncate
手动测试
配完配置文件,别等第二天cron运行。先手动测试:
bash
# 调试模式:模拟运行,不实际改动 logrotate -d /etc/logrotate.d/nginx # 强制轮转:实际执行 logrotate -f /etc/logrotate.d/nginx # 加verbose输出详细信息 logrotate -vf /etc/logrotate.d/nginx
真实案例
一个公司的Nginx日志配置了rotate 30且每天轮转,保留了30天日志。某天流量突增,单日日志从1GB涨到15GB。30天就是450GB。/var分区直接被写爆,网站502。检查时发现rotate参数被注释掉了,变成了默认的0,日志永远不会删除。
把rotate改回14,加了一行size 1G按大小触发轮转,每天定时运行,问题解决。
最后一句
logrotate的配置不难,难的是你一直用默认配置。每天花5分钟把/etc/logrotate.d/目录下的配置文件过一遍,确认rotate数量合理、compress开启、postrotate正确。如果你现在还靠手动删日志,明天把它配好。一次配置,长期受益。




