如何在Linux中使用Logrotate设置和管理日志轮转
## 如何在Linux中使用Logrotate设置和管理日志轮转
在 Linux 系统中,`/var/log`是最值得关注(也是最重要)的目录之一。根据《文件系统层次结构标准》(FHS),系统内大多数服务的运行活动都会记录在此目录或其子目录下的文件中。
这些文件被称为**日志**,是分析系统运行状态(以及历史行为)的关键依据。当管理员或工程师排查故障时,日志往往是他们首要查阅的信息来源。
如果分别查看 `CentOS/RHEL/Fedora/Rocky Linux`和`Debian/Ubuntu`(以多发行版为例)的 `/var/log` 目录内容,通常会看到以下形式的日志文件及子目录:
**\# 在 RHEL/CentOS/Rocky Linux 和 Fedora 中:**
```
[root@localhost ~]# ls /var/log
anaconda chrony dnf.log.3 maillog pcp speech-dispatcher
atop cron dnf.rpm.log maillog-20250525 php-fpm spooler
audit cron-20250525 firewalld maillog-20250601 private spooler-20250525
boot.log cron-20250601 gdm maillog-20250608 qemu-ga spooler-20250601
boot.log-20250426 cron-20250608 hawkey.log maillog-20250615 README spooler-20250608
boot.log-20250511 cron-20250615 hawkey.log-20250525 mariadb samba spooler-20250615
boot.log-20250605 cups hawkey.log-20250601 messages secure sssd
boot.log-20250606 dnf.librepo.log hawkey.log-20250608 messages-20250525 secure-20250525 tallylog
btmp dnf.log hawkey.log-20250615 messages-20250601 secure-20250601 tuned
btmp-20250601 dnf.log.1 httpd messages-20250608 secure-20250608 wtmp
cacti dnf.log.2 lastlog messages-20250615 secure-20250615
[root@localhost ~]#
```
{.aligncenter}
**\# 在 Debian 和 Ubuntu 中:**
```
admin@debian:~$ ls /var/log
alternatives.log dmesg.4.gz mysql
alternatives.log.1 dpkg.log mysql.err
alternatives.log-2.gz dpkg.log.1 mysql.log
alternatives.log-3.gz dpkg.log.2.gz mysql.log.1.gz
apache2 dpkg.log.3.gz mysql.log.2.gz
apt dpkg.log.4.gz mysql.log.3.gz
aptitude exim4 mysql.log.4.gz
aptitude.1.gz faillog mysql.log.5.gz
aptitude.2.gz fontconfig.log news
aptitude.3.gz fsck popularity-contest
audit hp popularitycontest-.0
auth.log installer popularity-contest.1.gz
auth.log.1 kern.log popularity-contest.2.gz
auth.log.2.gz kern.log.1 popularity-contest.3.gz
auth.log.3.gz kern.log.2.gz popularity-contest.4.gz
auth.log.4.gz kern.log.3.gz popularity-contest.5.gz
```
在这两种情况下,我们可以观察到,有些日志文件名以预期的`log`结尾,而其他的要么被重命名为带有日期的名称(例如,在CentOS上的maillog-20250615),要么被压缩(考虑到Debian上的`auth.log.2.gz`和`mysql.log.1.gz`)。
这种设定并非发行版的默认行为,我们可以通过修改配置文件中的指令来进行调整。
如果日志无限累积,最终会占满 `/var/log` 所在的文件系统。为防止这种情况,系统管理员可以使用名为 **logrotate** 的工具定期清理日志。
简而言之,当满足特定条件时,`logrotate`会重命名或压缩主日志文件,确保后续事件记录到空白的新文件中。
此外,它还会删除"旧"日志文件,仅保留最新日志。
#### **1.在 Linux中安装Logrotate**
要安装 **logrotate**,只需使用包管理器:
```
---------- On Debian and Ubuntu ----------
## aptitude update && aptitude install logrotate
---------- On CentOS, RHEL and Fedora ----------
## yum update && yum install logrotate
```
```
[root@localhost ~]# yum update && yum install logrotate
上次元数据过期检查:4:05:45 前,执行于 2025年06月16日 星期一 04时55分05秒。
依赖关系解决。
=========================================================================================================================
软件包 架构 版本 仓库 大小
=========================================================================================================================
安装:
kernel x86_64 5.14.0-570.21.1.el9_6 baseos 1.8 M
升级:
dracut x86_64 057-88.git20250311.el9_6 baseos 385 k
…
```
```
[root@localhost ~]# logrotate -v
logrotate 3.18.0 - Copyright (C) 1995-2001 Red Hat, Inc.
This may be freely redistributed under the terms of the GNU General Public License
用法: logrotate [-dfv?] [-d|--debug] [-f|--force] [-m|--mail=command] [-s|--state=statefile] [--skip-state-lock]
[-v|--verbose] [-l|--log=logfile] [--version] [-?|--help] [--usage] [OPTION...]
[root@localhost ~]#
```
需要特别注意的是,主配置文件(`/etc/logrotate.conf`)可能会指定:更具体的配置可以放在`/etc/logrotate.d`目录下的各个`.conf`文件中。
**当且仅当**存在以下未注释的行时,才会启用该配置:
```
include /etc/logrotate.d
```
{.aligncenter}
#### **2.在 Linux中配置Logrotate**
作为一款功能强大的工具,logrotate提供了丰富的配置指令,让我们能够灵活设置日志轮转的时机、方式以及后续操作。
现在,在`/etc/logrotate.d/httpd.conf`文件中添加以下配置内容并逐行解析每个配置项的作用:
```
[root@localhost ~]# vim /etc/logrotate.d/httpd.conf
```
{.aligncenter}
首行配置表明该配置块内的指令适用于/var/log/httpd目录下的所有日志文件:
* **weekly**
表示日志将按周轮转(每周尝试执行一次)。其他可选值包括:`daily`(每日)、`monthly`(每月)
* **rotate 3**
仅保留**3份**历史日志。当第四次轮转发生时,最旧的日志文件将被删除。
* **size=10M**
设置触发轮转的**最小文件大小为10MB**。即:日志文件必须达到10MB才会被轮转。
* **compress**:启用压缩功能
* **delaycompress**:延迟压缩(**最新一份**历史日志保持未压缩状态,其余历史日志均压缩存储)
**\# 模拟运行测试**
可通过-d选项执行空跑测试(`dry-run`),预览实际执行时的操作(移除该选项则真正执行):
```
[root@localhost ~]# logrotate -d /etc/logrotate.d/httpd.conf
WARNING: logrotate in debug mode does nothing except printing debug messages! Consider using verbose mode (-v) instead if this is not what you want.
reading config file /etc/logrotate.d/httpd.conf
warning: 'size' overrides previously specified 'weekly'
Reading state from file: /var/lib/logrotate/logrotate.status
Allocating hash table for state file, size 64 entries
Creating new state
Creating new state
……
Handling 1 logs
rotating pattern: /var/log/httpd/* 10485760 bytes (3 rotations)
empty log files are rotated, old logs are removed
considering log /var/log/httpd/access_log
Now: 2025-06-16 09:33
Last rotated at 2025-06-08 00:00
log does not need rotating (log size is below the 'size' threshold)
considering log /var/log/httpd/access_log-20250608
Creating new state
Now: 2025-06-16 09:33
Last rotated at 2025-06-16 09:00
log does not need rotating (log size is below the 'size' threshold)
considering log /var/log/httpd/error_log
Now: 2025-06-16 09:33
Last rotated at 2025-06-15 00:00
log does not need rotating (log size is below the 'size' threshold)
considering log /var/log/httpd/error_log-20250608
Creating new state
Now: 2025-06-16 09:33
Last rotated at 2025-06-16 09:00
log does not need rotating (log size is below the 'size' threshold)
considering log /var/log/httpd/error_log-20250615
Creating new state
Now: 2025-06-16 09:33
Last rotated at 2025-06-16 09:00
log does not need rotating (log size is below the 'size' threshold)
[root@localhost ~]#
```
{.aligncenter}
如果不想压缩日志文件,我们可以通过 **dateext** 指令改用日期格式对轮转后的日志进行重命名。若需自定义日期格式(默认格式为`yyyymmdd`),还可配合 **dateformat** 指令进行指定。
通过`notifempty`指令可禁止对空日志文件执行轮转操作。此外,我们还可配置`logrotate`将轮转后的日志邮件发送给系统管理员(本文示例为netskyman@163.com)以供查阅。
下面我们将通过`/etc/logrotate.d/squid.conf` 文件,专门针对 `/var/log/squid/access.log`设置轮转规则:
```
[root@localhost logrotate.d]# pwd
/etc/logrotate.d
[root@localhost logrotate.d]# vim squid.conf
/var/log/squid/access.log {
monthly
create 0644 root root
rotate 5
size=1M
dateext
dateformat -%d%m%Y
notifempty
mail netskyman@163.com
}
```
{.aligncenter}
通过下图可见,当前日志尚未达到轮转条件。但当文件大小达到设定阈值(size=1M)时,系统将执行以下操作:
**\# 日志轮转处理**
* 当前活跃日志(access.log)将被重命名为带日期的历史日志(如:access.log-160062025,表示2025年6月16日轮转)
* 自动创建新的空日志文件(access.log)
* 新日志文件权限设置为0644(rw-r--r--)
* 新日志文件属主和属组均为root
**\# 历史日志管理**
* 当累计历史日志达到6份时(由rotate参数控制)
* 系统会自动将最旧的日志文件(即第7份日志)通过邮件发送至netskyman@163.com
```
[root@localhost ~]# logrotate -d /etc/logrotate.d/squid.conf
WARNING: logrotate in debug mode does nothing except printing debug messages! Consider using verbose mode (-v) instead if this is not what you want.
reading config file /etc/logrotate.d/squid.conf
warning: 'size' overrides previously specified 'monthly'
Reading state from file: /var/lib/logrotate/logrotate.status
Allocating hash table for state file, size 64 entries
Creating new state
Creating new state
Handling 1 logs
rotating pattern: /var/log/squid/access.log 1048576 bytes (5 rotations)
empty log files are not rotated, old logs mailed to netskyman@163.com
considering log /var/log/squid/access.log
Creating new state
Now: 2025-06-16 09:55
Last rotated at 2025-06-16 09:00
log does not need rotating (log size is below the 'size' threshold)
[root@localhost ~]#
```
{.aligncenter}
{.aligncenter}
假设希望在日志轮转时执行自定义命令,只需将该命令放置在 **postrotate** 和 **endscript** 指令之间即可实现。
例如,若要在`/var/log/myservice`目录下的任何日志发生轮转时向root用户发送邮件,只需在`/etc/logrotate.d/squid.conf`文件中添加以下红色标记的内容:
```
/var/log/myservice/* {
monthly
create 0644 root root
rotate 5
size=1M
postrotate
echo "A rotation just took place." | mail root
endscript
}
```
最后需要特别注意的是:当配置存在冲突时,`/etc/logrotate.d/*.conf` 中的选项会覆盖主配置文件中的设置。
#### **3.Logrotate与Cron的协作关系**
**1)默认安装行为**
* Logrotate 安装时会自动在 \*\*
```
/etc/cron.daily/
```
\*\* 目录下生成名为 `logrotate` 的定时任务文件。
* 与其他同目录下的 cron 任务类似:
* **若无 anacron**:每日 **6:25 AM** 自动执行
* **若启用 anacron**:执行时间推迟至约 **7:35 AM**
**2)执行时间验证方法**
检查以下文件中的 `cron.daily` 相关配置:
```
## 查看 crontab 配置(无 anacron 时生效)
grep cron.daily /etc/crontab
## 或查看 anacrontab 配置(使用 anacron 时生效)
grep cron.daily /etc/anacrontab
```
**3)关键说明**
* **优先级**:
anacron 的存在会覆盖传统cron的时间设定,适用于非 24 小时运行的服务器。
* **手动触发**:
如需立即测试,可直接运行:
```
/etc/cron.daily/logrotate
```
* **日志记录**:
执行结果通常记录在 `/var/log/cron` 或系统日志中。
#### **4.总结**
在需要管理大量日志的系统中,使用 **logrotate** 能大幅简化日志文件的管理工作,它能够根据预设周期或文件大小阈值,自动完成日志的**轮转、压缩、删除**及**邮件通知**等操作。
要实现自动化日志管理,只需确保通过 **cron 任务**定期运行`logrotate`即可。