logrotate 日志轮转配置:避免日志丢失与文件持续增长
应用把日志持续写入普通文件时,需要安排保留和轮转,否则容量会随运行时间增长。Ubuntu 24.04 常见的 logrotate 可以按配置改名、压缩和清理历史日志,但它不负责决定业务日志是否已经完整采集。先确认日志由谁写、谁轮转,再添加规则,避免与应用自身轮转或容器日志管理重复处理。
明确应用怎样打开日志
有些应用在每次任务运行时重新打开文件,另一些长期持有打开的文件描述符。把旧日志改名后,后一类程序可能继续往旧文件写,因此新文件一直为空、旧文件却越来越大。处理方式应按应用文档选择重新打开日志的接口,不能猜一个信号就发给进程。
journal 日志、Docker 管理的日志和普通文本日志有不同生命周期。本教程针对独立普通文件,使用 /var/log/demo-job/run.log 演示;该目录和文件必须属于已确认的应用,不能把通配符直接指向所有系统日志。
为可重新打开文件的任务编写规则
以下例子假设 demo-job 是短时任务,每次运行重新打开日志,账号和组均已经存在,并已确认轮转时没有长时间占用文件。管理员先确认 /etc/logrotate.d/demo-job 尚未被其他规则使用,再将下面内容保存到该文件,并确认主配置 /etc/logrotate.conf 包含 include /etc/logrotate.d,让后面的完整配置检查实际加载新规则:
/var/log/demo-job/run.log {
daily
rotate 14
missingok
notifempty
compress
delaycompress
create 0640 demo-job demo-job
su demo-job demo-job
}
这个示例每天检查轮转、保留指定份数,并延后压缩最近一次轮转文件。数字是演示保留方案,应按容量与业务复盘需要调整,不能假定十四份就一定覆盖十四天。su 身份必须对相关目录有完成轮转的权限,创建文件的归属也要与之匹配。Ubuntu logrotate 手册说明了这些指令。
时间条件和大小条件不要混淆
写 daily 不代表它在后台持续监视日志;logrotate 需要被 cron 或 systemd timer 实际调用。若调度每天执行一次,即使写了按小时轮转的条件,也不会自动变成每小时运行。
size 与时间间隔规则有优先关系,不能把两个选项随便叠加后猜测结果。要实现“按时间处理,但太大时提前处理”等策略,应选择相应的组合,并确保检查频率足够。先估算最坏增长速度,再决定调用频率与保留空间。logrotate 官方项目提供上游手册和维护说明。
先调试,再做受控的真实轮转
把规则放到明确的新配置文件后,首先使用调试模式:
# Ubuntu 服务器
sudo logrotate --debug /etc/logrotate.conf
systemctl list-timers --all
调试模式不修改日志,也不更新轮转状态。查看是否有重复匹配、目录权限和语法问题,再确认现场实际由哪个计划调用。不要因为输出“没有必要轮转”就加入强制参数反复执行;它可能只是还没到条件。
需要真实验收时,先保存相关日志副本,在低峰或任务停止期间处理单个目标规则。观察旧文件、新文件、属主、权限和最新日志时间,确认下一次任务确实写到新文件。只看轮转文件名出现,还不能证明应用已经切换了写入位置。
谨慎看待 copytruncate 与恢复
copytruncate 会先复制内容再截断原文件,在两步之间存在新日志可能丢失的窗口;它不是对所有应用都无损的通用解决方案。能使用应用明确支持的重新打开机制时,应优先按该机制设计。需要持续精确采集时,还应使用适合的日志收集方式。
删除旧日志文件不一定立即释放空间,仍被程序打开的文件可能继续占用。此时应核对写入进程并按业务方式重新打开或重启,不直接对进程强杀。不要手工编辑轮转状态文件来掩盖调度问题。
配置变更异常时,恢复本次规则的备份,保留现有日志文件用于比对;已被删除的历史内容无法靠恢复规则重建。后续监控应同时关注磁盘占用、日志更新时间和轮转任务结果,让“磁盘没满”和“日志没断”都得到验证。