最近在项目中遇到对于上线正常运行应用系统进行日常巡检时需要提取错误日志,以分析程序运行情况(或方便开发人员定位问题)。由于项目组之前没有类似工具,于是动手写下这个脚本小工具,可以根据输入的日期和目标日志文件路径,提取出输入日期当天及以后的所有错误日志。简单适用根据目前的使用效果已经能满足日常工作使用需要。大家也可以根据自己的需要进行扩展。
##################################################################
#!/bin/sh
# Author:Mr.Hsia
##################################################################
argc=$#;
targetFile="";
beginDate="";
help()
{
echo "usage :${0} ";
echo " eg:${0} 20170101 \"/tmp/example.log\"";
echo " eg:${0} 2017-01-01 \"/tmp/example.log\"";
exit 0;
}
replaceStr()
{
local srcStr=${1};
local oldSubStr=${2};
local newSubStr=${3};
local subIdx=`expr index "${srcStr}"
"${oldSubStr}"`;
if [ ${subIdx} -gt 0 ]
then
srcStr=`echo "${srcStr}" | awk
'gsub(/'${oldSubStr}'/,'\"${newSubStr}\"',$1) {
print $1 }'`;
fi
echo ${srcStr};
}
if [ ${argc} -lt 1 ];
then
help;
exit 0;
else
if [ ${argc} -eq 1 ];
then
argv1=${1};
if [
${argv1} = "-h" ] || [ ${argv1} = "help" ]
then
help;
exit 0;
else
targetFile=${1};
#check the source log file is exist?
if [ ! -s ${targetFile} ]
then
echo "file
not exist or is empty[file:${targetFile}].";
exit
0;
fi
fi
else
beginDate=${1};
beginDate=`replaceStr
"${beginDate}" "-" ""`;
beginDate=`replaceStr
"${beginDate}" "\/" ""`;
beginDate=`replaceStr
"${beginDate}" "\." ""`;
beginDate=`replaceStr
"${beginDate}" "#" ""`;
if [ ${#beginDate} -lt 8
]
then
help;
exit 0;
fi
targetFile=${2};
#check the source log
file is exist?
if [ ! -s ${targetFile}
]
then
echo "file not exist or is
empty[file:${targetFile}].";
exit 0;
fi
fi
fi
#isErrorBlock
isErrorBlock()
{
#0-is not in error block,1-is error
block.
local isErrBlk=false;
local tmpLineStr=$1;
tmpStr=`echo "${tmpLineStr}" | awk '{
printf $1 }'`;
#echo "tmpStr="${tmpStr}
if [ ! "${tmpLineStr}" ] || [ -z
"${tmpLineStr}" ] ;
then
echo
${isInErrBlk};
exit
0;
fi
local beginIdx=$(expr match "${tmpStr}"
".*ERROR");
local tmpErrBlk=${beginIdx};
if [ ${beginIdx} -le 0 ] ;
then
beginIdx=$(expr match "${tmpStr}" ".*Exception:");
fi
local endKeys=("DEBUG"
"INFO"
"WARN"
"信息:"
"警告:"
);
local endIdx=0;
for endFlag in
${endKeys[@]}
do
endIdx=$(expr match "${tmpStr}" ".*${endFlag}");
if [
${endIdx} -gt 0 ] ;
then
break;
fi
done
if [ ${beginIdx} -gt 0 ] ;
then
isErrBlk=true;
else
if [ ${endIdx} -gt 0 ]
;
then
isErrBlk=false;
else
isErrBlk=true;
fi
fi
echo "${isErrBlk}";
}
#isNextSegment
isNextSegment()
{
#0-is not in error block,1-is error
block.
local isNextSect=false;
local tmpLineStr=$1;
#echo ${tmpLineStr}
if [ ! "${tmpLineStr}" ] || [ -z
"${tmpLineStr}" ] ;
then
echo
${isNextSect};
exit
0;
fi
local
segKeys=("ERROR"
"DEBUG"
"INFO"
"WARN"
"信息:"
"警告:"
""
""
""
""
);
for flag in ${segKeys[@]}
do
local matchIdx=$(expr
match "$tmpLineStr" ".*${flag}");
if [ ${matchIdx} -gt 0
];
then
isNextSect="true";
break;
fi
done
echo ${isNextSect};
}
#readSpecLine
readSpecLine()
{
local beginIdx=`echo $1 | awk '{printf
"%d",$0}'`;
local src_file=$2;
local dest_file=$3;
#check the source log file is exist?
if [ ! -s ${src_file} ]
then
echo
"file not exist or is empty[file:${src_file}].";
exit
0;
fi
local countLines=1;
while read line
do
#echo
"Line:${countLines},readLine=${line}";
if [
${countLines} -ge ${beginIdx} ] ;
then
if [ ${countLines} -gt ${beginIdx} ] ;
then
local
vNxSeg=(`isNextSegment "${line}"`);
if [
${vNxSeg} == "true" ];
then
break;
fi
fi
local vRets=(`isErrorBlock "${line}"`);
local ret1=${vRets[0]};
if [ "${ret1}" == "true" ] ;
then
echo "${line}" >>
${dest_file};
else
break;
fi
fi
countLines=$[ ${countLines}+1 ];
done <
${src_file};
}
mainEntity()
{
#check the source log
file is exist?
if [ ! -s ${targetFile}
]
then
echo
"file not exist or is empty[file:${targetFile}].";
exit
0;
else
#make
pickuplogs directory
local
outputDir=$PWD"/pickuplogs"
mkdir
-p ${outputDir}
#create a new file for save pickup error
message.
local
outputFile=${outputDir}"/"${targetFile##*/}".error"
#echo
"create file:"${outputFile}
rm -f
${outputFile};
touch
${outputFile};
#backup source log file.
rm -f
"${targetFile}.pick";
cp -f
"${targetFile}" "${targetFile}.pick";
targetFile="${targetFile}.pick"
fi
local arrLineNo=();
if [ -z ${beginDate} ]
;
then
arrLineNo=(`grep -n "ERROR" "${targetFile}" | awk
' {printf "%d\n",$0}'`);
else
local arrLines=(`grep -n "ERROR" "${targetFile}"
| awk 'gsub(/-/,"",$2) {printf
"%d-%s\n",$0,$2}'`);
local idx=0;
for itemStr in ${arrLines[@]}
do
items=(`echo "${itemStr}" |
awk 'BEGIN{ FS="-"}; { printf "%s\n%s\n",$1,$2}'`);
local
dateTime=${items[1]};
if [ ! -z dateTime ]
&& [ ${dateTime} -ge ${beginDate} ]
then
arrLineNo[idx]=${items[0]};
fi
idx=$[ ${idx}+1 ];
done
fi
local
maxCount=${#arrLineNo[@]};
local count=1;
#echo
"Total:${maxCount}";
for lineNo in
${arrLineNo[@]}
do
#echo
"LineNo:${lineNo},count=${count},maxCount=${maxCount}";
percentVar=`awk 'BEGIN{printf "%.2f%%\n",
('${count}'/'${maxCount}')*100}'`;
echo
"LineNo:${lineNo},Index=${count},maxCount=${maxCount},progress:${percentVar}";
echo
"-------------------===========${lineNo}========-------------------"
>> ${outputFile}
readSpecLine ${lineNo} "${targetFile}"
"${outputFile}" ;
count=$[ ${count}+1 ] ;
done
rm -f
"${targetFile}";
}
mainEntity;
exit 0;