Linux日志切割
1. 建立脚本文件
mkdir -p /app/script/log_clean
vi /app/script/log_clean/log_clean.sh
2. 脚本内容
#!/bin/sh
#日志压缩清理脚本,本脚本对指定目录文件进行压缩、清理,支持超过指定大小清理,超过指定日期清理。
#========================自定义配置==============================
#配置格式:定义log_conf数组,数组的第一个值为:日志目录;第二个为:匹配日志文件;第三个为:日志过期时间,操作过期时间则进行删除;第四个为:最大存储大小,超过则会进行删除;第五个为:不压缩最近几个日志,第六个为:是否进行切割,切割则填写c,否则填写f,第七个为:切割的文件名
log_conf[0]=""/opt/lingmou/capture-server-exception/logs/" "*.zip.*" "7" 100 10" #表示清理/opt/lingmou/capture-server-exception/logs/目录下匹配为*.zip.*的日志文件,最长保留日期为7天,最大存储为100G,不压缩最近10个日志(方便查看)
log_conf[1]=""/opt/nginx/logs/" "configcenter.private.access.log.202*" "7" 10 2 c "configcenter.private.access.log"" #表示清理opt/nginx/logs/目录下匹配为configcenter.private.access.log.202*的日志文件,最长保留日期为7天,最大存储10G,不压缩最近2个日志,进行切割日志,切割的日志文件为configcenter.private.access.log
script_log="log.log" #[必填]当前脚本日志存储路径,默认为当前目录的log.log文件
#========================程序====================================
cd $(cd `dirname $0`; pwd) #切换到脚本运行目录
log_clean_check="$1"
log_name="清理日志" #填写日志脚本名称,以方便能在日志文件里面快速查找到
run() {
for log_conf_str in "${log_conf[@]}"; do
log_conf_file_path=$(echo "${log_conf_str}" | awk '{print $1}')
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 开始处理:${log_conf_str}" | tee -a ${script_log}
if [[ -d $log_conf_file_path ]]; then
log_conf_file_path_list=$(find ${log_conf_file_path} -maxdepth 0 -type d)
while read line; do
log_conf_str2=$(echo "${log_conf_str}" | awk '{$1="";print $0}')
log_conf_str2=$(echo "${line}${log_conf_str2}")
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 开始处理日志文件:${log_conf_str2}" | tee -a ${script_log}
Start ${log_conf_str2}
done <<<"$log_conf_file_path_list"
else
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 处理完成,目录:${log_conf_file_path} 不存在,不进行处理!" | tee -a ${script_log}
fi
done
}
#启动判断程序
Start() {
log_path="$1"
log_key="$2"
log_overdue="$3"
log_max="$4"
log_nogzip="$5"
log_cutting="$6"
log_cut="$7"
#判断是否需要切割日志
if [[ $log_cutting = "c" ]]; then
if [[ -n $log_cut ]]; then
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 切割日志启动" | tee -a ${script_log}
cut_logs
fi
fi
#启动过期日志判断
if [[ -n $log_overdue && $log_overdue != "-1" ]]; then
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 限制日期模式启动" | tee -a ${script_log}
clean_overdue
fi
#判断是否需要压缩日志
if [[ -n $log_nogzip && $log_nogzip != "-1" ]]; then
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 压缩日志启动" | tee -a ${script_log}
if [ ! -d $log_bak ]; then
mkdir -p $log_bak
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 创建备份目录:$log_bak" | tee -a ${script_log}
fi
gzip_logs
fi
#清除操作指定大小文件
if [[ -n $log_max && $log_max != "-1" ]]; then
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 限制文件大小模式启动" | tee -a ${script_log}
clean_max
fi
}
#切割日志
cut_logs() {
log_filepath="${log_path}${log_cut}"
log_newpath="${log_filepath}.$(date -d "yesterday" +"%Y-%m-%d")"
while :; do
if [ ! -f $log_newpath ]; then
break
else
i=$(expr $i + 1)
log_newpath="${log_filepath}.$(date -d "yesterday" +"%Y-%m-%d").${i}"
fi
done
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 将${log_filepath}复制为${log_newpath}"
if [[ "${log_clean_check}t" != "tt" ]]; then
if [[ -f ${log_filepath} ]]; then
cp -fpb ${log_filepath} ${log_newpath}
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 复制完成" | tee -a ${script_log}
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 清空${log_filepath}日志" | tee -a ${script_log}
: >${log_filepath}
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 日志切割完成" | tee -a ${script_log}
else
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 文件${log_filepath}不存在不进行处理" | tee -a ${script_log}
fi
fi
}
#压缩日志
gzip_logs() {
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 压缩目录:$log_path 匹配文件:$log_key 不压缩个数:$log_nogzip" | tee -a ${script_log}
filelist=$(find ${log_path} -name "${log_key}" | xargs ls -tr | grep ${log_path} | grep -v gz | tac | sed "1,${log_nogzip}d" | tac)
for line in $filelist; do
log_bak="${line%/*}/bak"
if [[ ! -d $log_bak ]]; then
mkdir -p $log_bak
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 创建备份目录:$log_bak" | tee -a ${script_log}
fi
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 开始压缩$line" | tee -a ${script_log}
if [[ "${log_clean_check}t" != "tt" ]]; then
if [[ -f ${line} ]]; then
gzip_size=$(gzip -9 $line)
else
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 文件${line}不存在不进行处理" | tee -a ${script_log}
fi
fi
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 压缩完成$line" | tee -a ${script_log}
line="${line}.gz"
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 开始移动压缩文件$line" | tee -a ${script_log}
if [[ "${log_clean_check}t" != "tt" ]]; then
if [[ -f ${line} ]]; then
mv $line $log_bak
else
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 文件${line}不存在不进行处理" | tee -a ${script_log}
fi
fi
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 移动压缩文件完成$log_bak" | tee -a ${script_log}
done
}
#清理:日期模式
clean_overdue() {
if [[ "${log_clean_check}t" != "tt" ]]; then
logs=$(find ${log_path} -mtime +${log_overdue} -name "${log_key}" | xargs rm -f) #清理日志
else
logs=$(find ${log_path} -mtime +${log_overdue} -name "${log_key}") #清理日志
echo "${logs}" | tee -a ${script_log}
fi
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 清理超过${log_overdue}天的日志完成" | tee -a ${script_log}
}
#清理:最大文件模式
clean_max() {
filelist=$(find ${log_path} -name "${log_key}" | xargs ls -tr | grep ${log_path})
filelist_count=$(echo "${filelist}" | wc -l)
i=0
for line in $filelist; do
i=$(expr ${i} + 1)
nowsize=$(find ${log_path} -name "${log_key}" | xargs du -cm | tail -1 | awk '{print $1/1024}')
if [[ $(echo "$nowsize > $log_max"|bc) -eq 1 ]]; then
if [[ $i -eq $filelist_count ]]; then
echo "" >$line
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 超过最大内存,当前:${nowsize}G,限制:${log_max}G,置空清理:${line}" | tee -a ${script_log}
else
logs=$(echo $line | xargs rm -f) #清理日志
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 超过最大内存,当前:${nowsize}G,限制:${log_max}G,清理:${line}" | tee -a ${script_log}
fi
else
echo "$(date "+%Y-%m-%d %H:%M:%S") [$log_name] 未超过最大内存,当前:${nowsize}G,限制:${log_max}G,不需要清理" | tee -a ${script_log}
break
fi
done
}
run
3. 给予可执行权限
chmod a+x /app/script/log_clean/log_clean.sh
4. 加入定时任务
echo "00 03 * * * root bash /app/scripts/log_clean/log_clean.sh >/dev/null 2>&1" >/etc/cron.d/log_clean