脚本说明:
日志切割与上传类脚本的功能:脚本自身的运行日志记录与清理、日志切割与打包、ftp上传、传送失败自动重传、断电自动补传、清理超期旧打包等
--------------------
#!/bin/bash# Cut and upload aclog log# by colin# revision on 2016-06-15######################################### 功能说明:该脚本运用于上传aclog日志## 使用说明:#+ ./aclog_backup_and_upload.sh -f /var/log/host/jnxac.log -t tar -h SDQD-TS-JNX-HLS# 更新说明:##########################################sleep 60 #延时60秒运行PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/binRUN_LOG='/var/log/cron_scripts_run.log'[ ! -f ${RUN_LOG} ] && touch ${RUN_LOG}echoGoodLog(){ echo -e "\033[32m`date +%F" "%T":"%N` $*\033[0m" >> ${RUN_LOG}}echoBadLog(){ echo -e "\033[31m`date +%F" "%T":"%N` $*\033[0m" >> ${RUN_LOG}}echoGoodLog "Now, Script: `basename $0` run."RUNLOG_MAX_NUM=100000RUNLOG_MAX_DELNUM=5000SEND_MAX_TIME=6SEND_WHILE_SLEEP_TIME=30BACK_SAVE_MAX_DAY=180LOG_CUT_MIN=60 # 日志文件30分钟切割一次cleanRunLog(){ CLEANLOGFILE=${1?"Usage: $FUNCNAME log_file_name"} TEMP_WC=`cat ${CLEANLOGFILE} |wc -l` [ "${TEMP_WC}" -gt "${RUNLOG_MAX_NUM}" ] && { sed -i "1,${RUNLOG_MAX_DELNUM}d" ${CLEANLOGFILE} && echoGoodLog "Clean up the ${CLEANLOGFILE}..." } echoGoodLog "Script: `basename $0` run done." exit}### 省份数组#PROVINCE=( sd hlj sc)### 脚本帮助提示函数#scriptsHelp(){ echoBadLog "=======================================" echoGoodLog "Usage parameters:" echoGoodLog "./`basename $0` -f/--file /var/log/host/qfgw.log [-t/--tar tar] [-h/--hostname SDQD-TS-CL-WIN]" echoGoodLog "Options:" echoGoodLog " -f/--file)" echoGoodLog " 必须的参数:需要切割与上传的日志文件" echoGoodLog " -t/--tar)" echoGoodLog " 可选参数:若需打包,使用方法: -t tar " echoGoodLog " -h/--hostname)" echoGoodLog " 可选参数:若一个站点存放了多个地方的相同类型日志,此时就需要设定每个日志所属站点" echoGoodLog " 比如:昌乐的网关日志,没有HLS,日志存储在青岛北,那加参数如下:-h SDQD-TS-CL-WIN" echoGoodLog " -c)" echoGoodLog " 可选参数:用于检查日志服务器上是否有存储日志的文件夹,没有就创建,需使用except命令,会自动安装" echoGoodLog " 注意:日志服务器必须要开放ssh远程登录,或者防火墙需要放行" echoGoodLog " 使用方法:./`basename $0` -c ;-c后面不需要加选项" echoGoodLog "Example:" echoGoodLog "./`basename $0` -f /var/log/host/qfgw.log -t tar -h SDQD-TS-CL-WIN" echoBadLog "======================================="}checkParameter(){ PARAMETER=${1:-null} PARAMETER_STATUS=`echo "${PARAMETER}" |grep "^-"|wc -l` if [ "${PARAMETER_STATUS}" -eq 1 -o "${PARAMETER}" = "null" ];then scriptsHelp echoBadLog "参数错误,请重新输入。" exit fi}### 判断是否带参数#if [ -z "$*" ];then scriptsHelp exitelse ## # 脚本传参数,调用相应的函数功能 # while test -n "$1";do case "$1" in --file|-f) shift checkParameter $1 LOG_NAME=$1 ;; --tar|-t) shift checkParameter $1 CTAR=$1 ;; --hostname|-h) shift checkParameter $1 CHOSTNAME=$1 ;; -c) CCHECK_LOG_SERVER_DIR=$1 ;; *) echoBadLog "Unknown argument: $1" scriptsHelp exit ;; esac shift donefi### 需要切割的日志为必须要的参数#checkParameter $LOG_NAMEIS_TAR=${CTAR:-notar}HOSTNAME=${CHOSTNAME:-`hostname`}TEMP_PRO=`echo ${PROVINCE[@]} |sed "s/ /|/g"`STATION=`echo ${HOSTNAME} |awk -F- '{print $3}'|tr [A-Z] [a-z]`STATION_TYPE=`echo ${HOSTNAME} |awk -F- '{print $2}'|tr [A-Z] [a-z]`STATION_SITE=`echo ${HOSTNAME} |awk -F- '{print $1}'|tr [A-Z] [a-z] |grep -Eo "\b${TEMP_PRO}"`############################## define the ftp clientLOG_TYPE="aclog"LOG_TYPEB="aclog"LCD_DIR="/data/${STATION}_log/${STATION}_${LOG_TYPE}"# 日志服务器上的保存文件夹特例#----------------------------case ${STATION_SITE}${STATION_TYPE} in #sdbs) CD_DIR="/${LOG_TYPEB}/${STATION_SITE}/qdjy/${STATION}/";; sdbs) CD_DIR="/${LOG_TYPEB}/${STATION_SITE}/qdjy/";; *) CD_DIR="/${LOG_TYPEB}/${STATION_SITE}/${STATION}/";;esac############################## define the ftp serverFTPSERVER='IP地址'FTPUSER='用户名'FTPPASSWD='密码'SSHPORT='端口'#############################T=`echo $(date +%k) |sed 's/ //g'`#LAST_T=`echo $(date -d "1 hour ago" +%k) |sed 's/ //g'`DAY_TIME=`date +%Y-%m-%d`LAST_DAY_TIME=`date -d "yesterday" +%Y-%m-%d`LAST_HOUR_TIME=`date +%Y-%m-%d-%H`FILENUM=`expr $(date +%M|sed 's/^0//g') / ${LOG_CUT_MIN}`DAY_LOG_TAR_NUM="${FILENUM}"[[ "${FILENUM}" -eq 0 ]] && { FILENUM=`expr 60 / ${LOG_CUT_MIN}` LAST_HOUR_TIME=`date -d "1 hour ago" +%Y-%m-%d-%H`}### 为兼容旧版本,当60分钟切割一次时,就和之前旧版本文件名一样咯#if [ ${LOG_CUT_MIN} -eq 60 ];then LOG_HOUR_NAME="${LOG_TYPE}${LAST_HOUR_TIME}.txt" else LOG_HOUR_NAME="${LOG_TYPE}${LAST_HOUR_TIME}-${FILENUM}.txt" fiLOG_DAY_NAME="${LOG_TYPE}${LAST_DAY_TIME}.txt" case "${IS_TAR}" in "tar") PUT_LOG_DAY_NAME="${LOG_DAY_NAME%.txt}.tar.gz" PUT_LOG_HOUR_NAME="${LOG_HOUR_NAME%.txt}.tar.gz" ;; "notar") PUT_LOG_DAY_NAME="${LOG_DAY_NAME}" PUT_LOG_HOUR_NAME="${LOG_HOUR_NAME}" ;;esactarLogFile(){ TARTONAME=${1?"Usage: $FUNCNAME tar_file_name need_tar_file_name"} FROMLOG=$2 tar -czf ${TARTONAME} --remove-files ${FROMLOG} if [ -e ${TARTONAME} ];then echoGoodLog "Tar: ${TARTONAME} is successfully." else echoBadLog "Tar: ${TARTONAME} was failed, Please check..." fi}checkProgramExist(){ PROGRAMNAME=${1?"Usage: $FUNCNAME program_install_name"} PROGRAMEXIST=`dpkg -l |grep -wo ${PROGRAMNAME}|wc -l` if [ "${PROGRAMEXIST}" -ge 1 ];then return 0; else /usr/bin/apt-get install ${PROGRAMNAME} -y if [ $? -eq 0 ];then echoGoodLog "Install ${PROGRAMNAME} is successfully." return 0; else echoBadLog "Install ${PROGRAMNAME} was failed, Please check..." return 1; fi fi}checkLogServerDir(){ checkProgramExist expect passwd=${FTPPASSWD} /usr/bin/expect <<-EOFset time 1spawn ssh -p${SSHPORT} ${FTPUSER}@${FTPSERVER}expect { "*yes/no" { send "yes\r"; exp_continue } "*password:" { send "$passwd\r" }}expect "*~$"send "cd /home/upload${CD_DIR}\r"expect { "*No such file or directory" { send "mkdir -p /home/upload${CD_DIR}\r" }}expect "*~$"send "exit\r"interactexpect eofEOF echo -e "\r"}[ ! -d ${LCD_DIR} ] && mkdir -p ${LCD_DIR}### 若切割后的日志文件存在时,就退出切割命令等#cd ${LCD_DIR} && [ ! -f ${PUT_LOG_HOUR_NAME} ] && { if [ -s ${LOG_NAME} ];then until [ -f ${LOG_HOUR_NAME} ] do cp ${LOG_NAME} ${LOG_HOUR_NAME} done if [ $? -eq 0 -a -f "${LOG_HOUR_NAME}" ];then echoGoodLog "Create ${LOG_HOUR_NAME} is successfully." else echoBadLog "Create ${LOG_HOUR_NAME} was failed, Please check..." fi [ "${IS_TAR}" = "tar" ] && tarLogFile ${PUT_LOG_HOUR_NAME} ${LOG_HOUR_NAME} if [ "${T}" -eq 0 -a "${DAY_LOG_TAR_NUM}" -eq 0 ];then TEMP_CHECK_LOG=`ls -l ${LOG_DAY_NAME} |awk '{print $5}'` cat ${LOG_NAME} >> ${LOG_DAY_NAME} [ $? -eq 0 ] || cat ${LOG_NAME} >> ${LOG_DAY_NAME} CHECK_LOG=`ls -l ${LOG_DAY_NAME} |awk '{print $5}'` else [ -f ${LOG_TYPE}${DAY_TIME}.txt ] || touch ${LOG_TYPE}${DAY_TIME}.txt TEMP_CHECK_LOG=`ls -l ${LOG_TYPE}${DAY_TIME}.txt |awk '{print $5}'` cat ${LOG_NAME} >> ${LOG_TYPE}${DAY_TIME}.txt [ $? -eq 0 ] || cat ${LOG_NAME} >> ${LOG_TYPE}${DAY_TIME}.txt CHECK_LOG=`ls -l ${LOG_TYPE}${DAY_TIME}.txt |awk '{print $5}'` fi echoGoodLog "CHECK: CHECK_LOG=${CHECK_LOG},TEMP_CHECK_LOG=${TEMP_CHECK_LOG}..." if [ "${CHECK_LOG}" -gt "${TEMP_CHECK_LOG}" ];then cat /dev/null > ${LOG_NAME} [ $? -eq 0 ] && echoGoodLog "Append: ${LOG_HOUR_NAME} to ${LOG_TYPE}_day_log is successfully." else echoBadLog "Append: ${LOG_HOUR_NAME} to ${LOG_TYPE}_day_log was failed, Please check..." fi [ "${T}" -eq 0 -a "${IS_TAR}" = "tar" -a "${DAY_LOG_TAR_NUM}" -eq 0 ] && tarLogFile ${PUT_LOG_DAY_NAME} ${LOG_DAY_NAME} else echoBadLog "Log: ${LOG_NAME} is null or not exist, Please check..." fi}### 检查保存文件夹目录是否存在#CHECK_LOG_SERVER_DIR=${CCHECK_LOG_SERVER_DIR:-"f.ck"}[ "${CHECK_LOG_SERVER_DIR}" = "-c" ] && checkLogServerDirFTP_LOG_DIR="/tmp/ftp_err"[ -d ${FTP_LOG_DIR} ] || mkdir -p ${FTP_LOG_DIR}FTP_ERROR_LOG="${FTP_LOG_DIR}/ftp_temp_${LOG_TYPE}_err$$.log"### FTP自动化上传函数#sendLog(){ SENDLOGFILE=$1 ftp -ivn ${FTPSERVER} 21 >${FTP_ERROR_LOG} << _EOF_user ${FTPUSER} ${FTPPASSWD}passivebinlcd ${LCD_DIR}cd ${CD_DIR}put ${SENDLOGFILE}bye_EOF_ ## # 统计前面FTP运行输出的错误日志记录行数 # LOG_COUNT=`grep -w "^226" ${FTP_ERROR_LOG}|wc -l` if [ "${LOG_COUNT}" -eq 1 ];then echoGoodLog "Send: ${SENDLOGFILE} to ftp_server was successfully." TEMP_SEND_STATUS=0 return 0 else echoBadLog "Send: ${SENDLOGFILE} more than $x time." TEMP_SEND_STATUS=1 sleep ${SEND_WHILE_SLEEP_TIME} return 1 fi}REUPLOADLIST="/var/log/reupload_list_${LOG_TYPEB}_${STATION}.log"TEMP_REUPLOADLIST="/var/log/temp_reupload_list_${LOG_TYPEB}_${STATION}.log"[ -f ${TEMP_REUPLOADLIST} ] && rm ${TEMP_REUPLOADLIST}runSendLog(){ SENDLOGNAME=$1 x=1;i=1 until [ "$i" -eq 0 ];do [ "$x" -gt "${SEND_MAX_TIME}" ] && { echoBadLog "Send: ${SENDLOGNAME} to ftp_server was failed, Please check..." echo "${LCD_DIR};;${CD_DIR};;${SENDLOGFILE}" >> ${TEMP_REUPLOADLIST} break } sendLog "${SENDLOGNAME}" i=`echo $?` x=`expr $x + 1` done}[ "${T}" -eq 0 -a -f "${LCD_DIR}/${PUT_LOG_DAY_NAME}" -a "${DAY_LOG_TAR_NUM}" -eq 0 ] && runSendLog ${PUT_LOG_DAY_NAME}[ -f "${LCD_DIR}/${PUT_LOG_HOUR_NAME}" ] && runSendLog ${PUT_LOG_HOUR_NAME}### 把上面两种发送成功的记录更新到这个临时文件#TEMP_SENDSUCCESFILE="/var/log/temp_send_succes_${LOG_TYPEB}_${STATION}.txt"SENDSUCCESFILE="/var/log/send_succes_${LOG_TYPEB}_${STATION}.txt"[ "${TEMP_SEND_STATUS}" -eq 0 ] && echo "${LCD_DIR};;${CD_DIR};;${SENDLOGFILE};;$(date +%s)" > ${TEMP_SENDSUCCESFILE}[ -e ${SENDSUCCESFILE} ] && { LCD_DIR=`cat ${SENDSUCCESFILE}|awk -F";;" '{print $1}'` CD_DIR=`cat ${SENDSUCCESFILE}|awk -F";;" '{print $2}'` LAST_DATE_SUCCESS=`date -d @"$(cat ${SENDSUCCESFILE}|awk -F";;" '{print $4}')" +%Y-%m-%d` INTERVAL_TIME=`expr $(date +%s) - $(cat ${SENDSUCCESFILE}|awk -F";;" '{print $4}')` LAST_DAY=`echo $(date -d @"$(cat ${SENDSUCCESFILE}|awk -F";;" '{print $4}')" +%d)|sed 's/^0//g'` NOW_DAY=`echo $(date +%d)|sed 's/^0//g'` [ "${LAST_DAY}" -ne "${NOW_DAY}" -a "${INTERVAL_TIME}" -gt 7000 ] && { if [ "${IS_TAR}" = "tar" ];then cd ${LCD_DIR} && { TEMP_SEND_FILES="${LOG_TYPE}${LAST_DATE_SUCCESS}.tar.gz" [ -e ${TEMP_SEND_FILES} ] || tarLogFile ${TEMP_SEND_FILES} ${LOG_TYPE}${LAST_DATE_SUCCESS}.txt } else TEMP_SEND_FILES="${LOG_TYPE}${LAST_DATE_SUCCESS}.txt" fi runSendLog ${TEMP_SEND_FILES} } rm ${SENDSUCCESFILE}}[ -f ${TEMP_SENDSUCCESFILE} ] && mv ${TEMP_SENDSUCCESFILE} ${SENDSUCCESFILE}### 重传上次发送失败的文件#+ 说明:重新上传函数的执行段,最好是放在后面,因为它依赖前面的FTP发送函数生成的TEMP_REUPLOADLIST清单#reUploadFile(){ TEMP_NEED_DO_FILE=$1 REUPLOADLIST_NUM=`cat ${TEMP_NEED_DO_FILE}|wc -l` [ "${REUPLOADLIST_NUM}" -ge 1 ] && { while read line do LCD_DIR=`echo ${line}|awk -F";;" '{print $1}'` CD_DIR=`echo ${line}|awk -F";;" '{print $2}'` REUPLOADFILENAME=`echo ${line}|awk -F";;" '{print $3}'` [ -f "${LCD_DIR}/${REUPLOADFILENAME}" ] && runSendLog ${REUPLOADFILENAME} done < ${TEMP_NEED_DO_FILE} } [ -e ${TEMP_NEED_DO_FILE} ] && rm ${TEMP_NEED_DO_FILE}}[ -s ${REUPLOADLIST} ] && reUploadFile ${REUPLOADLIST}[ -f ${TEMP_REUPLOADLIST} ] && mv ${TEMP_REUPLOADLIST} ${REUPLOADLIST}[ -f ${FTP_ERROR_LOG} ] && rm ${FTP_ERROR_LOG}### 清理超过90天的备份日志#[ -d ${LCD_DIR} ] && cd ${LCD_DIR} && { for FILENAME in `find . -type f -ctime +"${BACK_SAVE_MAX_DAY}" | awk -F/ '{print $2}'` do rm ${FILENAME} && echoGoodLog "Clear: ${LCD_DIR}/${FILENAME}..." done}cleanRunLog ${RUN_LOG}
--------------------