logrotate 配置实战:防止 Linux 系统日志挤满根分区

logrotate 配置封面

这篇指南帮助你配置 logrotate(Linux 日志轮转工具)防止系统日志挤满根分区:核心配置项、测试方法和常见问题排查。Linux 默认安装了 logrotate 但配置不一定符合实际生产环境,需要根据日志增长量和磁盘容量调整。

如果你的服务器日志增长快但 logrotate 没及时清理,根分区可能被填满导致系统无法启动。Hostease 中文博客的 容器安全加固关注应用层安全,本文关注操作系统层的日志管理。日志管理是日常运维常被忽视但出问题时影响严重的小项。

一、logrotate 工作原理

logrotate 按预设规则定期轮转日志文件,包括压缩、删除过期日志、创建新日志文件。它的运行依赖 cron(Linux 定时任务)每天执行,检查所有配置段是否满足轮转条件。

默认配置文件 /etc/logrotate.conf 会包含 /etc/logrotate.d/ 下的所有配置段,大多数服务的日志轮转配置都在这个目录。例如 syslog、nginx、apache、mysql 等都有自己的轮转配置。修改配置前先理解现有规则,避免覆盖导致日志丢失。

logrotate 轮转流程

二、核心配置项解析

一个标准的 logrotate 配置段示例:

/var/log/nginx/*.log {
    daily
    rotate 7
    missingok
    notifempty
    compress
    delaycompress
    create 0640 www-data adm
    sharedscripts
    postrotate
        systemctl reload nginx
    endscript
}

关键参数含义:

  • daily/weekly/monthly:轮转频率。生产环境根据日志增长速度选择。
  • rotate N:保留的归档数量。超过 N 个最老的会被删除。
  • missingok:日志文件不存在时不报错。适合轮转任务跑在日志生成之前。
  • notifempty:空文件不轮转。
  • compress:压缩归档。delaycompress 延迟压缩上一个归档,让可能还在读取的服务正常退出。
  • sharedscripts:所有日志轮转后才执行一次 postrotate,避免服务被频繁重启。
  • postrotate:轮转后执行的命令,通常是通知服务重新打开日志文件。

三、判断日志增长量

配置轮转策略前先评估日志增长量。用 du -sh 查看当前日志大小,观察一段时间的增长率。

du -sh /var/log/*.log
ls -lh /var/log/nginx/

对于 nginx access.log 这种高频访问日志,单文件可能每天几百 MB。轮转频率和保留数量要按这个量计算:每天轮转、保留 7 个归档,大约一周的日志量。如果磁盘空间紧张,把保留数量减到 3-4,或用 weekly 替代 daily。

如果你的服务日志特别大(如 ELK 收集或审计日志),考虑用其他存储方案而不是本地文件系统。大量小文件对 inode(文件系统的索引节点)消耗也很快,分区空间可能没满但 inode 用完了。

四、配置测试方法

修改 logrotate 配置后必须测试。用 -d 参数模拟运行,确认配置正确。

logrotate -d /etc/logrotate.d/nginx
logrotate -f /etc/logrotate.d/nginx

-d 是 dry run(空跑),会打印会执行的操作但不做实际修改。确认输出符合预期后,去掉 -d 实际运行。-f 强制执行,不等轮转周期。如果 logrotate 报错说权限不足,检查 /var/lib/logrotate/ 目录的写入权限。配置错误还会导致服务收不到 SIGHUP(Unix 信号,用于通知服务重新加载配置)信号,新的日志继续写入已轮转的文件。

logrotate 失败的常见原因包括:postrotate 命令执行失败(如 systemctl 不存在)、权限不足、配置语法错误。建议在 CI(持续集成)流程中加入 logrotate 配置语法检查:

for f in /etc/logrotate.d/*; do
    logrotate -d "$f" > /dev/null 2>&1 || echo "Config error: $f"
done

如果你的服务器同时跑多个服务,每个服务的轮转配置要单独管理,避免一个服务的日志清理规则影响另一个服务。

轮转策略对比

五、与日志管理的配合

logrotate 解决的是磁盘空间问题,但日志管理还需要考虑:日志收集(用 filebeat、fluentd 等把日志转发到集中存储)、日志查询(用 Loki、ES 等支持快速检索)、日志告警(关键错误实时通知)。logrotate 是日志生命周期的第一环,本地保留近几天用于排查,远程保留全部用于审计。

对于 WordPress 安全加固后的站点,wp-content/debug.log 这类应用日志也建议加入 logrotate 轮转。WordPress 默认会把错误写入这个文件,如果不清理可能持续增长导致磁盘填满。如果使用 OpenTelemetry 链路追踪,tracing 数据量更大,更需要配置有效的轮转和归档策略。日志轮转也要和 数据库复制延迟监控配合:数据库 binlog 和 redo log 的保留策略通常不由 logrotate 管理,但需要统一规划磁盘空间,避免日志轮转释放的空间又被数据库日志占满。

六、监控与告警

监控 /var/log 目录的空间使用率,配置告警阈值。当空间使用率超过 80% 时提醒,超过 90% 时紧急告警。logrotate 是被动的轮转工具,不会主动清理历史日志,需要配合监控才能在异常增长时及时介入。还可以监控 logrotate 的执行日志 /var/lib/logrotate/status,确认 cron 每天都在跑,配置变更后这个文件应该能看到最近一次执行时间。

监控时要注意区分不同分区的空间使用。根分区 / 满了会导致系统无法启动,/var 分区满了会影响日志和数据库写入,/tmp 分区满了会影响临时文件。如果日志写在独立分区(如 /var 单独挂载),磁盘满只影响该分区内的服务,不一定会让整个系统崩溃,但影响范围要明确记录。建议用 df -h 定期检查所有分区的使用率,对日志所在分区单独设置更高的监控频率。同时设置 inode 使用率监控,避免大量小文件耗尽 inode 导致即使磁盘有空间也无法写文件。

总结

logrotate 配置的核心是按日志增长量设定轮转频率和保留数量,配合监控系统空间使用率。配置完成后用 -d 测试,强制执行后检查归档文件。postrotate 脚本要确保服务重新打开日志文件,否则新日志会写入已轮转的文件名。定期检查 logrotate 执行日志确认 cron 正常工作。对于 Hostease 这类 [VPS](https://cn.hostease.com/vps/) 环境,建议每月检查一次磁盘使用率和日志增长趋势,及时调整轮转策略避免磁盘填满。

发表评论