人人都会AI编程

24.3 日志轮转:logrotate 配置、切割策略、压缩归档

更新时间:2026-07-12

日志文件如果不加管理会无限制地增长,最终撑满磁盘,导致服务停止甚至系统故障。Linux 系统中解决这一问题的标准工具是 logrotate。它不是后台守护进程,而是一个通过定时任务(通常由 cron 每日触发)运行的命令行工具,能够按照预设规则自动对日志进行轮转、压缩、删除或邮寄。

1. logrotate 工作方式

logrotate 的主配置文件为 /etc/logrotate.conf,通常在文件末尾通过 include /etc/logrotate.d 指令载入目录中各个应用的独立配置。系统中已安装的多数服务(如 nginx、mysql、rsyslog)都会在该目录下放置自己的轮转配置。

logrotate 每天由 /etc/cron.daily/logrotate 脚本调用一次(具体取决于发行版)。它会读取配置,比对每个日志文件的状态(记录在 /var/lib/logrotate/logrotate.status 文件中),决定是否执行轮转操作。

2. 一个典型的轮转配置

/etc/logrotate.d/nginx 为例:

/var/log/nginx/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 640 nginx adm
    sharedscripts
    postrotate
        [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
    endscript
}

这段配置的含义是:

  • daily:每天轮转一次(还可以是 weeklymonthlyyearly)。
  • rotate 14:保留 14 个历史日志文件,超出数量的旧日志会被删除。
  • compress:轮转后的旧日志用 gzip 压缩(例如 access.log.1.gz)。
  • delaycompress:最新轮转出来的日志(.1)不压缩,下个周期再压缩,避免影响仍可能被写入的进程。
  • missingok:如果日志文件不存在,不报错继续执行。
  • notifempty:如果日志文件为空,不进行轮转。
  • create 640 nginx adm:轮转后立即创建一个权限 640、属主 nginx、属组 adm 的新日志文件,保证服务能继续写入。
  • sharedscriptspostrotate 脚本只对所有匹配的日志文件执行一次,而不是每个文件都执行一次。
  • postrotateendscript 之间的命令在轮转后执行,这里向 nginx 发送 USR1 信号使其重新打开日志文件。

3. 切割策略:基于时间还是大小

除时间周期外,logrotate 也支持基于文件大小的轮转,这对突发写入量大的应用非常有用:

/var/log/myapp/*.log {
    size 100M
    rotate 5
    compress
    missingok
}
  • size 100M 表示当日志文件达到 100 MB 时就进行轮转,与时间无关。可同时使用 dailysize,此时两者为“或”关系,哪个条件先满足就轮转。
  • 也可以使用 maxsizeminsize,结合时间周期形成更精细的控制。

4. 压缩与归档

旧日志压缩是 logrotate 的标配功能,通过 compress 开启,默认使用 gzip。可以使用 compresscmdcompressext 改用其他压缩算法,如:

compresscmd /usr/bin/xz
compressext .xz

除了压缩,你还可以通过 dateext 参数让轮转后的日志文件名带上日期(如 messages-20250212.gz)而非单纯用数字后缀,这便于按日期快速定位:

dateext
dateformat -%Y%m%d

如果需要将旧日志转移到其他目录或远程存储,可使用 olddir 指令:

olddir /var/log/archived/nginx

轮转后文件会被移动到该目录,如果该目录不存在,logrotate 会报错,除非加上 noolddir 的处理逻辑。更复杂的归档任务可通过 postrotate 脚本配合 rsyncaws s3 等命令实现。

5. 手动执行与排错

logrotate 可以手动运行,这在新增配置或调试时非常重要:

  • 按配置执行一次:logrotate /etc/logrotate.conf
  • 强制轮转(即使条件未满足):logrotate -f /etc/logrotate.conf
  • 配合 -d 选项进入调试模式,只显示将要执行的动作而不真正操作:logrotate -d /etc/logrotate.conf
  • 使用 -v 显示详细过程。

如果发现某应用的日志没有正常轮转,首先检查:

  • 配置文件语法是否正确(logrotate -d 会给出提示);
  • 日志文件路径是否实际存在且可读;
  • missingok 是否已合理使用,避免因文件缺失导致整个任务中断(默认情况下,缺失日志文件会导致 logrotate 报错退出);
  • 状态文件 /var/lib/logrotate/logrotate.status 中的记录是否与当前文件名和日期相符,必要时可手工修正或删除该状态文件让其重新初始化。

6. 实用经验

  • 统一管理:尽量将各应用的轮转配置放在 /etc/logrotate.d/ 下,使用独立的 .conf 文件,保持清晰。
  • 信号处理:绝大多数守护进程在日志轮转后需要收到信号才会重新打开日志文件,否则会继续写入已被重命名的旧文件。务必参考各服务的文档,在 postrotate 中加上正确的重载命令。
  • 权限一致:用 create 指令创建的新日志文件权限和属主必须与原始文件一致,否则可能导致服务无法写入。可以在轮转前用 ls -l 记录原始权限,然后照搬配置。
  • 定期监控:设置监控告警,当某个日志文件大小超出预期或 cron 运行 logrotate 报错时及时通知。即使有轮转,瞬间爆发的大量日志仍可能填满磁盘,此时应结合 maxsize 或进程自身的日志速率限制。

logrotate 原理简单,却是生产环境中维持系统稳定必不可少的组件。熟练掌握它的配置和调试方法,可以有效避免因日志堆积引起的各类故障。