
你是不是也遇到过这种情况:网站突然卡了,SSH敲命令要等好几秒,甚至报“No space left on device”。上去一查,磁盘满了。
再一查,/var/log目录几十个GB。日志把你的硬盘撑爆了。
你手动删了几个大文件,网站恢复了。下个月,又来一次。
别每次手动删了。今天教你一个工具,让日志自己管自己。
先看一个数据
某云厂商统计,超过25%的磁盘爆满事件,元凶是日志文件。不是网站文件、不是数据库、不是备份,就是日志。
一个日访问1万次的网站,access.log一天增长100-200MB。一个月就是3-6GB。加上error.log、系统日志、数据库日志……一年下来,几十GB很正常。
更可怕的是,很多人从来不删日志。服务器跑了三年,日志占了100GB。
logrotate是什么?
logrotate是Linux自带的日志轮转工具。它的工作就是:让日志自己管自己。
你给它定个规矩,比如:
- 每天切一次
- 保留最近7天的
- 7天前的删掉
- 旧的压缩起来
它每天自动执行,你不用管。
反常识点:logrotate不需要安装,系统自带。你可能每天都在用它,只是不知道。因为系统自己的日志(比如/var/log/syslog)就是靠logrotate在管。
logrotate怎么工作的?
logrotate通过两个地方配置:
- 全局配置:
/etc/logrotate.conf,定义默认规则 - 应用配置:
/etc/logrotate.d/目录,每个应用一个配置文件
系统每天通过crontab自动执行logrotate命令,扫描这些配置文件,按规则处理日志。
你可以手动跑,也可以让它自己跑。
基础配置:看懂一个例子
假设你想让Nginx的access.log每天切一次,保留7天,旧的压缩。在/etc/logrotate.d/nginx里写:
text
/var/log/nginx/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 640 nginx adm
postrotate
systemctl reload nginx > /dev/null 2>&1
endscript
}
逐行解释:
| 参数 | 含义 |
|---|---|
daily | 每天轮转一次(还有weekly、monthly) |
rotate 7 | 保留7个旧文件,第8个删掉 |
compress | 压缩旧日志(变成.gz) |
delaycompress | 延迟压缩(上一个日志不立即压缩,和compress配合用) |
missingok | 日志文件不存在也不报错 |
notifempty | 空日志不轮转 |
create 640 nginx adm | 轮转后创建新日志文件,权限640,属主nginx:adm |
postrotate | 轮转后执行的命令,这里重载Nginx让它用新日志文件 |
实战:配置Nginx日志轮转
第一步:创建配置文件
bash
vim /etc/logrotate.d/nginx
第二步:粘贴上面的配置(根据你的Nginx用户调整create那一行)
第三步:测试配置是否正确
bash
logrotate -d /etc/logrotate.d/nginx
-d是调试模式,只模拟运行,不真的改文件。看到"rotating pattern"没有报错,就说明配置没问题。
第四步:手动执行一次
bash
logrotate -f /etc/logrotate.d/nginx
-f强制轮转。执行后去/var/log/nginx/看看,应该有access.log.1.gz之类的文件。
第五步:确认crontab在跑
bash
cat /etc/crontab | grep logrotate
一般系统自带,每天凌晨跑。如果没有,可以自己加一行。
常用配置参数速查
| 参数 | 作用 |
|---|---|
daily | 每天轮转 |
weekly | 每周轮转 |
monthly | 每月轮转 |
rotate N | 保留N个旧文件 |
compress | 压缩旧日志 |
delaycompress | 延迟压缩 |
missingok | 日志不存在不报错 |
notifempty | 空日志不轮转 |
create mode owner group | 创建新日志并设权限 |
size 100M | 日志超过100M就轮转(代替daily) |
maxsize 100M | 超过100M轮转,但也不超过daily频率 |
postrotate | 轮转后执行的命令 |
prerotate | 轮转前执行的命令 |
手动测试和调试
修改配置后,先调试再执行。
调试模式(不实际执行):
bash
logrotate -d /etc/logrotate.d/nginx
强制轮转(实际执行):
bash
logrotate -f /etc/logrotate.d/nginx
查看状态(上次轮转时间):
bash
cat /var/lib/logrotate/status | grep nginx
一个真实案例
有个朋友的服务器,跑了两年,突然磁盘满了。我上去一看,/var/log/nginx/access.log 42GB。他说:“我以为日志会自动删的。”
我说:“会,但要你配。”
他花了10分钟配了logrotate,手动跑了一次,42GB变成几百MB。他说:“以前每次磁盘满了才想起来删日志,以后不用管了。”
几个常见场景的配置模板
场景一:Nginx日志,每天切,留7天
text
/var/log/nginx/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 640 nginx adm
postrotate
systemctl reload nginx
endscript
}
场景二:系统日志,每周切,留4周
text
/var/log/messages {
weekly
rotate 4
compress
missingok
notifempty
create 0644 root root
}
场景三:大日志文件,超过100M就切(不管时间)
text
/var/log/nginx/access.log {
size 100M
rotate 10
compress
missingok
notifempty
postrotate
systemctl reload nginx
endscript
}
最后一句
日志是服务器的日记本。它天天写,但你不用天天看。看了也别手删。
花10分钟配好logrotate,让日志自己管自己。以后磁盘再也不会被日志撑爆。
今天就去检查你的/var/log有多大。如果超过10GB,现在就配logrotate。




