VPS配置了Logrotate,日志仍然持续变大,问题通常不只在“轮转周期”。Logrotate负责按条件改名、压缩或创建文件,systemd timer或Cron负责定时调用,应用进程还必须把写入切换到新文件。任何一层失效,都会出现“配置看起来有,磁盘还是被日志吃满”的现象。
先确认是哪一种不生效
| 现象 | 可能原因 | 优先检查 |
|---|---|---|
| 从未生成轮转文件 | 调度未运行、配置未include、条件未满足 | timer/Cron、状态文件、调试输出 |
| 手动执行报错 | 语法、权限、目录或用户配置错误 | 详细输出与配置文件 |
| 生成了新文件,旧文件仍增长 | 应用继续写旧文件描述符 | lsof、postrotate、服务重开日志 |
| 压缩文件存在但磁盘未降 | 旧文件被占用、保留过多或其他日志增长 | df/du、打开文件、保留策略 |
| 轮转后短暂丢日志 | 重开时序或copytruncate边界 | 应用官方轮转方式与测试日志 |
先记下目标日志路径、当前大小、文件所有者、最后修改时间和写入进程。不要在尚未确认来源时直接删除最大文件。
第一层:Logrotate是否被系统定时调用
现代发行版可能使用systemd timer,也可能由Cron每天运行:
systemctl status logrotate.timer --no-pager
systemctl list-timers --all | grep -i logrotate
journalctl -u logrotate.service --since "-2 days" --no-pager若系统没有这些单元,再检查发行版的Cron配置。不要为了“保险”同时新增timer和Cron,否则可能造成重复执行。还要确认系统时间与时区正确,休眠或停机期间是否需要补跑取决于调度器配置。
第二层:用调试模式看它为什么跳过
sudo logrotate -d /etc/logrotate.conf
sudo logrotate -v /etc/logrotate.conf-d用于调试判断,通常不执行实际轮转;-v会给出更详细过程,并可能按正常条件实际处理。运行前应查阅本机版本帮助,避免把生产配置误当成无副作用测试。
重点看目标配置是否被include、通配符是否匹配、状态文件记录的上次轮转时间、daily或size条件是否满足,以及是否因重复定义而跳过。
第三层:配置文件、目录和权限要一起查
ls -l /etc/logrotate.d/
ls -ld /var/log /var/log/your-app
ls -l /var/log/your-app/*.logLogrotate需要能够读取旧文件、在目录中改名和创建新文件。使用create时,新日志的权限、所有者和组必须让应用继续写入;非root目录可能需要su指定轮转用户和组。目录权限过宽也可能触发安全拒绝。
配置文件本身还可能因为错误后缀、权限或主配置未include而未被加载。不要把编辑器备份文件留成可匹配配置,也不要通过给日志目录777来绕过权限问题。
第四层:状态文件可能让“今天不轮转”成为正常结果
Logrotate使用状态文件记录上次处理时间。刚手动轮转过、复制了旧状态文件,或多套任务共用/不共用预期状态时,本次可能因周期未到而跳过。调试输出会说明判断。
-f强制轮转会忽略部分时间条件并实际修改文件,不应作为第一步。先理解状态和配置,再在维护窗口对单个受控配置验证,并提前确认应用如何重开日志。
第五层:文件轮转了,应用还在写旧句柄
Linux进程可以继续向已经改名甚至已删除的文件写入。可检查:
sudo lsof +L1
sudo lsof /var/log/your-app/*.log对于Nginx、数据库和其他守护进程,应使用其官方支持的重开日志信号、管理命令或安全重载。Logrotate配置通常通过postrotate完成通知;命令路径、PID文件或服务名错误时,轮转文件虽然出现,写入却没有切换。
不要为了释放一个日志直接杀死未知进程。先确认服务角色、健康检查和恢复通道,再执行受控重载,随后验证新文件持续增长而旧文件不再变化。
rename重开与copytruncate如何取舍
| 方式 | 优点 | 限制 |
|---|---|---|
| 改名后通知服务重开 | 通常不需复制整个文件,边界更清晰 | 应用必须支持重开,通知命令必须可靠 |
| copytruncate | 应用无需重开文件 | 复制与截断间可能丢失或重复日志,大文件增加IO |
能可靠重开日志的服务通常优先采用官方方式。只有应用无法重开且已接受copytruncate边界时才使用后者,并在真实写入速率下验证。
Journald不是Logrotate管理的普通文件
systemd-journald使用自己的日志存储与保留机制。先查看:
journalctl --disk-usage其容量、保留时间和持久化设置应通过journald配置管理,不能简单为二进制journal文件套普通Logrotate。应用同时写文本日志和journal时,两套保留策略都要检查。
轮转后磁盘仍满,继续查这三项
- 已删未释放:旧日志仍被进程打开,
du看不到但df空间未归还; - 保留过多:
rotate份数、日期文件和压缩策略与增长速度不匹配; - 根因未修:错误循环、调试模式、访问洪峰或应用异常让新日志继续高速增长。
如果df和du不一致,可参考极跃圈的VPS已删未释放文件与inode排查;磁盘已经接近满载时,则按日志、Docker与数据库安全清理顺序先恢复必要余量。
上线前做一次完整轮转演练
- 向测试日志写入带时间戳的标记;
- 用调试输出确认配置匹配和轮转理由;
- 在维护窗口触发一次受控轮转;
- 确认旧文件保留、新文件权限正确;
- 继续写入并确认内容进入新文件;
- 验证压缩、保留份数和删除周期;
- 等待下一次自动调度,确认不是只能手动成功。
最后为磁盘使用率、日志增长速度和轮转失败设置告警。轮转只能限制存储增长,重复错误本身仍需要从应用、访问和系统日志中定位。
结论
VPS日志轮转不生效,应把调度器、Logrotate条件、文件权限和应用写入句柄分开检查。调试模式解释“为什么没轮转”,状态文件解释“为什么现在跳过”,lsof和服务重开流程则解释“为什么旧日志仍增长”。






