




已阅读5页,还剩8页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
处理Apache日志的Bash脚本作者: 阮一峰日期: 2012年1月 6日去年一年,我写了将近100篇网络日志。现在这一年结束了,我要统计访问量排名,看看哪些文章最受欢迎。(隆重预告:本文结尾处将揭晓前5名。)以往,我用的是AWStats日志分析软件。它可以生成很详细的报表,但是不太容易定制,得不到某些想要的信息。所以,我就决定自己写一个Bash脚本,统计服务器的日志,顺便温习一下脚本知识。事实证明,这件事比我预想的难。虽然最终脚本只有20多行,但花了我整整一天,反复查看手册,确认用法和合适的参数。下面就是我的日志分析脚本,虽然它还不是通用的,但是我相信里面用到的命令,足以满足一般的日志分析需求,同时也是很好的学习Bash的实例。如果下面的每一个命令你都知道,我觉得可以堪称熟练使用Bash了。一、操作环境在介绍脚本之前,先讲一下我的服务器环境。我的网络服务器软件是Apache,它会对每一个http请求留下记录,就像下面这一条:9 - - 01/Feb/2011:00:02:09 +0800 GET /blog/2009/11/an_autobiography_of_yang_xianyi.html HTTP/1.1 200 84058 /blog/2009/11/freenomics.html Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:3) Gecko/20101203 Firefox/3.6.13它的意思是2011年2月1日,IP地址为9的访问者,向服务器请求访问网址/blog/2009/11/an_autobiography_of_yang_xianyi.html。当天所有的访问记录,组成一个日志。过去一年,一共生成了365个日志文件。它们存放在12个目录中,每一个目录表示一个月(2011-01、2011-02、.2011-12),里面的日志文件依次为www-01.log、www-02.log、.www-31.log(假定该月有31天)。在不压缩的情况下,365个日志文件加起来,要占掉10GB空间。我的目标就是分析这10GB日志,最后得到一个如下形式的访问量排名:访问量 网址1访问量 网址2访问量 网址3. .二、为什么要用Bash很多计算机语言,都可以用来完成这个任务。但是,如果只是简单的日志分析,我觉得Bash脚本是最合适的工具。主要原因有两个:一是开发快,Bash脚本是各种Linux命令的组合,只要知道这些命令怎么用,就可以写脚本,基本上不用学习新的语法,而且它不用编译,直接运行,可以边写边试,对开发非常友好。二是功能强,Bash脚本的设计目的,就是为了处理输入和输出,尤其是单行的文本,所以非常合适处理日志文件,各种现成的参数加上管道机制,威力无穷。前面已经说过,最终的脚本我只用了20多行,处理10GB的日志,20秒左右就得到了结果。考虑到排序的巨大计算量,这样的结果非常令人满意,充分证明了Bash的威力。三、总体思路我的总体处理思路是这样的:第一步,处理单个日志。统计每一天各篇文章的访问量。第二步,生成月度排名。将每一天的统计结果汇总,得到月度访问量。第三步,生成年度排名。将12个月的统计结果汇总,进行年度访问量的排序。四、处理单个日志以2011年1月1日的日志为例,它在目录2011-01之中,文件名是www-01.log,里面有10万条如下格式的记录:9 - - 01/Feb/2011:00:02:09 +0800 GET /blog/2009/11/an_autobiography_of_yang_xianyi.html HTTP/1.1 200 84058 /blog/2009/11/freenomics.html Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:3) Gecko/20101203 Firefox/3.6.13处理这个日志,我只用了一行代码:awk $9 = 200 print $7 www-01.log | grep -i /blog/2011/.*.html$ | sort | uniq -c | sed s/ */g www-01.log.result它用管道连接了5个命令,每一个都很简单,我们依次来看:(1) awk $9 = 200 print $7 www-01.logawk命令默认用空格,将每一行文本分割成若干个字段。仔细数一下,我们需要的只是第7个字段,即http请求的网址,print $7表示将第7个字段输出,结果就是:/blog/2009/11/an_autobiography_of_yang_xianyi.html考虑到我们只统计成功的请求,因此再加一个限制条件,服务器的状态代码必须是200(表示成功),写成$9 = 200,即第9个字段必须是200,否则不输出第7个字段。更精细的统计,还应该区分网络蜘蛛和真实访问者,由于我想不出简单的分辨方法,这里只好忽略了。(2)grep -i /blog/2011/.*.html$在输出的所有记录的第7个字段之中,并不是每一条记录都需要统计的。根据我的文章的命名特点,它们的网址应该都以/blog/2011/开头,以.html结尾。所以,我用一个正则表达式/blog/2011/.*.html$,找出这些记录。参数i表示不区分大小写。(3)sort这时,所有需要统计的记录应该都列出来了,但是它们的次序是杂乱的。接着,使用sort命令,不过目的不是为了排序,而是把相同的网址排列在一起,为后面使用uniq命令创造条件。(4)uniq -cuniq的作用是过滤重复的记录,只保留一行。c参数的作用,是在每行的开头添加该记录的出现次数。处理之后的输出应该是这样的:32 /blog/2011/01/guidelines_for_english_translations_in_public_places.html32 /blog/2011/01/api_for_google_s_url_shortener.html30 /blog/2011/01/brief_history_of_arm.html它表示以上三篇文章,在1月1日的日志中,分别有32条、32条、30条的访问记录(即访问次数)。(5)sed s/ */g www-01.log.result上一步uniq命令添加的访问次数,是有前导空格的。也就是说,在上例的32、32、30之前有一连串空格,为了后续操作的方便,这里把前导空格删去。sed命令是一个处理行文本的编辑器,s/ */g是一个正则表达式(和*之间有一个空格),表示将行首的连续空格替换为空(即删除)。接着,将排序结果重定向到文件www-01.result。单个日志分析就完成了。五、月度汇总排名经过上一步之后,1月份的31个日志文件,生成了31个对应的分析结果文件。为了汇总整个月的情况,必须把这31个结果文件合并。(6)合并分析结果for i in www-*.log.result do cat $i log.resultdone这是一个循环结构,把所有www-01.log.result形式的文件,都写进log.result文件。然后,我用一行语句,计算月度排名。sort -k2 log.result | uniq -f1 -all-repeated=separate |./log.awk |sort -rn final.log.result这行语句由3个命令和1个awk脚本组成:(7)sort -k2 log.result由于是31个文件汇总,log.result文件里面的记录是无序的,必须用sort命令,将相同网址的记录归类在一起。但是此时,访问次数是第一个字段,网址是第二个字段,因此参数k2表示根据第二个字段进行排序。(8)uniq -f1 -all-repeated=separateuniq的作用是过滤重复的记录,参数f1表示忽略第一个字段(访问次数),只考虑后面的字段(网址);参数表示all-repeated=separate,表示过滤掉所有只出现一次的记录,保留所有重复的记录,并且每一组之间用一个空行分隔。这一步完成以后,输出结果变成如下的形式:617 /blog/2011/01/guidelines_for_english_translations_in_public_places.html455 /blog/2011/01/guidelines_for_english_translations_in_public_places.html223 /blog/2011/01/2010_my_blogging_summary.html253 /blog/2011/01/2010_my_blogging_summary.html相同网址都归在一组,组间用空行分割。为了简洁,上面的例子每一组只包含两条记录,实际上每一组都包含31条记录(分别代表当月每天的访问次数)。(9)log.awk脚本为了将31天的访问次数加总,我动了很多脑筋。最后发现,唯一的方法就是用awk命令,而且必须另写一个awk脚本。#!/usr/bin/awk -fBEGIN RS= #将多行记录的分隔符定为一个空行sum=0 #定义一个表示总和的变量,初值为0for(i=1;i final.log.result对awk脚本的处理结果进行排序,sort默认使用第一个字段,参数r表示逆序,从大往小排;参数n表示以数值形式排序,不以默认的字典形式排序,否则会出现10小于2的结果。排序结果重定向到final.log.result。至此,月度排名完成。六、脚本文件用一个脚本,包含上面两节所有的内容。#!/bin/bashif ls ./*.result & /dev/null #判断当前目录中是否有后缀名为result的文件存在thenrm *.result #如果有的话,删除这些文件fitouch log.result #创建一个空文件for i in www-*.log #遍历当前目录中所有log文件do echo $i . #输出一行字,表示开始处理当前文件awk $9 = 200 print $7 $i|grep -i /blog/2011/.*.html$|sort|uniq -c|sed s/ */g $i.result #生成当前日志的处理结果cat $i.result log.result #将处理结果追加到log.result文件echo $i.result finished #输出一行字,表示结束处理当前文件doneecho final.log.result . #输出一行字,表示最终统计开始sort -
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年事业单位工勤技能-辽宁-辽宁水工监测工一级(高级技师)历年参考题库含答案解析(5套)
- 2025年四川省南充市【辅警协警】笔试预测试题(含答案)
- 2025年辅警招聘考试公安基础知识模拟试卷题后含答案及解析
- 【2024年】山西省吕梁市辅警协警笔试笔试测试卷(含答案)
- 文化创意礼品定制在礼品市场2025年品牌影响力分析报告
- 中医考试题及答案
- 中医考研专业考试题目及答案
- 聚焦2025年二手电商平台信用体系建设与市场竞争力研究报告
- 2025年农业废弃物资源化利用与农村废弃物处理设施升级改造项目建议
- 2025年游戏化营销在品牌传播中的互动性策略与效果优化报告
- 医学技术专业讲解
- 唯奋斗最青春+课件-2026届跨入高三第一课主题班会
- 共青团中央所属事业单位2024年度社会公开招聘笔试备考题库参考答案详解
- 2025年《分级护理制度》考试试题(及答案)
- 高中喀斯特地貌说课课件
- 气候变化与健康课件
- 公司电脑配备管理办法
- 2025年中国花盆人参行业市场发展前景及发展趋势与投资战略研究报告
- 娱乐直播培训课件下载
- 细胞生物学复习资料非常详细
- 临沂在编考试试题及答案
评论
0/150
提交评论