用心打造
VPS知识分享网站

Linux日志一直不轮转?logrotate配置与验证指南

明明已经在 /etc/logrotate.d/ 写了配置,日志文件却一直变大,最常见的原因并不是logrotate失效,而是定时任务没有运行、文件没有匹配、轮转条件尚未满足,或者轮转后应用仍占用旧文件。

先区分没有触发、配置报错和轮转后未重新打开日志三种情况。 直接删除当前日志虽然能暂时腾出空间,却可能让进程继续写入已经删除但仍被占用的文件。

Linux日志文件因logrotate未触发或配置错误而持续增长的示意图

确认logrotate有没有被调度

使用systemd的发行版通常由 logrotate.timer 定时触发,先检查定时器和最近一次执行结果:

systemctl status logrotate.timer --no-pager
systemctl list-timers logrotate.timer --all
journalctl -u logrotate.service -u logrotate.timer --since '7 days ago'

部分系统仍由cron运行,可查看 /etc/cron.daily/logrotate、cron日志和对应服务状态。容器精简镜像可能只安装了logrotate程序,却没有cron或systemd负责执行。

官方说明中,logrotate通常每天由cron或systemd timer调用。配置中的daily只表示每次程序运行时如何判断,并不会自己创建一个常驻调度器。

检查配置是否真的匹配日志

主配置一般是 /etc/logrotate.conf,并通过 include /etc/logrotate.d 加载应用配置。先确认目标文件路径、通配符和配置文件本身:

sudo grep -R --line-number '/var/log/myapp' /etc/logrotate.conf /etc/logrotate.d
sudo ls -l /var/log/myapp.log /etc/logrotate.d/myapp
sudo logrotate --debug /etc/logrotate.conf

--debug 只输出判断过程,不修改日志,也不会更新状态文件,适合安全检查。注意配置文件名、权限或属主不符合发行版安全规则时,目录内文件可能被跳过。

若日志由普通用户目录写入,还要关注父目录权限。不要为了让轮转通过就把日志目录改成777,应使用正确的 0、1 权限和应用运行身份。

看懂状态文件与首次运行

logrotate会在状态文件中记录上次轮转时间,常见位置是 /var/lib/logrotate/status,不同发行版也可能使用其他路径:

sudo grep -F '/var/log/myapp.log' /var/lib/logrotate/status 2>/dev/null
sudo logrotate --verbose /etc/logrotate.conf

新日志第一次被发现时,logrotate可能只记录当前时间,因此daily、weekly或monthly条件不会在第一次运行就立即满足。日志看起来很大,也不代表时间条件已经到达。

需要按容量触发时,应根据业务使用 sizeminsizemaxsize,并理解它们与时间条件的组合方式。不要随手删除状态文件,整机所有轮转规则都可能因此重新计算。

核对轮转规则和文件创建

一个基础配置可以写成:

/var/log/myapp.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 0640 myapp adm
}

missingok 允许文件不存在,notifempty 跳过空日志,rotate 决定保留数量,create 决定新文件的权限和属主。应用若因为新文件属主错误而无法继续写入,表面上会像轮转把日志弄丢了。

压缩、保留天数和轮转频率要与磁盘容量共同计算。轮转不是备份,rotate 14只表示保留有限个历史文件,重要审计日志仍要发送到独立存储。

处理应用仍写旧文件的问题

许多服务在日志被重命名后,需要收到reload或专用信号才会关闭旧文件并打开新文件。可以在配置中使用 postrotate,但命令必须符合应用官方的重载方式:

postrotate
    systemctl kill -s HUP myapp.service 2>/dev/null || true
endscript

先用 lsof +L1 查看是否存在已删除却仍被进程占用的大文件。对支持重新打开日志的服务,优先使用信号或reload;copytruncate 会先复制再清空原文件,在复制与截断之间存在丢失少量日志的窗口。

不要为了省事给所有服务统一使用copytruncate。 数据库、Web服务器和自带日志管理能力的应用,应该按各自文档选择更可靠的轮转方式。

安全测试一次完整轮转

先执行debug检查,再在确认备份和磁盘空间充足后考虑强制轮转:

sudo logrotate --debug /etc/logrotate.conf
sudo logrotate --force --verbose /etc/logrotate.conf

--force 会实际改变日志和状态,适合新增规则后的受控验证,不应当作日常修复命令。测试后检查新旧文件、压缩结果、属主权限、应用日志和服务状态。

需要先演练轮转和postrotate脚本时,可通过 萤光云 建立同发行版测试机;想快速复制多地区日志环境,也可以使用 LightNode 临时部署。测试文件不要包含生产日志中的用户信息和访问令牌。

轮转后的验收方法

完成测试后,至少检查以下结果:

ls -lh /var/log/myapp.log*
stat /var/log/myapp.log
systemctl is-active myapp.service
sudo lsof +L1

新日志应由正确用户继续写入,历史文件数量和压缩状态符合配置,状态文件时间正常更新,并且定时器下一次执行时间可见。

最终验收标准不是出现了一个 0 文件,而是应用持续写新日志、旧文件按策略保留、没有删除文件占用,同时下一轮调度仍能自动执行。

FAQ

为什么配置了daily,当天执行却没有轮转?

daily依赖logrotate实际被调度运行和状态文件中的上次时间。新日志首次记录状态时,时间条件也可能暂未满足。

logrotate –debug会改变文件吗?

不会。官方说明debug模式不修改日志,也不更新状态文件,只打印判断信息。

可以每天用–force解决吗?

不建议。force会无视正常判断并实际轮转,长期使用会掩盖调度、规则或状态文件问题。

温馨提示

处理超大日志前先确认磁盘余量和进程占用。直接删除正在写入的日志并不一定释放空间,正确做法是完成轮转、让应用重新打开文件,再确认旧文件描述符已经释放。

赞(0)
未经允许不得转载;国外VPS测评网 » Linux日志一直不轮转?logrotate配置与验证指南
分享到