michael数据库kingdba.blog.chinaunix.net

平淡,平凡,平静,低调。

  • 博客访问: 212350
  • 博文数量: 77
  • 博客积分: 1732
  • 博客等级: 上尉
  • 技术积分: 802
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-11 16:02
个人简介

博客很久没有更新了,原因是大多数时间都忙在研究技术上,却懒得腾时间出来把技术分享,最近在开源力量上开课《Mongodb管理与维护》,让屌丝们从0到精通,敬请关注。本博客技术原创更新滞后一些,找时间更新有关mysql,mongodb等内容,谢谢大家关注。

文章分类

全部博文(77)

文章存档

2011年(20)

2010年(40)

2009年(7)

2008年(10)

微信关注

IT168企业级官微



微信号:IT168qiye



系统架构师大会



微信号:SACC2013

订阅
热词专题
缓存日志按站点分割脚本 2008-05-08 15:43:52

分类: LINUX

本人用squid缓存了三十多个站点,两台缓存每天共产生约6G的日志,但想把日志按站点分割出来,以便日志分析软件进行详细的分析。最近研究了一个月,终于出来了。现公开源码,给大家分享。转载请注明出处踏遍芳草地--黄锡峰原创http://blog.chinaunix.net/u2/66215/showart.php?id=681180.

我的squid日志,apache格式的.

logformat combined %>a %ui %un [%tl] "%rm %ru HTTP/%rv" %Hs %<st "%{Referer}>h" "%{User-Agent}>h" %Ss:%Sh

 

1chlog.sh的作用是拷贝日志到另一个目录进行处理,拷贝前先进行判断日志有几天的,以确保只保留三天日志.因为日志太大,白白占了空间.

[root@www cachelog]# cat chlog.sh
#!/bin/sh

#生成今天的日期变量
 y=`date --date='0 days ago' "+%Y"`
 m=`date --date='0 days ago' "+%m"`
 d=`date --date='0 days ago' "+%d"`

#生成三天前的日期变量
 yy=`date --date='3 days ago' "+%Y"`
 mm=`date --date='3 days ago' "+%m"`
 dd=`date --date='3 days ago' "+%d"`
 #
如果三天前的日志还存在的话,就删除。即只保存最近三天的日志。
 if [ -d /cachelog/log$yy$mm$dd ]
 then
     /bin/rm -rf /cachelog/log$yy$mm$dd ;
 fi

#如果今天的日志文件夹不存在的话,就建立今天的日志文件夹。

 if [ ! -d /cachelog/log$y$m$d ]
 then
     /bin/mkdir /cachelog/log$y$m$d ;
 fi

#squid的日志拷贝过来,在这个文件夹里进行处理,并修改权限,#以便能共享给windows的指定用户共享。

 cp /var/log/squid/access.log.0 /cachelog/log$y$m$d/
 chmod 755 /cachelog/log$y$m$d/access.log.0 

2sortlog.sh对日志文件进行排序,目的是为了把相同的站点日志排在一起,把相同的站点日志排在一起,分割日志就快速了。
#!/bin/bash

#生成昨天的日期变量 y是年,m是月,d是日。用来判别日志文件夹是那天的。
y=`date --date='1 days ago' "+%Y"`;
m=`date --date='1 days ago' "+%m"`;
d=`date --date='1 days ago' "+%d"`;


##
按日志的第五段(即按站点字段)排序,并重定向到当天的日志文件夹中。排序后的日志文件命名为access.log.0.s

/bin/sort -t/ -k 5 /cachelog/log$y$m$d/access.log.0 > /cachelog/log$y$m$d/access.log.0.s

3、建立要统计的站点文本文件,以便读取。我网站为sina.lotour.com,这文本文件命名为lotour,每个站点一行,以便用shell读取。

