Logrotate 日志轮转实战:核心指令、应用配置与排错指南

日志文件不轮转,磁盘迟早被写满。本文详解 Linux logrotate 的工作原理、配置文件结构、rotate/compress/copytruncate 等核心指令、自定义应用轮转配置的写法与 debug 排错方法,并说明本地轮转与观测云平台留存如何分工。

最佳实践
Logrotate 日志轮转实战:核心指令、应用配置与排错指南技术指南封面

日志轮转(Log Rotation)是在日志文件达到预设周期或大小时,将其重命名归档、压缩历史文件并清理超期文件的机制,Linux 上的标准实现是 logrotate 工具。 它的使命很朴素:别让日志把磁盘写满,同时让单个日志文件保持在可检索、可传输的合理大小。

核心要点速览

  • 轮转触发条件有两种:按时间(daily/weekly/monthly)或按大小(size),满足其一即执行;
  • 配置分两层:全局默认 /etc/logrotate.conf,单应用策略放 /etc/logrotate.d/
  • 最容易踩的坑是轮转后应用还在往旧文件写——用 copytruncatepostrotate 通知应用重开文件解决;
  • 排错三板斧:logrotate -d 干跑调试、logrotate -fv 强制轮转、/var/lib/logrotate/status 查状态;
  • 本地轮转只负责磁盘兜底,长期留存与归档应交给观测云的多索引与存储策略。

为什么必须做日志轮转?

日志落到本地文件是持久化的第一步——历史分析、审计、排障都依赖它。但文件持续膨胀会带来三个问题:磁盘空间耗尽引发故障;单个文件过大导致 grep/检索缓慢;无关旧数据淹没关键信息。轮转把日志数据按时间或大小切分到多个文件,并自动清理超期文件,是文件日志体系的标配组件。

Ubuntu 及主流发行版默认已安装并启用 logrotate,可用 logrotate --version 验证。

配置文件结构:全局 + 单应用

  • /etc/logrotate.conf:主配置,定义全局默认(默认每周轮转、保留 4 份);
  • /etc/logrotate.d/:目录下每个文件对应一个应用/服务的轮转策略,会覆盖全局默认。

系统自带示例(/etc/logrotate.d/rsyslog):

/var/log/syslog
{
    rotate 7        # 保留 7 份历史文件
    daily           # 每天轮转
    missingok       # 文件缺失时不报错
    notifempty      # 空文件不轮转
    delaycompress   # 推迟一次再压缩(便于采集器读完)
    compress        # gzip 压缩旧文件
    postrotate
        /usr/lib/rsyslog/rsyslog-rotate
    endscript
}

核心指令速查表

指令 作用
daily / weekly / monthly 按天/周/月轮转
size 100M 文件超过指定大小即轮转(与时间条件取先满足者)
rotate N 保留 N 份历史文件,超出的删除
compress / nocompress 是否 gzip 压缩历史文件
delaycompress 延迟一轮再压缩,给采集程序留读取窗口
missingok / notifempty 文件缺失不报错 / 空文件不轮转
create 644 user group 轮转后新建日志文件的权限与属主
copytruncate 复制后清空原文件,应用无需重开句柄
dateext 归档文件用日期后缀而非递增数字
prerotate/postrotate 轮转前后执行的脚本(如通知服务 reload)

给自定义应用写一份轮转配置

假设应用把日志写在 /var/log/myapp/myapp.log,新建 /etc/logrotate.d/myapp

/var/log/myapp/*.log
{
    daily
    rotate 14
    size 200M
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
    create 644 myapp myapp
}

copytruncate 还是 create?

这是最关键的一个取舍:

  • 默认(create):把旧文件改名、新建同名文件。前提是应用能感知文件变化——通常要配 postrotate 脚本给进程发信号(如 kill -USR1)让它重开日志句柄;
  • copytruncate:先复制一份归档,再把原文件清空。应用继续往原文件写,无需配合,代价是复制瞬间可能丢极少量日志。

应用不支持信号重开句柄时,选 copytruncate 最省心。

排错:轮转没生效怎么办?

  1. 查状态文件sudo cat /var/lib/logrotate/status,确认目标文件在轮转清单中及上次轮转时间;
  2. 干跑调试sudo logrotate -d /etc/logrotate.d/myapp,只模拟不执行,配置拼写错误(如 compresss)会直接报 公开资料未说明 option
  3. 强制执行sudo logrotate -fv /etc/logrotate.conf-f 立即轮转、-v 输出详细过程。

prerotate/postrotate 脚本不执行,检查脚本是否有可执行权限(chmod +x)、路径是否正确。

本地轮转与平台留存如何分工?

观测云落地:使用观测云后,日志一经 DataKit 采集上报,分析、检索与长期留存都转移到平台侧完成 。此时本地 logrotate 的定位是磁盘兜底——缩短保留份数、收紧大小即可;真正的生命周期管理交给观测云:按业务线划分多索引,为不同索引配置差异化的存储策略(标准存储/低频存储/归档存储),需要长期合规留存的日志通过数据转发归档到对象存储 。DataKit 文件采集基于偏移量跟踪,能正确衔接轮转产生的新文件,本地清理不影响平台数据完整性 。

总结

logrotate 的配置可以浓缩为一句话:定好触发条件(时间或大小)、定好保留份数、处理好"应用重开文件"这个坑。配合观测云后,它退居为本地磁盘的安全阀,日志的检索、告警与长期留存全部由平台接管。

常见问题(FAQ)

Q:轮转后应用不再写日志了,是什么原因?
最常见的原因是应用仍持有旧文件句柄:旧文件被改名后,应用的输出跟着旧文件走了。解决方案二选一:配置 postrotate 脚本通知应用重开日志文件,或改用 copytruncate 模式。

Q:logrotate 是实时守护进程吗?
不是。logrotate 由系统定时任务(cron.daily 或 systemd timer)按天触发,所以 size 条件的最小检查粒度也是一天;需要更高频控制时,可以自建 cron 条目指定单独的配置文件和状态文件。

Q:如何保留更久的历史日志但又不占磁盘?
本地只保留短期热数据(如 14 天),把日志通过 DataKit 上报观测云后,用归档存储或数据转发到对象存储实现低成本长期留存,本地与平台各管一段。

Q:rotate 0 是什么意思?
表示不保留任何历史副本——轮转时直接删除旧文件。适合日志已实时上报平台、本地完全不留档的场景。


系列阅读:Linux 系统日志管理入门降低日志成本七步法

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台