正常运行的服务器每天都会产生大量的日志,如果长时间不清理,会导致磁盘使用率过载,严重的会影响IO密集型操作,比如数据库查询操作的性能。如果有一个监控磁盘使用率的脚本,当检测到磁盘使用率超过指定阈值后,就去清理日志文件,就可以避免这种情况。
该脚本基于磁盘利用率判断是否要删除指定目录下面的日志文件,如果磁盘利用率超过90%,将删除指定目录下所有的日志文件;超过80%,默认删除10天之前的日志文件。其中,磁盘利用率和删除文件的时间都可以配置。
在~/scripts目录下新建removeLog.sh文件,清理超期日志脚本removeLog.sh内容如下:
#!/bin/bash
#
#********************************************************************
#Author: freedom
#Date: 2022-09-08
#Description: 日志超期删除
#Version: v1
#********************************************************************
# 要清理日志的目录,默认将日志同步到该目录下面,没有该目录提前新建好,主要属主和属组为freedom,不要使用sudo mkdir命令,目录不要使用~有时会导致问题
# 使用方式,可以直接执行该脚本removeLog.sh,也可以指定要清理日志的路径,比如./removeLog.sh /home/freedom/synclog/logs
# getStrLen get input arg length
function getStrLen() {
str=$1
return ${#str}
}
# removeLogByTime 清理距现在多久之前生成的文件
function removeLogByTime() {
# 在指定日期列表中找到这个时间之前的文件,即为要清除的过期文件
for time in ${times[@]}
do
# 通过df命令过滤磁盘使用率那一列得到具体数值
freeRatio=`df | grep '/$'| awk '{print $(NF-1)}' | awk -F'%' '{print $1}'`
if ((freeRatio>=$diskUsed90)); then
echo "=============disk oversive $diskUsed90 ============" >> $logPath
removeFile $targetDir 0
elif ((freeRatio>$diskUsed80)); then
echo "=============disk oversive $diskUsed80 ============" >> $logPath
removeFile $targetDir $time
else
echo "============ normal ===========" >> $logPath
echo "未超过设定的磁盘利用率的最低阈值$diskUsed80,暂不清理,当前$(date "+%Y-%m-%d %H:%M:%S")剩余磁盘空间$freeRatio%" >> $logPath
break
fi
done
}
# removeFile 清理指定目录targetDir的文件,$2传入距现在多久之前的文件,0表示删除targetDir目录下所有的文件
function removeFile() {
targetDir=$1
timeLimit=$2
echo "开始清理之前,$(date "+%Y-%m-%d %H:%M:%S")磁盘使用率剩余$freeRatio%" >> $logPath
if [ ! -d "$targetDir" ]
then
echo "想要清理的日志目录$targetDir不存在,脚本将要退出" >> $logPath
return 1
fi
# 没有超期时间,过滤出该目录targetDir下所有文件并删除;否则,只擅长超期文件
if [ ${timeLimit} -le 0 ]
then
clearFiles=$(find $targetDir -type f | xargs)
echo "timeLimit=$timeLimit <=0,将要删除$targetDir目录下所有文件" >> $logPath
else
clearFiles=$(find $targetDir -type f -cmin +$timeLimit | xargs)
echo "timeLimit=$timeLimit >0,将要删除$timeLimit分钟之前创建的文件" >> $logPath
fi
if [ ${#clearFiles} -le 0 ]
then
echo "当前目录$targetDir没有超期$(expr $timeLimit / 1440)天的文件" >> $logPath
return 2
fi
echo "$(date "+%Y-%m-%d %H:%M:%S"),将要清理的文件有:${clearFiles[@]}" >> $logPath
# 清理targetDir目录下所有的文件,只需timeLimit=0
`find $targetDir -type f -cmin +$timeLimit | xargs rm -f`
if [ $? -ne 0 ]
then
echo "$(date "+%Y-%m-%d %H:%M:%S"),清理文件:find $targetDir -type f -cmin +$timeLimit | xargs 失败" >> $logPath
fi
echo "清理距离现在$(expr $timeLimit / 1440)天数据后,$(date "+%Y-%m-%d %H:%M:%S")剩余磁盘空间$freeRatio%" >> $logPath
}
# ============== var ==============
set -o nounset
# 默认指定删除的文件的目标目录
defaultDir="$HOME/rsynclogs"
# 获取将要清理日志所在的目录,可以从输入参数中获取,无输入使用默认目录,自定义目录清理有风险,改成清理固定目录
# getStrLen $1
# # 判断脚本是否带有目录参数,如果不带参数,使用存放日志的默认路径
# if [[ $? -le 0 ]]; then
# # targetDir="/var/log/a4stack/erms"
# targetDir=$defaultDir
# # 如果脚本带有路径参数,判断该参数指定目录是否存在
# elif [ -d "$1" ]; then
# targetDir=$1
# else
# echo "想要清理的目标日志目录$logDir不存在,请检查,清理程序将退出!" >> $logPath
# exit 1
# fi
targetDir=$defaultDir
# 清理过程产生日志的目录
logDir="/tmp"
# 清理日志的目录不存在则创建,并赋予权限
if [ ! -d $logDir ]; then
mkdir -p logDir
chown $USER.$USER -R $logDir
chmod 755 -R $logDir
fi
# 清理过期文件日志
logFile="clear.txt"
# 记录清理过程产生日志的路径
logPath="$logDir/$logFile"
if [ ! -f $logPath ]; then
touch $logPath
fi
# 磁盘使用率,超过该值时开始清理日志,该数值可以修改,修改后记得重启脚本
diskUsed80=80
# 磁盘使用率超过80%,清理10天之前的文件;超过90%,清理$HOME/synclog目录下所有文件
diskUsed90=90
# 时间单位:分钟,14400分钟=10天,默认清理10天及之前的文件
times=("14400")
echo "$(date "+%Y-%m-%d %H:%M:%S") start, clear distination dir=$targetDir, log record path=$logPath" >> $logPath
removeLogByTime
想要修改磁盘利用率,可以调整diskUsed80和diskUsed90两个变量的值,diskUsed80表示,当磁盘使用率达到80时,清除/rsynclogs目录下超过times(默认10天)的文件;diskUsed90表示,当磁盘利用率达到90时,清除/rsynclogs目录下所有同步的文件。
times数组表示要清理多久之前的文件,单位为分钟,默认是1440分钟,当磁盘利用率超过diskUsed80时,才会清除times之前的文件。
如何才能将上面清理日志的脚本定时执行呢?可以使用crontab。
crondtab是Linux系统中用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,crondtab进程每分钟会定期检查是否有要执行的任务,如果有要执行的任务,则自动执行该任务。
将上面的脚本clear.sh脚本通过“crontab -e” 添加到定时任务中,清理日志的脚本即可在后台定时清理。
crontab -e
第一次编辑cron作业的时候,需要选择相应的编辑器,如nano、vim.basic,选择后才可以配置新的cron作业,一般选择2,即使用vim.basic编辑器编辑crontab作业。crontab的默认编辑器是nano,不方面使用。下面,是通过select-editor命令修改crontab的默认编辑器为vim.basic。
freedom@freedom:~$ select-editor
Select an editor. To change later, run 'select-editor'.
1. /bin/nano <---- easiest
2. /usr/bin/vim.basic
3. /usr/bin/vim.tiny
4. /bin/ed
Choose 1-4 [1]: 2
然后编辑crontab定时作业。下面的命令是每5分钟执行一次清理日志的脚本,并将执行日志追加到cron.log文件中。
*/5 * * * * /home/freedom/scripts/removeLog.sh >> /tmp/cron.log 2>&1
使用下面的命令,可以移除之前编辑的cron定时作业。
crontab -r
cron服务设置相关命令:
service crond start //启动服务
service crond stop //关闭服务
service crond restart //重启服务
service crond reload //重新载入配置
service crond status //查看crontab服务状态
PS:新创建的cron作业,并不会立马执行,至少需要2分钟才会执行,如果重启cron服务,则会马上执行。
crontab -l:显示当前用户处于执行中的crontab文件内容。
freedom@freedom:~/scripts$ crontab -l
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
*/5 * * * * /home/freedom/scripts/removeLog.sh >> /tmp/cron.log 2>&1
可以看到,上面crontab执行计划是每5分钟执行一次删除日志的脚本removeLog.sh。删除文件过程产生的日志在/tmp/clear.txt文件中,可以通过 cat /tmp/clear.txt查看。
下面是将磁盘使用率设置为70(diskUsed80=70)时查看的清理日志:
2022-05-20 11:05:01 start, clear distination dir=/tmp/clear.txt, log record path=/tmp/clear.txt
=============disk oversive 70 ============
开始清理之前,2022-05-20 11:05:01磁盘使用率剩余80%
timeLimit=1000 >0,将要删除1000分钟之前创建的文件
2022-05-20 11:05:01,将要清理的文件有:/home/freedom/rsynclogs/36/a4stack/erms-mp-poller/normal.log /home/freedom/rsynclogs/36/a4stack/erms-api/access.log.2022-04-21.0.gz /home/freedom/rsynclogs/36/a4stack/erms-api/normal.log.2022-04-21.0.gz /home/freedom/rsynclogs/36/a4stack/erms-api/normal.log.2022-04-25.0.gz /home/freedom/rsynclogs/36/a4stack/erms-api/normal.log
/home/freedom/rsynclogs/36/a4stack/erms-api/access.log.2022-04-26.0.gz
......
/home/freedom/rsynclogs/36/a4stack/erms-schedule-manager/normal.log.2022-04-22.0.gz
清理距离现在0天数据后,2022-05-20 11:05:01剩余磁盘空间80%
2022-05-20 11:10:01 start, clear distination dir=/tmp/clear.txt, log record path=/tmp/clear.txt
=============disk oversive 70 ============
开始清理之前,2022-05-20 11:10:01磁盘使用率剩余79%
timeLimit=1000 >0,将要删除1000分钟之前创建的文件
当前目录/home/freedom/rsynclogs没有超期0天的文件
2022-05-20 11:15:01 start, clear distination dir=/tmp/clear.txt, log record path=/tmp/clear.txt
=============disk oversive 70 ============
开始清理之前,2022-05-20 11:15:01磁盘使用率剩余79%
timeLimit=1000 >0,将要删除1000分钟之前创建的文件
当前目录/home/freedom/rsynclogs没有超期0天的文件
2022-05-20 11:20:01 start, clear distination dir=/tmp/clear.txt, log record path=/tmp/clear.txt
=============disk oversive 70 ============
开始清理之前,2022-05-20 11:20:01磁盘使用率剩余79%
timeLimit=1000 >0,将要删除1000分钟之前创建的文件
当前目录/home/freedom/rsynclogs没有超期0天的文件
2022-05-20 11:25:01 start, clear distination dir=/tmp/clear.txt, log record path=/tmp/clear.txt
=============disk oversive 70 ============
开始清理之前,2022-05-20 11:25:01磁盘使用率剩余79%
timeLimit=1000 >0,将要删除1000分钟之前创建的文件
当前目录/home/freedom/rsynclogs没有超期0天的文件
2022-05-20 11:30:02 start, clear distination dir=/tmp/clear.txt, log record path=/tmp/clear.txt
=============disk oversive 70 ============
开始清理之前,2022-05-20 11:30:02磁盘使用率剩余79%
timeLimit=1000 >0,将要删除1000分钟之前创建的文件
当前目录/home/freedom/rsynclogs没有超期0天的文件
2022-05-20 11:35:01 start, clear distination dir=/tmp/clear.txt, log record path=/tmp/clear.txt
=============disk oversive 70 ============
开始清理之前,2022-05-20 11:35:01磁盘使用率剩余80%
timeLimit=1000 >0,将要删除1000分钟之前创建的文件
当前目录/home/ld/rsynclogs没有超期0天的文件
2022-05-20 11:40:01 start, clear distination dir=/tmp/clear.txt, log record path=/tmp/clear.txt