程序代码如下:
perl负责提取5分钟内的日志
awk负责分析5分钟内的日志
#######
perl部分
#######
#!/usr/bin/perl -w
$log=$ARGV[0];##日志由参数1获取
$pre_opt=`stat -c '%s' $log`;#调用shell命令stat获得日志起始点字节数
sleep 300;####等待300秒即5分钟
while (1)
{
open (LOG,"<$log");#打开日志
$min5_opt=`stat -c '%s' $log`;#调用shell命令stat获得5分钟后的结束点字节数
if ($min5_opt>$pre_opt)#判断日志是否更新增加
{ seek(LOG,$pre_opt,0);#调用seek来偏移指针位置
$byte=$min5_opt-$pre_opt;#结束字节减开始字节之差即5分钟内所有内容
read(LOG,$content,$byte);#调用read来读取5分钟内的内容
open (LOG_5min,">./access_5min.log");
print LOG_5min "$content";#将内容打印到句柄LOG_5min内
system ("bash ./awk_log.sh ./access_5min.log");#调用shell awk程序进行日志分析
close LOG_5min;
$pre_opt=$min5_opt;#将结束赋值给开始
close LOG;
sleep 300;#等待5分钟轮询
}
elsif ($min5_opt==$pre_opt)#如果开始字节数等于结束时间数
{
open (ERROR_LOG,">>./perl_log.errlog");
$ftime=localtime();
printf ERROR_LOG "$ftime may be log is broken or apache is down\n" ;#说明日志在5分钟内没有更新,有可能磁盘满了无法写入导致的日志错误;还有肯能是apache服务已经停掉
printf ERROR_LOG "perl_log is unnormal exit\n";
exit;
}
}
#######
awk部分
#######
#!/bin/bash
################
#for squid######
#file awk_log.sh
#log same as 58.35.104.18 - - [16/Mar/2009:10:55:28 +0800] "GET
http://i1.sinaimg.cn/IT/images/2007-12-06/U2485P2T78D10797F3303DT20071206113416.gif HTTP/1.1" 200 662 "" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; GTB5; .NET CLR 1.1.4322; .NET CLR 2.0.50727)" TCP_MEM_HIT:NONE [2]
#################################################################################
#BY IORI########
#vesion v2.0#
################
APACHE_LOG=$1
if [ -f $APACHE_LOG ];then
#echo -e "\033[0;32;1m This is me" #测试语句
#######IP address#####################################################
GET_IP=`netstat -tpln|awk '/^tcp/&&/:80/ {print $4}'|awk -F ':' '{print $1}'|head -n1` #获得主机IP
#######END#################################################################
##########RSYNC_log################################################################
RSYNC_LOG=${GET_IP}_`date '+%H:%M:%S'`.log #创建日志文件名
#######END#########################################################################
#####GET time##################################################
GET_TIME=`head -n 1 $APACHE_LOG|awk -F '[' '{print $2}' |awk '{print $1}'|sed 's#/# #g'|sed 's#:# #'`
START_TIME=`date -d "$GET_TIME" '+%Y-%m-%d %H:%M:%S'`#得到日志中的第一行时间戳
GET_TIME=`tail -n 1 $APACHE_LOG|awk -F '[' '{print $2}' |awk '{print $1}'|sed 's#/# #g'|sed 's#:# #'`
END_TIME=`date -d "$GET_TIME" '+%Y-%m-%d %H:%M:%S'`#得到日志中的尾行时间戳
#####END###############################################################
AWK_SECOND=300 #设定分析时间
echo -n -e "GET_IP=${GET_IP}\nSTART_TIME=${START_TIME}\n" >> ./$RSYNC_LOG
awk -v second=$AWK_SECOND '{if($9~/20[0-6]|30[0-5]/)BYTE+=$10}{if($9~/200/) http200++}{if($9~/304/) http304++}{if($9~/403/) http403++}{if($9~/404/) http404++}{if($9~/500/) http500++}{if($9~/503/) http503++}END{printf "client_request=%.2f\n",NR/second;printf "client_kbyte_out=%.2f\n",BYTE/1024/second;printf "sys_http200=%.2f\n",http200/second;printf "sys_http304=%.2f\n",http304/second;printf "sys_http403=%.2f\n",http403/second;printf "sys_http404=%.2f\n",http404/second;printf "sys_http500=%.2f\n",http500/second;printf "sys_http503=%.2f\n",http503/second}' $APACHE_LOG >> ./$RSYNC_LOG #日志分析处理主要代码
echo -n -e "END_TIME=$END_TIME\n" >> ./$RSYNC_LOG
if [ -f ./$RSYNC_LOG ]&&[ ! -z ./$RSYNC_LOG ];then
rsync -rtopg /usr/home/yanglei1/$RSYNC_LOG 202.106.*。*::模块名 >/dev/null 2>&1 && mv ./$RSYNC_LOG ./jtc_bak_log/ #传递到远程并在成功后备份
fi
fi
处理速度与效率演示
perl抓取300w行数据
./perl_log.pl.bak access_301w.log
real 0m2.537s
user 0m0.790s
sys 0m1.749s
awk分析80w行数据
wc -l access_3bai.log
800000
./awk_log.sh_bak access_80w.log
real 0m5.131s
user 0m2.934s
sys 0m2.200s
awk分析300w行数据
wc -l access_3bai.log
3000000
time ./awk_log.sh_bak access_3bai.log
real 0m14.007s
user 0m11.502s
sys 0m2.517s
阅读(1032) | 评论(1) | 转发(0) |