一、logrotate简介
logrotate 是一个用于管理日志文件的工具,可以自动切割、压缩、删除旧的日志文件,并创建新的日志文件,从而节省系统磁盘空间。它通常基于 crontab 运行,默认配置文件位于 /etc/logrotate.conf,自定义配置文件放在 /etc/logrotate.d/ 目录下。
Linux系统默认安装logrotate工具。
二、logrotate相关文件
- 计划任务:/etc/cron.daily/logrotate
- 程序文件:/usr/sbin/logrotate
- 配置文件: /etc/logrotate.conf(全局定义)
- 模块配置目录:/etc/logtotate.d/(局部定义,局部定义覆盖全局定义)
- 日志文件:/var/lib/logrotate/logrotate.status
1、/etc/cron.daily/logrotate文件内容
#!/bin/sh
/usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
/usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit 0
2、/etc/logrotate.conf文件内容
# see "man logrotate" for details
# global options do not affect preceding include directives
# rotate log files weekly
weekly #默认轮转时间为7天
# keep 4 weeks worth of backlogs
rotate 4 #默认轮转四次
# create new (empty) log files after rotating old ones
create #日志轮转后创建空的日志文件
# use date as a suffix of the rotated file
dateext #轮转日志名后添加YYYYMMDD时间格式
# uncomment this if you want your log files compressed
#compress
# packages drop log rotation information into this directory
include /etc/logrotate.d #包含logrotate.d目录下的所有文件,也就是说,logrotate.d目录下的所有文件都会被执行(不要将文件备份到此目录下)
# system-specific logs may be also be configured here.
三、logrotate执行过程
执行过程引用的文章是:Linux logrotate执行流程分析 - 简书
简而言之就是系统执行/etc/cron.daily/
下的logrotate脚本
---> 执行logrotate
---> 根据/etc/logrotate.conf
配置执行/etc/logrotate.d/XXX
---> 转储XXX文件下的日志成功。
(logrotate /etc/logrotate.conf
)
四、logrotate常见参数
配置参数 说明
compress 通过gzip压缩转储以后的日志
nocompress 不压缩
copytruncate 用于还在打开中的日志文件,把当前日志备份并截断
nocopytruncate 备份日志文件但是不截断
create mode owner group 转储文件,使用指定的权限,所有者,所属组创建新的日志文件
nocreate 不建立新的日志文件
delaycompress 和 compress 一起使用时,转储的日志文件到下一次转储时才压缩
nodelaycompress 覆盖 delaycompress 选项,转储同时压缩
errors address 转储时的错误信息发送到指定的Email 地址
ifempty 即使是空文件也转储,此为默认选项
notifempty 如果是空文件的话,不转储
mail address 把转储的日志文件发送到指定的E-mail 地址
nomail 转储时不发送日志文件
olddir directory 转储后的日志文件放入指定目录,必须和当前日志文件在同一个文件系统
noolddir 转储后的日志文件和当前日志文件放在同一个目录下
prerotate/endscript 在转储以前需要执行的命令,这两个关键字必须单独成行
postrotate/endscript 在转储以后需要执行的命令,这两个关键字必须单独成行
daily 指定转储周期为每天
weekly 指定转储周期为每周
monthly 指定转储周期为每月
rotate count 指定日志文件删除之前转储的次数,0 指没有备份,5 指保留5 个备份
tabooext [+] list 让logrotate不转储指定扩展名的文件,缺省的扩展名是:.rpm-orig,.rpmsave, v, 和 ~
size size 当日志文件到达指定的大小时才转储,bytes(缺省)及KB或MB
sharedscripts 默认,对每个转储日志运行prerotate和postrotate脚本,日志文件的绝对路径作为第一个参数传递给脚本。 这意味着单个脚本可以针对与多个文件匹配的日志文件条目多次运行(例如/ var /log /news /*.example)。 如果指定此项sharedscripts,则无论有多少个日志与通配符模式匹配,脚本都只会运行一次
nosharedscripts 针对每一个转储的日志文件,都执行一次prerotate 和 postrotate脚本,此为默认值
missingok 如果日志不存在,不提示错误,继续处理下一个
nomissingok 如果日志不存在,提示错误,此为默认值
五、logrotate实战
- 系统环境:Red Hat 9.5
- logrotate版本:logrotate 3.18.0
1、案例一
要求:对/root下的test1.log文件每天进行转储压缩(如果test1.log文件为空,不进行转储),转储次数为三次,转储位置与日志同一目录下。
【案例搭建】
/etc/logrotate.d/test1文件如下设置,/etc/logrotate.conf文件不做修改,如上【二.2】所示:
(改回标准时间的命令是systemctl restart chronyd,如果系统是Rad Hat7之下,使用的命令是systemctl restart ntpd.)
/root/test1.log{
daily
missingok
rotate 3
compress
delaycompress
notifempty
create 640 root root
sharedscripts
postrotate
dd if=/dev/zero of=/root/test1.log bs=`date +%d`K count=1
echo `date +%Y%m%d` >> /root/test1.log
endscript
}
为了便于测试和查看结果,我们先在/root/下创建一个名为test1.log的文件,在文件中写【当日k】大小的文件并在文件最后一行写入日期,命令如下所示:
dd if=/dev/zero of=/root/test1.log bs="$(date +%d)"k count=1
echo "$(date +%Y%m%d)" >> test1.log
【案例测试】
测试方法:使用date命令修改系统时间,查看/root/下日志的生成情况。(注!:在生产环境下,不能修改系统时间,否则可能会影响到系统的正常运行、数据的一致性以及用户的使用体验。)
date -s "$(date -d 'tomorrow')"
【案例结果分析和改进】
在/etc/logrotate.d/test1文件中设置了daily参数,所以日志每天都会进行切割;compress和delaycompress参数组合使用,表示日志当天切割,第二天压缩,日志压缩类型为【gz】;rotate 3 表示保留三天的备份日志文件;postrotate和endscript组合参数内命令转储后执行,所以日志一直都有内容。
由于在logrotate.conf文件中,设置了【dateext】,所以轮转日志后缀会加上日期。logrotate切割日志通过cron调用且调用时间是凌晨,此时日志是前一天的内容,但是日志后缀时间格式是当天的,如下图所示。
为了解决这一问题我们可以在在logrotate.conf文件中【dateext】后面添加【dateyesterday】选项。
( linux日志默认存放在/var/log/目录下,为了便于查看测试结果,我才放在/root/目录下。)
2、案例二
要求:对/root/下的test1.log文件每天进行转储压缩(如果test1.log文件为空,不进行转储),转储次数为三次,转储位置存放在/data/下。
【案例搭建】
案例二依托于案例一,在/etc/logrotate.d/test1文件中添加一行【olddir /data/即可】,如下所示:
/root/test1.log{
daily
missingok
rotate 3
compress
delaycompress
notifempty
create 640 root root
olddir /data/
sharedscripts
postrotate
dd if=/dev/zero of=/root/test1.log bs=`date +%d`K count=1
echo `date +%Y%m%d` >> /root/test1.log
endscript
}
【案例测试】
测试方法(与案例一一样):使用date命令修改系统时间,查看/root/和/data/下日志的生成情况。(注!:在生产环境下,不能修改系统时间,否则可能会影响到系统的正常运行、数据的一致性以及用户的使用体验。)
date -s "$(date -d 'tomorrow')"
【案例结果分析】
当日志所在目录存储空间不足时,我们可以使用【olddir】参数将备份的日志文件迁移到指定目录,但是该目录必须与要转储的日志文件位于同一物理设备上。本次测试的服务器/data目录下没有挂载任何磁盘,所以测试是成功的。但是在生产环境中,/data*目录一般会挂载磁盘,此时/var/log/与/data*不是同一物理磁盘,olddir参数设置会失效并产生报错,如下所示:
使用如下命令查看块设备的详细信息:
lsblk -f
两个目录处于不同物理设备产生报错【error: /etc/logrotate.d/nginx:16 olddir /data/logs bak/nginxlog bak/ and log file /var/log/nginx/access.log are on different devices】
解决如上问题我们可以通过撰写脚本并设置定时任务,或者是直接修改日志的存储位置 。
六、故障排错
1、logrotate常见命令
我们可以通过如下命令对检查配置文件是否有语法错误:
logrotate -d /etc/logrotate.conf
logrotate -d /etc/logrotate.d/XXX
2、logrotate通过cron.daily调用,可以查看cron日志文件排查故障
cat /var/log/cron | grep cron.daily
参考文章:
logrotate自定义切割时间的一些坑 - 梦轻尘 - 博客园
Linux自带神器logrotate详解 - 详 - 博客园
如何在 logrotate 未正常运行时调试 logrotate 警告或错误 - Red Hat Customer Portal