1.6.3 日志轮转与保留策略(logrotate)

日志轮转与保留策略(logrotate)#

logrotate 用于控制日志文件的轮转、压缩、保留与清理,防止日志无限增长。通过定时任务触发,依据配置文件对指定日志进行处理,并可在轮转后执行重载脚本。

原理草图(轮转流程)#

文章图片

安装与服务状态确认#

  • 安装(不同发行版二选一):
# RHEL/CentOS/Rocky
sudo dnf install -y logrotate

# Debian/Ubuntu
sudo apt-get update && sudo apt-get install -y logrotate
  • 确认触发方式
# systemd 方式
systemctl list-timers | grep -E 'logrotate'

# cron 方式
ls -l /etc/cron.daily/logrotate

核心配置文件与加载顺序#

  • 主配置:/etc/logrotate.conf
  • 业务配置目录:/etc/logrotate.d/

查看主配置中是否包含业务目录:

grep -n "include" /etc/logrotate.conf

常用配置项与命令解释#

  • daily | weekly | monthly:轮转周期
  • rotate N:保留 N 个历史文件
  • size 100M:达到阈值立即轮转
  • compress / delaycompress:压缩策略
  • create 0640 user group:新文件权限/属主/属组
  • missingok:文件不存在不报错
  • notifempty:空文件不轮转
  • sharedscripts:postrotate 只执行一次
  • copytruncate:复制后截断(不重启但可能丢日志)

典型示例(完整可执行)#

场景: 自定义业务日志 /var/log/myapp/*.log,按天轮转,保留 14 天,超过 200M 立即轮转,轮转后 reload 服务。

1) 创建配置文件

sudo tee /etc/logrotate.d/myapp >/dev/null <<'EOF'
/var/log/myapp/*.log {
    daily
    rotate 14
    size 200M
    compress
    delaycompress
    missingok
    notifempty
    create 0640 myapp myapp
    sharedscripts
    postrotate
        systemctl reload myapp >/dev/null 2>&1 || true
    endscript
}
EOF

2) 手动测试配置

# -d:调试模式,不实际轮转;-f:强制轮转
sudo logrotate -d /etc/logrotate.d/myapp
sudo logrotate -f /etc/logrotate.d/myapp

3) 预期效果
- 产生 /var/log/myapp/app.log.1
- 压缩为 /var/log/myapp/app.log.2.gz
- 新日志文件权限为 0640 且属主为 myapp

轮转策略设计建议#

  • 业务日志:按天轮转,保留 14~30 天,开启压缩
  • 审计日志:保留 90 天以上,建议集中归档
  • 高频日志:按大小轮转(如 100M),避免单文件过大
  • 关键日志:轮转后同步到集中日志平台(如 rsyslog/ELK)

运行与排错指南(含命令)#

  • 未轮转:检查语法与状态文件
sudo logrotate -d /etc/logrotate.conf
sudo cat /var/lib/logrotate/status | grep myapp
  • 日志仍写旧文件:应用未重载,检查 postrotate
systemctl status myapp
journalctl -u myapp -n 50
  • 压缩失败:检查 gzip 与权限
which gzip
ls -l /var/log/myapp
  • 误删/保留不足:rotate 过小或 size 设置过低
grep -n "rotate" /etc/logrotate.d/myapp
grep -n "size" /etc/logrotate.d/myapp

练习#

1) 为 nginx 日志设置“按大小 100M 轮转,保留 20 份,压缩”的配置。
2) 用 logrotate -d 验证配置输出,解释为何未轮转。
3) 将 copytruncate 改为 postrotate + reload 并比较是否丢日志。