宝塔日志从不轮转:单个访问日志涨到 221MB-第三维度MokIII

症状:磁盘莫名其妙少了几百 MB

面板上看磁盘占用,发现 /www/wwwlogs 目录下单站日志已经 221 MB,整个目录 371 MB。而这个目录从来没有轮转过——没有 .1、.gz,只有一个不断长大的 .log。

后果不止是占空间:

  • grep / awk 分析日志时要把几百 MB 读一遍,慢到没法用;
  • 磁盘写满会让整台机器上的所有站一起挂;
  • 日志文件太大时,某些工具直接放弃处理。

一、先确认到底有没有在轮转

ls -lh /www/wwwlogs/ | head
cat /etc/logrotate.d/* 2>/dev/null | head -40
ls -l /etc/cron.daily/logrotate

如果 /etc/logrotate.d/ 里没有任何针对 /www/wwwlogs 的规则,那就是根本没配。

二、加上规则

新建 /etc/logrotate.d/bt-wwwlogs:

/www/wwwlogs/*.log {
    daily
    rotate 7
    missingok
    notifempty
    compress
    delaycompress
    create 0700 www www
    sharedscripts
    postrotate
        [ -f /www/server/nginx/logs/nginx.pid ] && kill -USR1 $(cat /www/server/nginx/logs/nginx.pid) 2>/dev/null || true
    endscript
}

几个关键项:

项为什么
daily + rotate 7每天切一次,保留 7 份。按站点量调整
compress + delaycompress压缩旧的;delaycompress 让最近一份保持可读(有些脚本还在写)
create 0700 www www新文件属主给 www,否则 nginx 可能没权限写入,日志会直接断掉
postrotate + kill -USR1必须。nginx 是持有文件句柄的,光把文件改名它还会继续往旧 inode 写,日志就"看着切了其实没切"。USR1 让 nginx 重新打开日志文件,不中断服务

三、别忘了检查 logrotate 自己有没有在跑

这是最容易漏的一步:配好了规则,但它从来没被执行过。

# 手动试跑(-d 是 debug,只打印不执行;确认没问题再去掉 -d)
logrotate -d /etc/logrotate.d/bt-wwwlogs

# 看 logrotate 自己的执行记录
grep -i logrotate /var/log/cron* 2>/dev/null | tail

我遇到的情况是:/etc/cron.daily/logrotate 这个文件被加上了不可修改属性(chattr +i),导致它长期没有被执行过。检查方法:

lsattr /etc/cron.daily/logrotate

看到 ----i--------- 之类的 i 属性,就要先把属性去掉:

chattr -i /etc/cron.daily/logrotate

顺带说明:/etc/cron.daily 在某些系统上是由 anacron 驱动的,只在机器按周期启动时才触发。如果机器长期不重启,也会一直不执行。这种情况下更稳的是直接写进 crontab 每天跑一次。

四、验证

# 立即跑一次
logrotate -f /etc/logrotate.d/bt-wwwlogs

# 应该看到切出来的文件
ls -lh /www/wwwlogs/ | head

# 确认 nginx 仍然正常(日志继续写、站点不 502)
tail -1 /www/wwwlogs/example.com.log
curl -s -o /dev/null -w '%{http_code}\n' https://www.example.com/

五、回滚

删掉 /etc/logrotate.d/bt-wwwlogs 即可,已有的 .gz 历史文件手动清理。


一句话总结:宝塔环境的 /www/wwwlogs 默认不轮转,日志涨到几百 MB 是常态。配规则时记住三点:新文件属主要给 web 用户、必须发 USR1 让 nginx 重开日志、以及确认 logrotate 自己真的在执行——最后这条最容易被忽略。