VPS日志轮转配置了却不生效?从Logrotate状态、权限到进程重开文件排查

轮转文件成功不等于服务已切换到新日志,先把调度、配置和写入进程分开检查
发布于
8

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、通配符是否匹配、状态文件记录的上次轮转时间、dailysize条件是否满足,以及是否因重复定义而跳过。

第三层:配置文件、目录和权限要一起查

ls -l /etc/logrotate.d/
ls -ld /var/log /var/log/your-app
ls -l /var/log/your-app/*.log

Logrotate需要能够读取旧文件、在目录中改名和创建新文件。使用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时,两套保留策略都要检查。

轮转后磁盘仍满,继续查这三项

  1. 已删未释放:旧日志仍被进程打开,du看不到但df空间未归还;
  2. 保留过多:rotate份数、日期文件和压缩策略与增长速度不匹配;
  3. 根因未修:错误循环、调试模式、访问洪峰或应用异常让新日志继续高速增长。

如果dfdu不一致,可参考极跃圈的VPS已删未释放文件与inode排查;磁盘已经接近满载时,则按日志、Docker与数据库安全清理顺序先恢复必要余量。

上线前做一次完整轮转演练

  1. 向测试日志写入带时间戳的标记;
  2. 用调试输出确认配置匹配和轮转理由;
  3. 在维护窗口触发一次受控轮转;
  4. 确认旧文件保留、新文件权限正确;
  5. 继续写入并确认内容进入新文件;
  6. 验证压缩、保留份数和删除周期;
  7. 等待下一次自动调度,确认不是只能手动成功。

最后为磁盘使用率、日志增长速度和轮转失败设置告警。轮转只能限制存储增长,重复错误本身仍需要从应用、访问和系统日志中定位。

结论

VPS日志轮转不生效,应把调度器、Logrotate条件、文件权限和应用写入句柄分开检查。调试模式解释“为什么没轮转”,状态文件解释“为什么现在跳过”,lsof和服务重开流程则解释“为什么旧日志仍增长”。

常见问题(FAQ)

Logrotate配置写好了,为什么日志没有每天轮转?
写入配置不等于调度已执行。还要确认systemd timer或Cron正常、状态文件记录、daily条件是否满足,以及配置是否被主配置include。使用调试模式可以查看本次为什么跳过。
可以直接用logrotate -f强制轮转吗?
强制模式会忽略时间条件并实际修改文件,不应在不了解配置时直接用于生产。先用调试模式和详细模式检查匹配、权限与postrotate,再在可回滚窗口做受控验证。
日志改名后空间为什么没有释放?
应用可能仍持有旧文件描述符并继续写入。应使用服务支持的重开日志信号或安全重载,随后用lsof检查旧文件是否仍被占用;不要只删除文件名。
copytruncate和postrotate该怎么选?
能安全重开日志的服务通常优先使用rename后通知服务重开。copytruncate适用于无法重开的程序,但复制与截断之间可能丢失或重复少量日志,且大文件复制有IO成本。

本文由作者原创/授权发布于极跃圈(jiyueip.com)未经许可,禁止转载。题图来自Unsplash,基于CC0协议。

声明:极跃圈(JIYUEIP.com)内网友所发表的所有内容及言论仅代表其本人,并不反映任何极跃圈(JIYUEIP.com)之意见及观点。

0 讨论
热门最新
总结
暂无总结
0 / 600