VPS磁盘被应用日志占满时,安装或修改 logrotate 并不代表轮转已经生效。常见故障包括规则路径未匹配、权限或用户配置错误、定时器没有运行、应用继续持有旧文件句柄,以及 copytruncate 在复制和截断之间造成日志丢失。排查应先确认“规则是否执行”,再确认“进程写哪一个文件”。
先检查规则和计划任务
logrotate -d /etc/logrotate.conf
logrotate -d /etc/logrotate.d/<service>
systemctl list-timers --all | grep -i logrotate
journalctl -u logrotate -b --no-pager
-d是调试模式,不会真正轮转文件。先用它确认匹配路径、频率、保留数量和权限,再在维护窗口执行实际操作。不同发行版可能使用systemd timer或cron触发,不能只检查其中一种。
确认规则匹配了真实日志
用 ls -l、stat 和应用配置核对日志路径、文件所有者、权限、日期后缀和通配符:
ls -l /var/log/<service>/
stat /var/log/<service>/<service>.log
grep -R "/var/log/<service>" /etc/logrotate.conf /etc/logrotate.d
容器、应用自带日志和宿主机日志可能不在同一个路径。规则写的是宿主文件,但应用实际把日志写进容器标准输出时,logrotate不会替你轮转容器日志。
理解rename与copytruncate的差异
理想情况下,logrotate先把旧文件重命名,再通知应用重新打开日志。应用支持USR1、reload或专用日志重开接口时,优先使用这种方式。copytruncate会复制当前文件后再截断原文件,适合无法重开句柄的程序,但复制窗口可能丢失或重复少量日志,并且大文件复制会增加I/O。
不要在不了解应用行为时同时使用 postrotate、copytruncate 和强制重启;应选择一种经过验证的方式,并记录变更。
找出仍占用旧文件的进程
lsof +L1 | grep '/var/log'
ls -l /proc/<pid>/fd | grep deleted
如果日志已被删除但进程仍持有文件描述符,目录大小会下降而磁盘空间不一定释放。根据应用文档执行优雅重载或重启,再用 lsof +L1 复核。不要直接向生产进程写入信号,先确认服务的重载语义和维护窗口。
压缩、保留和权限也要验收
检查 rotate、daily/weekly、compress、delaycompress、su 和 create 等选项是否符合业务留存要求。轮转后的文件应由正确用户和组拥有,应用能继续写入新文件,压缩任务不会与备份、扫描或高峰写入争抢I/O。不要为节省磁盘删除仍在法定或业务保留期内的日志。
用一次小范围演练完成验收
- 保存规则、当前文件大小和进程日志句柄。
- 用调试模式确认匹配,再在维护窗口执行一次受控轮转。
- 验证新文件创建、应用仍能写入、旧文件按策略压缩或保留。
- 检查
df -h、lsof +L1和应用错误日志。 - 观察下一次计划任务,确认不是手动执行才成功。
日志轮转的目标不只是让文件名变小,而是让应用、轮转器、压缩器和保留策略在同一生命周期内协作。先证实规则执行,再处理句柄和重开方式,才能避免磁盘反复被日志填满。






