访问日志分析
背景说明
183.14.160.219 - - [25/Jul/2015:11:22:10 +0800] "GET /AwkInAction/section1/chapter_3_1.html?=1437794529940 HTTP/1.1" 200 18325 "http://book.saubcy.com/AwkInAction/" "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0"
50.23.254.154 - - [25/Jul/2015:11:22:28 +0800] "GET /AwkInAction/section_1/chapter_3_1.html HTTP/1.1" 200 18325 "-" "Disqus/1.0"
183.60.70.30 - - [25/Jul/2015:11:28:55 +0800] "GET /js/jquery.touchSwipe.min.js HTTP/1.1" 200 5293 "http://book.saubcy.com/js/jquery.touchSwipe.min.js" "Mozilla/5.0 (Linux; U; Android 4.4.2; zh-cn; GT-I9500 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 MQQBrowser/5.0 QQ-Manager Mobile Safari/537.36"
...
在缺乏独立程序统计上报的情况下,往往nginx access日志就能提供给我们足够的分析数据依据。参考上面的日志样例,提供的信息有:ip、访问时间、请求页面、返回码、文件大小、引用页、客户端浏览器。
我们现在的需求是每天统计日志中昨天出现的浏览器访问占比,然后有针对性的进行页面浏览体验优化。
问题分析
- 因为目前的战点访问量还不大,nginx日志并没有按天进行存储,所以首先就是需要在所有的日志记录中区分出状态的记录行;
- 然后需要取出其中的浏览器客户端字段进行计数;
- 最后计算占比进行输出。
解决方案
BEGIN{ # 根据当前时间计算得到昨天的日期 timestamp = systime(); timeStr = strftime("%H %M %S", timestamp); split(timeStr, values, " "); validTimestamp = timestamp - strtonum(values[1])*60*60 - strtonum(values[2])*60 - strtonum(values[3]) - 1; validTime = strftime("%e/%b/%Y", validTimestamp); print(validTime); } { # 检查日期不为昨天则跳过处理 if ( 0 == index($4, validTime) ) { next; } # 使用新的分隔符分隔记录 split($0, values, "\""); # 过滤其中的机型信息 split(values[6], values, ") "); # 统计计数 ++clients[values[length(values)]]; } END{ # 统计总数 total = 0; for ( client in clients ) { total += clients[client]; } if ( 0 == total ) { exit; } # 计算输出 for ( client in clients ) { precent = (clients[client]/total)*100; printf("%5.2f%%: %s\n", precent, client); } }
$awk -f case_2-1.awk case_2-1.data
程序首先通过当前日期计算出昨天的时间得到用来进行日期过滤的字符串,然后重新拆分记录得到浏览器字段,最后在处理完所有记录后进行统计计算并输出。