随着业务增长,日志量不断加大,清理日志成为定期的日常任务,本节所提供的shell脚本配合crontab可实现对日志的定时清理及压缩存储,内置参数配置及运行参数,能满足常用的日志清理场景需求。(日志文件的格式请参考本博客之前golang环境下的日志记录器-系列)
推荐的crontab指令:
* 10 * * 1 sh /data/web/xxxxx/crontab.sh run > /data/web/xxxxx/crontab.txt如上配置需将本脚本放置于/data/web/xxxxx目录下,具体使用时请自行调整
使用时需要配置:
DEL_FILE_RET,保留当前日志前最近多久的日志文件
FILE_DIR,日志文件的存放路径
FILE_DIR_BACK,日志压缩存储的存放路径
FILE_HEAD,日志文件头,多类日志文件空格分割,如本节示例request,实际存储文件名形如request.log.2017-xx-xx
FILE_TAIL,日志文件后缀,多类空格分割,如本节示例log
运行参数:
clear 清理文件,可单独使用,运行仅清理文件,不进行压缩存储
backup 压缩存储文件,可单独使用,运行仅压缩文件,及清理历史的压缩文件
run 先清理需要删除的文件,并将保留文件压缩存储,可视为clear和backup指令的结合
#!/bin/bash #@description 定时任务,以当前系统时间为基准,向前搜索DEL_FILE_NUM个文件,跳过最近DEL_FILE_RET个文件 #* 10 * * 1 sh /data/web/xxxxx/crontab.sh run > /data/web/xxxxx/crontab.txt #@author chenbintao #@data 2017-07-10 10:22 0.0.1 初稿 # 2017-07-10 21:31 0.0.9 增加日志打印方法 # 2017-07-11 21:31 0.1.0 修改压缩文件带路径的问题 # # VERSION=0.1.0 #版本 DEL_FILE_NUM=32 #删除文件数(总共的删除文件数) DEL_FILE_RET=3 #保留文件间隔(当前时间多久不被删除) FILE_DIR=/data/web/xxxxx/logs/ #文件目录 FILE_DIR_BACK=/data/web/xxxxx/logs/backup/ #文件目录 FILE_HEAD=(request response) #文件名称 FILE_TAIL=(log) #文件后缀 FILE_TAR=tar #压缩文件后缀 PAR_TEST=test #测试模式参数 PAR_CLEAR=clear #清理文件 PAR_BACKUP=backup #备份文件 PAR_RUN=run #正式运行 # # # #方法集 function ifo(){ echo "=======================================文件清理/备份任务脚本 V${VERSION}($0)=======================================" echo "---0.模式选择(test:生成测试,run:正式运行(清理&备份),clear:清理文件,backup:备份文件)" echo "---1.生成工具目录" echo "---2.清理历史文件" } function clear(){ echo "2.清理非保留原始/压缩文件" for((i=${DEL_FILE_RET}+1;i<=${DEL_FILE_NUM};i++));do #计算时间 file_date=`date -d -${i}day +%F` #遍历文件头列表 for j in ${FILE_HEAD[@]}; do #遍历文件后缀列表 for k in ${FILE_TAIL[@]}; do #组装文件名 file_name=${j}.${k}.${file_date} #删除原始文件 cd ${FILE_DIR} if [ ! -f "${FILE_DIR}${file_name}" ]; then println '不存在文件:'${FILE_DIR}${file_name} else println '删除文件:'${FILE_DIR}${file_name} rm -rf ${FILE_DIR}${file_name} fi #删除压缩文件 cd ${FILE_DIR_BACK} tar_flie_name=${file_name}.${FILE_TAR} if [ ! -f "${FILE_DIR_BACK}${tar_flie_name}" ]; then println '不存在文件:'"${FILE_DIR_BACK}${tar_flie_name}" else println '删除文件:'"${FILE_DIR_BACK}${tar_flie_name}" rm -rf "${FILE_DIR_BACK}${tar_flie_name}" fi done done done } function backup(){ echo "3.压缩保留文件并删除原始文件" for((i=1;i<=${DEL_FILE_RET};i++)); do #计算时间 file_date=`date -d -${i}day +%F` #遍历文件头列表 for j in ${FILE_HEAD[@]}; do #遍历文件后缀列表 for k in ${FILE_TAIL[@]}; do #组装压缩文件名 file_name=${j}.${FILE_TAIL}.${file_date} if [ ! -f "${FILE_DIR}${file_name}" ]; then continue fi #生成压缩文件 tar_flie_name=${file_name}.${FILE_TAR} cd ${FILE_DIR} if [ ! -f "${FILE_DIR_BACK}${tar_flie_name}" ]; then println '压缩文件:'"${FILE_DIR_BACK}${tar_flie_name}" tar -zcPf "${FILE_DIR_BACK}${tar_flie_name}" ${file_name} else println '已存在文件:'"${FILE_DIR_BACK}${tar_flie_name}" fi #清理原始文件 rm -rf ${FILE_DIR}${file_name} println "删除文件:"${FILE_DIR}${file_name} done done done } function test(){ echo "1.产生测试文件" cd ${FILE_DIR} for((i=1;i<=${DEL_FILE_NUM};i++)); do #计算时间 file_date=`date -d -${i}day +%F` #遍历文件头列表 for j in ${FILE_HEAD[@]}; do #遍历文件后缀列表 for k in ${FILE_TAIL[@]}; do #组装文件名 cd ${FILE_DIR} file_name=${j}.${k}.${file_date} #创建原始文件 touch ${FILE_DIR}${file_name} #创建压缩文件 tar_flie_name=${file_name}.${FILE_TAR} cd ${FILE_DIR} tar -zcPf "${FILE_DIR_BACK}${tar_flie_name}" ${file_name} # println "测试:创建文件 ${FILE_DIR}${file_name} ${FILE_DIR_BACK}${tar_flie_name}" done done done } function println(){ echo `date '+%Y-%m-%d %H:%M:%S'`":"$* } ############################################################################################# #运行代码 echo "0.运行前准备" cd ${FILE_DIR} if [ ! -d "${FILE_DIR}" ]; then echo "日志目录不存在,退出!" exit fi if [ ! -d "${FILE_DIR_BACK}" ]; then echo "备份目录不存在,创建!" mkdir -p ${FILE_DIR_BACK} fi ifo if [ $# -gt 0 ];then if [ $1 == ${PAR_TEST} ];then test exit elif [ $1 == ${PAR_RUN} ];then clear backup exit elif [ $1 == ${PAR_CLEAR} ];then clear exit elif [ $1 == ${PAR_BACKUP} ];then backup exit fi echo "参数错误,退出!" exit fi exit