文章目录
- 日志文件的轮循(logrotate)
- 轮循基本原理
- 轮循的基本配置
- 实际测试logrotate的操作
- 使用案例
- 自定义日志文件的轮循功能
日志文件的轮循(logrotate)
日志轮循(logrotate)是一种用于管理日志文件的工具,它可以帮助我们自动地对日志文件进行切割、压缩、删除等操作,以便于节省磁盘空间和方便日志文件的管理。下面是日志轮循的一些详细介绍:
轮循基本原理
日志文件在不断地记录信息,如果不对它进行处理,它会越来越大,最终可能会占满磁盘空间。而轮循的基本原理就是在某个时刻对日志文件进行切割,将已经记录的信息保存到一个新的文件中,同时将旧的日志文件进行压缩或删除。这样,就可以保留一定的日志信息,同时也不会浪费过多的磁盘空间。
它的执行结构有点类似下图
由上图图例我们可以清除地知道,第一次执行时,原本的日志文件会被备份并重命名为messages.1,然后新建一个空的messages文件来存储日志。第二次执行时,messages.1会被备份并重命名为messages.2,messages会被重命名为messages.1,然后新建一个空的messages文件来存储日志。如果设置了保留三个日志文件,那么第四次执行时,最老的日志文件messages.3会被删除并由新的日志文件替换。
最近的日志文件轮循后的文件名已经会加上日期参数并保留在系统中,以避免数据丢失。
轮循的基本配置
多久进行一次这样的轮循任务可以在logrotate.conf文件中找到。
[root@localhost ~]# vim /etc/logrotate.conf
# 下面的设置是"logrotate"的默认设置值,如果个别的文件设置了其他的参数
# 则将以个别的文件设置为主,若该文件没有设置到的参数则以这个文件的内容为默认值。
weekly <== 默认每个星期对该日志文件进行一次轮循的任务
rotate 4 <== 保留几个日志文件,默认是保留4个1
create <== 由于日志文件被更名,因此建立一个新的来继续存储的意思
dateext <== 就是这个设置值,可以让被轮循的文件名称加上日期。
#compress <== 被修改的日志文件是否需要压缩,若干日志文件太大则可考虑使用此参数
include /etc/logrotate.d
# 将 /etc/logrotate.d/ 这个目录中的所有文件都读进来执行轮循的任务。
/var/log/wtmp { <== 仅针对/var/log/wtmp所设置值
monthly <== 每个月一次,替换每周
create 0664 root utmp <== 指定新建文件的权限与所属账号/组
minsize 1M <== 文件容量一定要超过 1M后才进行轮循(略过时间参数)
rotate 1 <== 仅保留一个,就是仅又wtmp.1保留而已。
}
# 这个wtmp可记录登录者与系统重新启动时的时间与来源主机及登录期间的时间
# 由于具有 minsize 的参数,因此不见得每个月一定会进行一次,要看文件容量。
# 由于仅保留一个日志文件而已,不满意的话可以将它改成 rotate 5。
由这个文件设置我们可以知道/etc/logrotate.d实际上是由/etc/logrotate.conf规划出来的目录。虽然可以把所有数据都写入/etc/logrotate.conf,但是这个文件会非常复杂,不方便维护。所以,将每个服务的日志文件轮循设置独立出来,作为一个文件放置在/etc/logrotate.d/中是一种方便且合理的做法。默认的轮循状态在/etc/logrotate.conf中设置,但各个服务可以自己设置自己的日志文件轮循。
例如,可以将rotate 4修改为rotate 9,保存更多的备份文件;对于占用硬盘空间较多的httpd等服务,可以考虑压缩日志文件。
上面介绍了 /var/log/wtmp 这个文件的设置,logrotate.conf 的设置语法为:
日志文件的绝对路径与文件名 ...{
个别的参数设置值,如monthly,compress等
}
下面我们再以 /etc/logrotate.d/syslog 这个轮循rsyslog.service 服务的文件,来看看该如何设置它的轮循?
/var/log/cron
/var/log/maillog
/var/log/messages
/var/log/secure
/var/log/spooler
{
missingok
sharedscripts
postrotate
/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
endscript
}
在上面的语法当中,我们知道正确的logrotate的写法为:
-
文件名:被处理的日志文件绝对路径文件名写在前面,可以使用空格符分隔多个日志文件
-
参数:上述文件名进行轮循的参数使用{}包括起来
-
执行脚本:可调用外部命令来进行额外的命令执行,这个设置于sharedscripts…endscript 设置合用才行。至于可用的环境为:
- prerotate:在启动logrotate 之前进行的命令,例如修改日志文件的属性等操作
- postrotate:在做完logrotate 之后启动的命令,例如重新启动(kill -HUP)某个服务
- Prerotate与prstrotate对于已经加上特殊属性的文件处理上面,是相当重要的执行程序
那么 /etc/logrotate.d/syslog 内设置的5个文件轮循功能就变成了:
-
该设置只对 /var/log/ 内的 cron、maillog、messages、secure、spooler有效
-
日志文件轮循每周一次,保留4个且轮循下来的日志文件不进行压缩(未更改默认值)
-
轮循完毕后(postrotate)取得syslog的PID后,以 kill -HUP重新启动syslogd
假设我们有针对 /var/log/messages 这个文件增加 chattr +a 属性时,依据logrotate的工作原理,我们知道,这个/var/log/messages 将会被更名未 /var/log/messages.1。但是由于加上这个 +a 的参数,所以更名是不可能成功的。那怎么办呢?就利用prerotate与postrotate来进行日志文件轮循前、后所需要做的操作。那么你可以这样修改一下文件
[root@localhost ~]# vim /etc/logrotate.d/syslog
/var/log/cron
/var/log/maillog
/var/log/messages
/var/log/secure
/var/log/spooler
{
sharedscripts
prerotate
/usr/bin/chattr -a /var/log/messages
endscript
sharedscripts
postrotate
/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
/usr/bin/chattr +a /var/log/messages
endscript
}
大概流程就是先给它去掉a 这个属性,让日志文件/var/log/messages 可以进行轮循操作。然后执行了轮循之后,再给他加入这个属性。
/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true解释:
第一部分 /bin/kill -HUPcat /var/run/syslogd.pid 2> /dev/null 表示发送 HUP 信号给进程号为 /var/run/syslogd.pid
的进程,即重启 syslogd 进程。
具体而言,这个命令会先使用 cat
命令读取 /var/run/syslogd.pid
文件中的进程号,然后将进程号传递给 /bin/kill
命令,发送 HUP 信号给该进程。2> /dev/null
表示将标准错误输出重定向到空设备,以防止错误信息被显示出来。如果 cat
命令或 /bin/kill
命令执行出错,进程号不存在或进程已经退出等情况,这个命令不会输出任何错误信息。
第二部分 2> /dev/null || true
表示将标准错误输出重定向到空设备,如果命令执行出错,返回值为非零值,会执行 true
命令,也就是不做任何处理,返回值为零。
这个命令的作用是确保即使重启 syslogd 进程出现错误,也不会导致整个脚本执行失败。
实际测试logrotate的操作
在Linux系统中,我们可以通过手动执行logrotate命令来对日志文件进行轮循。
logrotate [-vf] logfile
选项:
-v:启动显示模式,会显示logrotate运行的过程
-f:不论是否符合配置文件的数据,强制每个日志文件都进行轮循的操作。
使用案例
执行一次logrotate看看整个流程是什么?
[root@localhost ~]# logrotate -v /etc/logrotate.conf
reading config file /etc/logrotate.conf # 表示正在读取这个主配置文件;
including /etc/logrotate.d # 正在读取目录下的配置文件
reading config file bootlog # 正在读取目录下的bootlog配置文件
reading config file chrony # 正在读取目录下的chrony配置文件
......
......
......
Handling 8 logs # 共有18个日志文件被记录
......
......
......
rotating pattern: /var/log/cron
/var/log/maillog
/var/log/messages
/var/log/secure
/var/log/spooler
weekly (4 rotations)
empty log files are rotated, old logs are removed
considering log /var/log/cron
log does not need rotating (log has been already rotated)considering log /var/log/maillog
log does not need rotating (log has been already rotated)considering log /var/log/messages
log does not need rotating (log has been already rotated)considering log /var/log/secure
log does not need rotating (log has been already rotated)considering log
......
......
......
强制进行logrotate的操作
[root@localhost ~]# logrotate -vf /etc/logrotate.conf
......
......
......
rotating log /var/log/messages, log->rotateCount is 4
dateext suffix '-20230518'
glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
glob finding old rotated logs failed
......
......
# 看到了吗?整个轮循的操作就是这样一步一步进行的
[root@localhost ~]# ll /var/log/messages* ; lsattr /var/log/messages
-rw-------. 1 root root 155 5月 18 23:19 /var/log/messages
-rw-------. 1 root root 488944 5月 18 23:11 /var/log/messages-20230518
-----a---------- /var/log/messages
# 主动加入a的隐藏属性
上面哪个-f具有【强制执行】的意思,如果一切的设置都没有问题的话,那么理论上,你的 /var/log 这个目录就会起变化,而且应该不会出现错误信息才对。
下面再做一些例题练习,更详细的了解logrotate功能
自定义日志文件的轮循功能
如果你想要将【所有的信息】都额外写入到/var/log/admin.log
应该怎么配置?这个文件时现在,你想要将该文件加上 +a 这个隐藏属性,而且设置下面相关信息
- 日志文件轮循一个进行一次
- 该日志文件若大于 10MB时,则主动进行轮循,不需要考虑一个月的期限
- 保存5个备份文件
- 备份文件需要压缩
应该怎么设置呢?
- 先设置好所需要添加的参数
[root@localhost ~]# vim /etc/rsyslog.conf
# Add by localhost 2023/5/17 # 自己修改时加入一些说明
*.info /var/log/admin.log
- 重启rsyslog.server
[root@localhost ~]# systemctl restart rsyslog.service
[root@localhost ~]# ll /var/log/admin.log
-rw-------. 1 root root 816 5月 17 10:18 /var/log/admin.log
# 可以看到已经建立了日志文件
# 如此一来。所有信息都会写入 admin.log
- 先增加 +a 这个属性
[root@localhost ~]# chattr +a /var/log/admin.log
[root@localhost ~]# lsattr /var/log/admin.log
-----a---------- /var/log/admin.log
[root@localhost ~]# mv /var/log/admin.log /var/log/admin.log.1
mv: 无法将"/var/log/admin.log" 移动至"/var/log/admin.log.1": 不允许的操作
# 这里确定了加入a的隐藏属性,所以root无法移动此日志文件
- 开始建立logrotate的配置文件,增加一个文件到/etc/logrotate.d 目录就对了
[root@localhost ~]# vim /etc/logrotate.d/admin
/var/log/admin.log {
monthly
size=10M
rotate 5
compress
sharedscripts
prerotate
/usr/bin/chattr -a /var/log/admin.log
endscript
sharedscripts
postrotate
/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
/usr/bin/chattr +a /var/log/admin.log
endscript
}
- 测试一下logrotate相关功能的显示信息
[root@localhost ~]# logrotate -v /etc/logrotate.conf
.......
.......
rotating pattern: /var/log/admin.log 10485760 bytes (5 rotations)
empty log files are rotated, old logs are removed
considering log /var/log/admin.log
log does not need rotating (log size is below the 'size' threshold)
not running prerotate script, since no logs will be rotated
not running postrotate script, since no logs were rotated
......
......
# 因为不足一个月,文件也没有大于10MB,所以不需要轮循
- 测试一下强制 logrotate 与相关功能的显示
[root@localhost ~]# logrotate -vf /etc/logrotate.conf
[root@localhost ~]# lsattr /var/log/admin.log*
-----a---------- /var/log/admin.log
---------------- /var/log/admin.log-20230518.gz
看到了吗?通过这个方式,我们就可以建立起属于自己的logrotate配置文件,很简单方便。尤其要注意/etc/rsyslog.conf 与/etc/logrotate.d/* 文件常常要配合起来一起使用。