Linux logrotate 日志轮转:自动清理日志避免磁盘占满
前言
在 Linux 服务器上运行网站、脚本或后台程序时,日志文件可能随着运行时间不断增长。如果没有定期清理,几个月下来就可能占用大量磁盘空间。
直接删除日志虽然简单,但既不方便保留历史记录,也可能因为程序仍然持有文件句柄,导致磁盘空间没有立即释放。
Linux 提供了 logrotate 工具,可以按照时间或文件大小自动轮转、压缩和清理日志。下面介绍它的基本使用方法。
一、检查 logrotate 是否安装
Ubuntu、Debian 通常已经预装 logrotate,可以先查看版本:
logrotate --version
如果没有安装,可以执行:
sudo apt update
sudo apt install logrotate
logrotate 本身不是一个需要长期运行的守护进程,而是由 cron 或 systemd timer 等调度机制定期执行。
可以尝试查看:
systemctl status logrotate.timer
如果系统没有这个 timer,也可以检查是否使用了 /etc/cron.daily/logrotate 等方式调度。
二、logrotate 的配置文件在哪里?
通常有两个主要位置:
/etc/logrotate.conf
/etc/logrotate.d/
/etc/logrotate.conf 是主配置文件,一般会通过 include 指令加载 /etc/logrotate.d/ 下的配置。
因此,为某个应用单独配置日志轮转时,通常不需要修改主配置文件,直接在 /etc/logrotate.d/ 中创建对应配置即可。
例如:
sudo nano /etc/logrotate.d/myapp
这样不同应用可以使用各自的轮转策略,也方便后期维护。
三、一个简单的日志轮转配置
假设某个应用持续向下面的文件写入日志:
/var/log/myapp/app.log
并且程序持续打开这个日志文件,暂时不支持主动重新打开日志句柄。
可以先使用下面的配置作为示例:
/var/log/myapp/app.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
copytruncate
}
各项参数含义如下:
daily:按照每天一次的周期轮转。rotate 7:最多保留 7 个历史轮转版本。compress:压缩旧日志,减少空间占用。delaycompress:推迟一个轮转周期再压缩最近的旧日志。missingok:日志文件不存在时不报错。notifempty:日志为空时不进行轮转。copytruncate:复制当前日志内容后,将原文件截断为零长度。
需要注意,rotate 7 是保留 7 个轮转版本,不是严格按照 7×24 小时删除日志。如果某天没有发生轮转,实际保留时间可能更长。
四、copytruncate 为什么需要谨慎?
这是实际使用中很重要的一个细节。
某些程序启动后会一直持有日志文件句柄。如果 logrotate 只是把原日志文件重命名,程序可能继续向旧文件写入内容,导致新日志文件没有数据。
copytruncate 的处理方式是先复制文件,再清空原文件内容,这样程序可以继续使用原有文件句柄写日志。
但它也有缺点:复制和截断之间存在短暂时间窗口,此时新写入的日志可能丢失。
所以,如果应用支持主动重新打开日志文件,更推荐采用正常的重命名轮转,并配合 postrotate 通知应用重新打开日志。
对于普通调试日志,copytruncate 可能是一个简单的兼容方案;但如果日志涉及审计、支付或其他不能接受丢失记录的场景,就不应该直接使用它。
五、按照文件大小轮转
除了按时间轮转,也可以根据日志大小决定是否处理。
例如:
/var/log/myapp/app.log {
size 50M
rotate 5
compress
missingok
notifempty
copytruncate
}
size 50M 表示检查时如果文件大小超过 50MB,就满足轮转条件。
需要注意,logrotate 只有在被调度执行时才会检查文件大小,并不是日志一达到 50MB 就立即触发轮转。
如果系统每天只执行一次 logrotate,那么日志仍然可能在当天增长到远大于 50MB。
此外,size 与 daily 等时间周期参数存在覆盖关系,不能简单理解为两个条件自动叠加。
如果需要同时考虑时间和文件大小,可以进一步了解 minsize 和 maxsize 的区别,并结合实际调度频率配置。
六、如何检查配置有没有问题?
修改配置后,不需要立即等待第二天才能发现错误。
可以使用调试模式:
sudo logrotate -d /etc/logrotate.conf
-d 表示 debug 模式,会显示计划执行的操作,但不会真正轮转日志,也不会更新状态文件。
如果只想检查某个应用的独立配置,也可以执行:
sudo logrotate -d /etc/logrotate.d/myapp
需要注意,单独执行配置文件时,不一定会加载主配置文件中的全局选项,因此结果可能与系统正常调度时略有不同。
如果确实需要立即触发一次轮转,可以使用 -f 强制执行,但它会真实修改日志文件,不建议在尚未确认配置时随意使用。
七、为什么配置了轮转,日志仍然很大?
可以重点排查以下情况。
第一,logrotate 是否被正常调度。如果定时任务没有运行,配置文件写得再正确也不会自动生效。
第二,日志路径是否正确。配置指向的文件与程序实际写入的文件不一致,自然无法达到预期效果。
第三,程序是否仍然写入旧文件。尤其是采用重命名方式轮转,但没有通知程序重新打开日志文件时,需要检查是否出现这种情况。
第四,权限是否足够。logrotate 需要有权限访问和操作对应的日志文件。如果日志目录由普通用户控制,还需要正确配置权限及必要的 su 参数。
第五,日志来源是否属于其他管理机制。例如 systemd journal 日志可以通过 journald 自身的保留策略管理,Docker 容器的标准输出日志也有专门的日志驱动和轮转配置,不应该一律直接套用普通文件的 logrotate 方案。
八、实际使用建议
对于长期运行的服务器,建议根据日志的重要程度分别设置策略。
普通应用日志可以保留少量历史版本并启用压缩;错误日志可以适当延长保留时间;审计类日志则应遵循实际安全与合规要求,必要时集中存储和备份。
另外,日志轮转只能管理文件增长,不能解决程序持续产生大量异常日志的根本问题。
如果短时间内日志量突然增加,最好同时检查应用是否出现了重复报错、异常重试或其他故障。
总结
logrotate 适合解决 Linux 服务器日志长期增长的问题,基本配置并不复杂。
日常使用时记住几个重点:
- 为不同应用单独创建轮转配置。
- 使用 rotate 和 compress 控制历史日志数量及空间占用。
- 使用 debug 模式预览配置,避免直接修改生产日志。
- 根据程序的写日志方式决定是否需要 copytruncate。
- 确认系统的定时调度正常运行。
相比定时执行 rm 删除日志,使用 logrotate 更容易保留历史记录,也更方便长期维护。
- 点赞
- 收藏
- 关注作者
评论(0)