bash 获取时间段内的日志内容

需求,获取时段内的/var/log/messages文件内出现错误的消息,支持多行的消息,支持天,小时分钟,秒级的区间,可以修改监控的日志对象

 

#!/bin/bash

if [ $# != 1 ] ; then
echo "USAGE: $0 num[Y|D|H|M|S]"
echo " e.g.: $0 12h"
exit 1;
fi 

interval=$1
unit=$(echo $interval | tr -d [:blank:] |tr -d [:digit:] |tr -t [a-z] [A-Z])
val=$(echo $interval | tr -d [:blank:] |tr -d [:alpha:] )
#echo $val
#echo $unit

case $unit in
Y)      unit="years"
	;;
D)	
	unit="days" 
	;;
H)
	unit="hours"
	;;
M)
	unit="minutes"
	;;
S)	
	unit="seconds"
	;;
*)
	echo "not"
	exit 1;
	;;
esac
#echo $unit

ts=$(date -d"-${val}${unit}" +"%s")
echo $ts 
#date span one year 计算两年之间的秒数
cts=$(date +"%s")
x1=$(date -d"$(date +%Y)-01-01 00:00:00" +"%s") 
x2=$(date -d"$(date -d'-1years' +%Y)-01-01 00:00:00" +"%s")
((secs=$x1-$x2))

checkfile=/var/log/messages
#checkfile=/home/student/test.txt

#first_line=$(awk -v ts="$ts" '{"date -d \""$1" "$2" "$3"\" +%s 2>/dev/null"|getline dt; if(dt>ts) {print $0; exit;}}' $checkfile)
first_line=$(awk -v secs="$secs" -v ts="$ts" -v cts="$cts" '{"date -d \""$1" "$2" "$3"\" +%s 2>/dev/null"|getline dt;if(dt>cts){dt=dt-secs;}if(dt>ts) {print $0; exit;}}' $checkfile)

echo "firstline is $first_line"

if [ "$first_line"X == "X" ]; then  exit 1; fi

basedir=$(cd `dirname $0`;pwd)
#echo "basedir is $basedir"

log=$basedir/linux_messages.log
>$log

#function to handle one msg
handleOneMsg()
{
msg="$1"
has_error=$(echo "$msg"|grep -oie "\berror\b")
if [ "$has_error"X != "X" ]; then
#first we should encode the < > &
msg_out=$(echo "$msg" |sed 's/&/&/g'| sed 's/</\</g'|sed 's/>/\>/g' )
cat <<EOF >>$log
<msg>
<hostName>`hostname`</hostName>
<product>LINUX</product>
<date>`date +"%Y-%m-%d %T"`</date>
<streamName>messages</streamName>
<output>$msg_out</output>
</msg>
EOF
fi

}

OLDIFS=IFS
IFS=$'\n'
for line in $(grep -A100000 -F "$first_line" $checkfile)
do
#date ..... one message is start with date 
#before another msg is the last msg's body
line_begin=$(echo $line | awk '{print $1,$2,$3}')
#echo "line begin is $line_begin"

line_begin_ts=$(date -d "$line_begin" "+%s" 2>/dev/null)
#echo "line begin ts is $line_begin_ts"

if [ "${line_begin_ts}"X == "X" -o "$msg"X == "X" ] ; then 
   msg="${msg}"$'\n'"${line}"
   continue;#consume next line
fi
 
 handleOneMsg "$msg"
 msg=$line
done

handleOneMsg "$msg"

IFS=$OLDIFS

 

posted on 2017-11-20 09:28  tneduts  阅读(222)  评论(0编辑  收藏

导航