[root@www cachelog]# cat lotour
abroad.lotour.com
aus.lotour.com
bbs.lotour.com
beijing. lotour.com
biz.lotour.com
bjaround.lotour.com
chi.lotour.com
chn.lotour.com
dnk.lotour.com
fra.lotour.com
gangdong.lotour.com
gdaround.lotour.com
golden.lotour.com
gou.lotour.com
guangxi.lotour.com
hebei.lotour.com
i.lotour.com
ind.lotour.com
ita.lotour.com
jiangsu.lotour.com
leisure.lotour.coml
member.lotour.com
outdoor.lotour.com
proc.lotour.com
scaround.lotour.com
search.lotour.com
shandong.lotour.com
shanghai .lotour.com
shanxi.lotour.com
sharound.lotour.com
sichuan.lotour.com
tha.lotour.com
tibet.lotour.com
usa.lotour.com
www.lotour.com
xing.lotour.com
yu.lotour.com
zhejiang.lotour.com
zhu.lotour.com
4
get_record_number.sh负责统计各个站点的日志数目的数量,把它重定向到一个文本文件/cachelog/record_number.txt中。

源码如下:

[root@www cachelog]# cat get_record_number.sh
#!/bin/bash

#生成昨天的日期变量 y是年,m是月,d是日。用来判别日志文件夹是那天的。
y=`date --date='1 days ago' "+%Y"`;
m=`date --date='1 days ago' "+%m"`;
d=`date --date='1 days ago' "+%d"`;

#输出第五段(即站点名),并统计相同的站点记录几条。

/bin/awk -F/ '{print $5}' /cachelog/log$y$m$d/access.log.1.s|uniq -c > /cachelog/record_number1.txt

 

生成Record_number.txt每行格式如下:

记录数  站点名

例如:196831 abroad.lotour.com

      2 abroawww.lotour.com

      1 adsview3.qq.com

    480 anhui.lotour.com

    149 aus.lotour.com

    129 aut.lotour.com

      2 bbs.fiatchina.com

      3 bbs.lotour.com

      1 bbs.racc.cn

    710 beijing.lotour.com

     23 beijinglm.lotour.com

     45 bel.lotour.com

      1 biz.lotour.com

 

5stat_number.sh 脚本的目的是根据第四步生成的文本文件生成各站点的日志记录在日志文件中的记录范围。

源码如下:

[root@www cachelog]# cat stat_number.sh
#!/bin/bash

declare -i sum=0; #已经统计的站点数变量
declare -i start=0; #
起始位置变量
declare -i end=0;   #
结束位置变量
declare -i web=0;   #
保存上一步生成的文本文件的行数
declare -i i=1;#
保存当前的第几行
declare -i b=0;

#如果/cachelog/stat_number.txt不存在的话,就建立。#/cachelog/stat_number.txt用于保存对上一步的文本文件record_number.txt进行处理的结果.
if [ ! -f /cachelog/stat_number.txt ]
then
   /bin/touch /cachelog/stat_number.txt ;
else

#如果/cachelog/stat_number.txt已经存在,证明已经有数据了,

#清空它.
   /bin/cat /dev/null > /cachelog/stat_number.txt ;
fi

 #rec_file记录上一步生成的文本文件的完整路径

rec_file="/cachelog/record_number.txt" ;

#web保存$rec_file的总行数
web=`wc -l $rec_file|awk '{print $1}'` ;
while [ "$i" -le "$web" ]
do
   if [ "$i" -eq 1 ]
   then
       start=1;#
