Oamc

日志切割(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 的日志驱动限制。