日志切割(logrotate)
场景
/var/log 被应用日志撑满,根分区 100%,或者需要一个服务只保留 14 天日志。
前置条件
- 应用把日志写在固定路径
- 应用支持重新打开日志文件(或者接受
copytruncate) - 有 root 权限
配置
cat >/etc/logrotate.d/myapp <<'EOF'
/opt/myapp/logs/*.log {
daily
rotate 14
missingok
notifempty
compress
delaycompress
copytruncate
dateext
dateformat -%Y%m%d
create 0640 appuser appuser
}
EOF
copytruncate:复制后清空原文件,适合不重启的应用create:重新创建文件时给对权限,否则应用写不进去
验证
logrotate -d /etc/logrotate.d/myapp # 只演练,不执行
logrotate -f /etc/logrotate.d/myapp # 强制执行一次
ls -lh /opt/myapp/logs/
-d 的输出里能看到哪些文件会被处理、为什么被跳过。
回滚
rm /etc/logrotate.d/myapp
已切割出来的历史文件手动清理。
坑
copytruncate会丢一小段日志(复制和清空之间的写入),要求严格就别用,改用postrotate发信号。create的属主写错,应用重启后写不了日志。- 全局
/etc/logrotate.conf里可能已经有weekly,单文件没写周期会继承默认值。 missingok和notifempty建议都加,不然空日志或临时不存在的路径会报错。- 日志切割不解决磁盘满,先
du -sh /var/log/*看看是谁大。 - 容器里的日志不走 logrotate,用 docker 的日志驱动限制。