Ubuntu 日志管家 logrotate 完全指南:安装、原理与深度配置
在 Ubuntu 系统中,logrotate 并非一个可有可无的附加组件,而是深深嵌入系统骨髓的”日志管家”。它全天候运行,确保日志文件不会肆意膨胀,避免磁盘空间被无声吞噬,同时也让日志的查看、归档与排查变得秩序井然。理解 logrotate 的工作原理、安装部署与配置哲学,是每一位 Ubuntu 运维人员的必修课。
一、安装部署:从确认到就绪
确认是否已安装
绝大多数 Ubuntu 发行版都默认预装了 logrotate。你可以通过以下命令快速验证:
logrotate --version
如果系统已安装,会显示版本号信息。若提示命令未找到,则需要手动安装。
安装步骤
如果确认未安装,执行以下命令完成部署:
sudo apt update
sudo apt install logrotate -y
安装完成后,系统会自动完成以下初始化工作:
- 创建主配置文件
/etc/logrotate.conf - 创建应用配置目录
/etc/logrotate.d/ - 建立状态文件
/var/lib/logrotate/status(用于记录各日志上次轮转时间) - 配置定时触发机制(通过 systemd timer 或 cron)
定时触发机制
logrotate 本身是一个被动执行的工具,需要外部定时任务来驱动。在较新的 Ubuntu 版本(如 20.04 及之后)中,触发方式已与 systemd 体系深度集成。你可以通过以下命令查看其定时器状态:
systemctl list-timers | grep logrotate
你将看到 logrotate.timer 和 logrotate.service 协同工作,通常配置为每天执行一次。在更早的版本中,触发脚本位于 /etc/cron.daily/logrotate,由 cron 每天唤醒。
二、核心机制:轮转的完整流程
加载配置
当 logrotate 被定时任务触发时,它首先加载配置文件,包括:
- 主配置文件 (
/etc/logrotate.conf):定义全局默认策略 - 目录配置 (
/etc/logrotate.d/):各应用的个性化配置,会覆盖全局设置
轮转条件判定
logrotate 根据配置文件中的指令,逐一检查每个日志文件是否需要轮转。触发条件主要有两类:
- 基于时间:
daily、weekly、monthly、yearly、hourly——按固定周期轮转 - 基于大小:
size 100M——当日志达到指定大小时触发轮转 - 组合条件:
maxsize可在周期内提前触发;minsize则要求同时满足大小和时间条件才触发
轮转执行过程
当判定需要轮转时,logrotate 会执行以下操作:
- 重命名当前日志文件:如将
syslog重命名为syslog.1 - 级联移动旧文件:
syslog.1→syslog.2,依次顺延 - 删除最旧文件:如果备份数量超过
rotate设定的上限,删除最旧的一个 - 创建新日志文件:以指定权限创建与原日志同名的空文件(
create方案) - 压缩归档:按
compress指令对旧文件进行 gzip 压缩 - 执行后处理脚本:运行
postrotate中定义的命令
状态记录
每次轮转完成后,logrotate 会将本次轮转时间记录到状态文件中(/var/lib/logrotate/status),用于后续判断是否满足时间周期条件。这里有一个值得注意的细节:状态文件中记录的 lastRotated 时间会考虑时区和夏令时的影响,相关补丁曾修复过夏令时切换导致轮转周期计算偏差的问题。
三、与应用程序的协作:优雅的日志切换
一个常见的疑问是:logrotate 在对一个正在被写入的日志文件进行操作时,如何不影响正在写入它的程序?这背后是 Linux 文件系统的inode机制在起作用。进程通过 inode(文件身份证号)操作文件,而非文件名。
logrotate 利用这一特性,提供两种主要方案:
方案一:Create 方案(默认)
这是 logrotate 的默认行为,流程如下:
- 重命名原日志文件(如
access.log→access.log.1)。由于重命名只修改目录项,不影响 inode,程序仍通过原 inode 继续写入 - 创建新日志文件:创建与原日志同名的新文件,获得新的 inode
- 通知程序重新打开日志:通过
postrotate脚本向应用程序发送信号(如向 nginx 发送USR1信号),应用程序重新根据文件名打开日志文件,此时打开的便是新文件,写入操作无缝切换
这种方式需要应用程序支持重新打开日志的机制,但最为安全可靠。
方案二:Copytruncate 方案
另一种方式是将当前日志内容复制作为备份,然后立即清空(截断)原日志文件。这种方式不需要程序配合重新打开文件,但有极小概率在复制和截断之间丢失日志数据,不推荐在高并发写入场景下使用。
四、配置的艺术:从全局到个体
logrotate 的强大源于其清晰的两层配置架构:
主配置文件 (/etc/logrotate.conf)
这是 logrotate 的”宪法”,定义全局默认策略。典型的全局配置包括:
weekly # 默认每周轮转
rotate 4 # 默认保留4份归档
compress # 默认启用压缩
missingok # 日志缺失时不报错
notifempty # 空日志不轮转
create 0644 root root
include /etc/logrotate.d # 引入应用配置目录
应用配置目录 (/etc/logrotate.d/)
这是 logrotate 配置的精华所在。/etc/logrotate.d/ 目录下的每一个文件,都像是为特定应用程序量身定制的”剧本”。当你通过 apt 安装 nginx、mysql、rsyslog 等软件时,它们通常会自动在这里创建配置文件,其中的指令会覆盖全局默认值。
以 /etc/logrotate.d/rsyslog 为例:
/var/log/syslog {
rotate 4
weekly
missingok
notifempty
compress
delaycompress
sharedscripts
postrotate
/usr/lib/rsyslog/rsyslog-rotate
endscript
}
核心参数详解
| 参数 | 含义 |
|---|---|
daily/weekly/monthly/yearly/hourly | 轮转周期 |
rotate N | 保留 N 份归档文件,超过则删除最旧的 |
compress | 使用 gzip 压缩归档文件 |
delaycompress | 推迟压缩,最新一份归档暂不压缩,便于快速查看 |
missingok | 日志文件不存在时忽略错误,继续执行 |
notifempty | 日志文件为空时不进行轮转 |
create MODE USER GROUP | 轮转后以指定权限创建新日志文件 |
size SIZE | 日志达到指定大小时触发轮转(与时间周期互斥) |
maxsize SIZE | 在时间周期内,若达到该大小则提前轮转 |
minsize SIZE | 需同时满足时间周期且达到该大小才轮转 |
postrotate ... endscript | 轮转完成后执行的脚本 |
sharedscripts | 所有日志处理完成后统一执行一次 postrotate,而非每个文件执行一次 |
五、日常工作流与调优
测试与调试
修改配置后,务必使用调试模式进行预演:
sudo logrotate -d /etc/logrotate.d/rsyslog
-d 参数会详细显示执行过程,但不会真正改动日志,用于排错和验证。
强制执行
确认无误后,可使用 -f 参数强制执行一次轮转:
sudo logrotate -f /etc/logrotate.d/rsyslog
查看状态
轮转状态记录在 /var/lib/logrotate/status 中,可查看各日志上次轮转时间:
cat /var/lib/logrotate/status | grep syslog
自定义执行频率
如果需要更精细的控制(如每小时轮转),可以在 /etc/cron.d/ 中创建自定义定时任务:
# 每小时执行一次 logrotate
0 * * * * root /usr/sbin/logrotate /etc/logrotate.conf
但需注意,如果配置了 hourly 周期,同一小时内多次执行不会重复轮转。
安全注意事项
logrotate 配置文件的权限和路径安全性至关重要。历史上曾存在因处理不可信路径而导致的本地提权漏洞(如 CVE-2011-1550),应确保配置文件目录的访问权限严格受控。
六、总结
logrotate 是 Ubuntu 系统中一位不可或缺的幕后功臣。它以标准化、高度可配置的方式,通过定时触发、条件判定、文件重命名与压缩、状态记录这一完整闭环,优雅地解决了日志管理中最枯燥但也至关重要的问题。无论是系统自带的 rsyslog,还是 nginx、apache2、MySQL 等应用服务,都通过 /etc/logrotate.d/ 中的配置文件与 logrotate 深度协作。理解其工作机理后,你便能从容地定制日志轮转策略,而不必担心日志文件在不经意间成为系统的”沉默杀手”。