第一个站点的起始行是1
#
给上一步标上行号,然后取第二段(多少行)和第三段(站点#).      

 rec=`/bin/awk '{print NR,$0}' $rec_file|grep -w ^$i|awk '{print $2,$3}'`;

#结束行是保存在end
 end=`/bin/awk '{print NR,$0}' $rec_file|grep -w ^$i|awk '{print $2}'`;    

 #sum保存了已经标记的总行数

  sum=$end;       

 if [ -z "$rec" ]
        then
           echo "$start  $end  $rec" > /dev/null;

#如果这一行并不存在域名,应该丢弃.
        else

#如果存在这个域名,就把起始行数,结束行数,域名重定向到stat_number.txt文件中.
           echo "$start  $end  $rec" >> /cachelog/stat_number.txt;

 fi
   else

#如果不是第一个记录,rec先保存了$rec_file中的一条记录.

rec=`/bin/awk '{print NR,$0}' $rec_file|grep -w ^$i|awk '{print $2,$3}'`;
    end=`/bin/awk '{print NR,$0}' $rec_file|grep -w ^$i|awk '{print $2}'` ;#
取得结束的行数
    start=$sum+1;#
起始的行数应该是上一个已经统计过的域名行数再加1.
    sum=$sum+$end;
    end=$sum;

#结束位置应该是上一次已经统计过的sum加上本次要统计的结束位置.
          echo "$start  $end  $rec" >> /cachelog/stat_number.txt;
    fi
((i++));
done   
###########################################################

生成的文本文件stat_number.txt每行格式如下:

起始行数  结束行数  共记录数  站点名称

260  197090  196831 abroad.lotour.com

197091  197092  2 abroawww.lotour.com

197093  197093  1 adsview3.qq.com

197094  197573  480 anhui.lotour.com

197574  197722  149 aus.lotour.com


6
stat.sh,上一步中,已经生成了所有站点的日志条目在日志文件中的范围,但有些站点并不是要统计的,这时需要把不统计的站点过滤掉。stat.sh的目的就在这此。

[root@www cachelog]# cat stat.sh
#!/bin/bash
declare -i num=0;
declare -i i=1;

#统计stat_number.txt的行数,保存在num.

num=`wc -l /cachelog/stat_number.txt|awk '{print $1}'`;

#把最终结果保存在stat_domain.txt文本文件中,如果不存在就建#,如果已经存在就删除它,再建一个新的.
if [ ! -f  /cachelog/stat_domain.txt ]
then
  /bin/touch /cachelog/stat_domain.txt ;
else
  /bin/rm -f /cachelog/stat_domain.txt ;
  /bin/touch /cachelog/stat_domain.txt ;
fi

while [ $i -le $num ]
do
#
stat_number.txt取出一个域名,保存在domain.
  domain=`awk '{print NR,$4'} /cachelog/stat_number.txt|grep -w ^$i|awk '{print $2}'` ;
  for d in `cat /cachelog/lotour`

  do 

#遍历保存了本公司统计的所有站点文件lotour,如果domain这个域名在lotour,就是要统计的.把它重定向到 stat_domain.txt.              
    if [ "$d" == "$domain" ]
    then
        awk '{print NR,$O}' /cachelog/stat_number.txt |grep -w ^$i|awk '{print $2,$3,$4,$5}' >> /cachelog/stat_domain.txt

    fi
  done
((i++));
done

7、前面第四,五,六步。处理的目的是为了这一步更快的分割日志,因为日志文件太大,用shell实现分割,如果不用前几步处理,运行一天一夜也没有什么效果。处理后只需要两三小时就完成,这一步就是根据第六步生成的stat_domain.txt的文本文件来取各站点日志,实现日志按站点分割.不再作注释.

[root@www cachelog]# cat get.sh

#!/bin/bash

y=`date --date='1 days ago' "+%Y"`;

m=`date --date='1 days ago' "+%m"`;

d=`date --date='1 days ago' "+%d"`;

  declare -i webNum=0;

  webNum=`wc -l /cachelog/stat_domain.txt|awk '{print $1}'`;

  declare -i i=1;

  declare -i st=0;

  declare -i en=0;

while [ $i -le $webNum ]

do

 # get the Domain Name as the filename;

  Domain=`awk '{print NR,$4}' /cachelog/stat_domain.txt|grep -w ^$i|awk '{print $2}'`;

 

    if [ ! -d /cachelog/all/$Domain ]

    then

         /bin/mkdir /cachelog/all/$Domain ;

         /bin/touch /cachelog/all/$Domain/access$y$m$d.log ;

    fi

 

   

    st=`awk '{print NR,$1}' /cachelog/stat_domain.txt|grep -w ^$i|awk '{print $2}'` ;

    en=`awk '{print NR,$2}' /cachelog/stat_domain.txt|grep -w ^$i|awk '{print $2}'` ;

 

    sed -n  "$st,$en p" /cachelog/log$y$m$d/access.log.0.s >> /cachelog/all/$Domain/access$y$m$d.log ;

  ((i++));

done

exit 0 ;

8、分割日志后,因为其过程会产生的排序文件,文本文件等,要进行清理。并轮询分割后的日志文件夹,以确保只保留最近三天的日志。

[root@www cachelog]# cat clear.sh

#!/bin/bash

y=`date --date='1 days ago' "+%Y"`

m=`date --date='1 days ago' "+%m"`

d=`date --date='1 days ago' "+%d"`

  if [ -d /cachelog/all.2 ]

  then

    /bin/rm -rf /cachelog/all.2

  fi

 

  if [ -d /cachelog/all.1 ]

  then

     /bin/mv /cachelog/all.1 /cachelog/all.2

   fi

     /bin/mv /cachelog/all /cachelog/all.1

 

     /bin/mkdir /cachelog/all

 

/bin/rm -f /cachelog/*.txt

#/bin/rm -f /cachelog/log$y$m$d/access.log.0

#/bin/rm -f /cachelog/log$y$m$d/access.log.1

#/bin/rm -f /cachelog/log$y$m$d/access.log.2

 

#/bin/rm -f /cachelog/log$y$m$d/access.log.0.s

#/bin/rm -f /cachelog/log$y$m$d/access.log.1.s

#/bin/rm -f /cachelog/log$y$m$d/access.log.2.s

9、把这些脚本放到计划任务中,每天凌晨时执行。

Squid日志过大,每天轮询三次,相应的脚本就变成三个,以便能并行处理,缩短分割时间。以下是完整的计划任务列表。

01 12   *  *  *  /usr/local/squid/sbin/squid -k rotate

20 12   *  *   *  /bin/bash   /cachelog/chlog.sh

 

 

01 18   * * * /usr/local/squid/sbin/squid -k rotate

20 18  *  *  *  /bin/bash   /cachelog/chlog1.sh

22 18  *  *  *  /bin/bash   /cachelog/clear.sh

 

01  0   * * * /usr/local/squid/sbin/squid -k rotate

20  0   *  *  *  /bin/bash   /cachelog/chlog2.sh

 

 

01  1  *  *  * /bin/bash   /cachelog/sortlog.sh

02  1  *  *  * /bin/bash   /cachelog/sortlog1.sh

03  1  *  *  * /bin/bash   /cachelog/sortlog2.sh

 

01  2  *  *  *  /bin/bash   /cachelog/get_record_number.sh

02  2  *  *  *  /bin/bash   /cachelog/get_record_number1.sh

03  2  *  *  *  /bin/bash   /cachelog/get_record_number2.sh

 

08  2  *  *  *  /bin/bash   /cachelog/stat_number.sh

09  2  *  *  *  /bin/bash   /cachelog/stat_number1.sh

10  2  *  *  *  /bin/bash   /cachelog/stat_number2.sh

 

12  2  *  *  *  /bin/bash   /cachelog/stat.sh

13  2  *  *  *  /bin/bash   /cachelog/stat1.sh

14  2  *  *  *  /bin/bash   /cachelog/stat2.sh

 

21  2  *  *  *  /bin/bash   /cachelog/get.sh

22  2  *  *  *  /bin/bash   /cachelog/get1.sh

23  2  *  *  *  /bin/bash   /cachelog/get2.sh

9windows日志分析系统每天通过linuxsamba服务同步一次。


阅读(1453) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

liukaiyi2010-09-09 17:02:37

必须定啊

huangxifeng6072008-05-11 15:05:49

写一篇原作不容易,是我的实践经验来的,对你有用.就顶一顶.

评论热议
请登录后评论。

登录 注册