加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

用perl对CDN节点日志进行统计

发布时间:2020-12-16 00:37:15 所属栏目:大数据 来源:网络整理
导读:前段时间公司运维部门要求我对CDN节点的日志进行分析,具体要求如下 1、输入参数为文件名,支持统配。文件为gz压缩,可用zcat解压。统配的多个文件, 必须是一天内的。 2、文件内为一条条的访问日志。格式如下: 2011-01-02 15:55:01 122.245.127.73 "/down.

前段时间公司运维部门要求我对CDN节点的日志进行分析,具体要求如下
1、输入参数为文件名,支持统配。文件为gz压缩,可用zcat解压。统配的多个文件,
必须是一天内的。
2、文件内为一条条的访问日志。格式如下:
2011-01-02 15:55:01 122.245.127.73
"/down.eebbk.net/xzzx/h1sp/xb8xdfxd6xd0xc9xfaxcexefxb1xd8xd0xde2
xc8xbexc9xabxccxe5xb1xe4xd2xec(xb6xfe).avi" 206 11568567 3316812
" http://www.eebbk.com/downlist.asp?sid=12814&classid=17356&tinyclassid=17374
&dhbig=xbbxc6xb8xd4xbfxcexccxc3&dhsmall=xb8xdfxd6xd0xb1xd8xd0
xde2&dhtiny=xc9xfaxcexef&title=xcaxd3xc6xb5xd1xa7xcfxb0xbbxfa
H1&mode=6846" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET
CLR 1.1.4322; .NET CLR 2.0.50727)"
3、该条日志中,2011-01-02 15:55:01 为日志时间点。其基准时间点的计算方法为,
将该时间点转换为标准的秒,再模300,得到基准时间点。如15:55。再比如,
18:23:08,其基准时间点位18:20。
4、该条日志中,表示应用层在3316812 毫秒,输出了11568567 字节。该信息折算到日
志统计上,是按如下处理:
--3316812 毫秒为 3316812/300000+1 = 11+1 = 12个日志计费点。(每个日志计费点
代表一个5分钟的区间)
--11568567字节平均分到12个日志计费点上,为该记录在该计费点上的带宽占用。如
11568567/12/300=3213bps
5、则该日志的流量将给15:00、15:05、15:10、15:15、15:20、15:25、15:30、
15:35、15:40、15:45、15:50、15:55这12个基准时间点,每个增加3123bps的值。
6、要求统计所有指定日志文件综合的各基准时间点的带宽
7、将各基准时间点的带宽值以如下格式输出显示:
time???? bps
00:00?? 1903342
00:05?? 1833133
....
23:55?? 2312342
Total Traffic
?
8、由于该程序将是手动运行在Apache服务器上的。所以程序要轻量级,同时不用占用
太多的磁盘。或许比较理想的是直接处理zcat的输出。(服务器上没有php)
我花了5个小时,先写出了一个单线程的程序,后来又改为多线程,感觉用perl写起来比较快,之间学会了用parsewords进行解析日志,parsewords太好用了。
执行命令:perl?analy_log.pl?CT-ZHZ-1-N004-A-bbg04_2011010414*
测试结果,分析几十M的压缩日志,才2秒多

?

代码如下:

?

 
 
  1. use?Text::ParseWords; ?
  2. use?threads; ?
  3. use?threads::shared; ?
  4. use?Time::Local; ?
  5. #print?@ARGV; ?
  6. ?
  7. #分析结果集 ?
  8. ?
  9. my?%result:shared; ?
  10. #最大线程数 ?
  11. ?
  12. my?$max_thread?=?2; ?
  13. #线程池 ?
  14. ?
  15. my?@thread_array; ?
  16. my?$current_thread?=?0; ?
  17. ?
  18. #检查参数 ?
  19. ?
  20. $argv_len?=?@ARGV; ?
  21. if($argv_len?==?0) ?
  22. { ?
  23. ????print?"it?need?filenamen"; ?
  24. ????exit(1); ?
  25. } ?
  26. ?
  27. #处理参数开始 ?
  28. ?
  29. $cmd="ls?'".join("'?'",@ARGV)."'?|"; ?
  30. #print?$cmd."n"; ?
  31. ?
  32. ?
  33. #处理参数结束 ?
  34. ?
  35. ?
  36. open(PIPE,?$cmd);? ?
  37. @filenames?=?<PIPE>;? ?
  38. close(PIPE); ?
  39. #print?"["; ?
  40. ?
  41. #print?@filenames; ?
  42. ?
  43. #print?"]n"; ?
  44. ?
  45. ?
  46. #多线程分析多个日志文件 ?
  47. ?
  48. foreach(@filenames){? ?
  49. ????if(?$current_thread?>=?$max_thread?) ?
  50. ??{ ?
  51. ????foreach?my?$thread(?@thread_array?) ?
  52. ????{ ?
  53. ??????$thread?->?join(?); ?
  54. ????} ?
  55. ????$current_thread?=?0; ?
  56. ????@thread_array=(); ?
  57. ??} ?
  58. ??$thread_array[$current_thread]?=?threads?->?new(&;analy,$_); ?
  59. ??$current_thread?++;? ?
  60. } ?
  61. ?
  62. #等待线程结束 ?
  63. ?
  64. foreach?my?$thread(?@thread_array?) ?
  65. { ?
  66. ???$thread?->?join(); ?
  67. } ?
  68. ?
  69. #按时间排序输出 ?
  70. ?
  71. my?@key=sort(keys(%result)); ?
  72. print?"timetttbpsn"; ?
  73. foreach?(@key){? ?
  74. ????????$k=$_; ?
  75. ????????print?$k."tt".$result{$k}."n"; ?
  76. } ?
  77. ?
  78. #去除前后空白字符 ?
  79. ?
  80. sub?trim ?
  81. { ?
  82. ????????my?$string?=?shift; ?
  83. ????????$string?=~?s/^s+//; ?
  84. ????????$string?=~?s/s+$//; ?
  85. ????????return?$string; ?
  86. } ?
  87. ?
  88. #分析一个日志文件 ?
  89. ?
  90. sub?analy ?
  91. { ?
  92. ????my?$filename=?trim(shift); ?
  93. ????$cmd="zcat?$filename?|"; ?
  94. ????open(PIPEFILE,$cmd); ?
  95. ????@lines=<PIPEFILE>; ?
  96. ????close(PIPEFILE); ?
  97. ????foreach(@lines) ?
  98. ????{ ?
  99. ????????#分解每一行 ?
  100. ?
  101. ????????my?@line=quotewords("?",?1,?$_); ?
  102. ????????#print?join(",",@line)."n"; ?
  103. ?
  104. ????????#print?$line[6]."n"; ?
  105. ?
  106. ???????? ?
  107. ????????#根据时间合并 ?
  108. ?
  109. ????????my($h,$m)=split(/:/g,$line[1]); ?
  110. ????????my($y,$mon,$d)=split(/-/g,$line[0]); ?
  111. ????????$m=int($m/5)*5; ?
  112. ????????my?$point=int($line[6]/300000+1); ?
  113. ????????my?$bps=int($line[5]/$point/300); ?
  114. ?????#print?$line[0].$line[1]."?m=$m,point=$point,bps=$bpsn"; ?
  115. ?
  116. ????????$endtime=timelocal(0,$m,$h,$d,$y-1900);#秒,分,时,日,月,年(year-1900) ?
  117. ?
  118. ????????my?@time_list=get_time_list($endtime,$point); ?
  119. ????????#累计字节数 ?
  120. ?
  121. ????????my?$i=0; ?
  122. ????????for($i=0;$i<$point;$i++) ?
  123. ????????{ ?
  124. ????????????$result{$time_list[$i]}+=$bps; ?
  125. ????????} ?
  126. ????} ?
  127. } ?
  128. #获得时间列表 ?
  129. ?
  130. sub?get_time_list ?
  131. { ?
  132. ????my?$endtime=trim(shift); ?
  133. ????my?$point=trim(shift); ?
  134. ????my?@time_list; ?
  135. ????my?$i=0; ?
  136. ????for($i=0;$i<$point;$i++) ?
  137. ????{ ?
  138. ????????push(@time_list,get_time_str($endtime)); ?
  139. ????????$endtime-=300; ?
  140. ????} ?
  141. ????@time_list; ?
  142. } ?
  143. #获得时间字符串 ?
  144. ?
  145. sub?get_time_str ?
  146. { ?
  147. ????my?$endtime=trim(shift); ?
  148. ????#@t=gmtime($endtime); ?
  149. ?
  150. ????($sec,?$min,?$hour,?$day,?$mon,?$year,?$wday,?$yday,?$isdst)?=?localtime($endtime); ?
  151. ????if($min<10) ?
  152. ????{ ?
  153. ????????$min="0$min"; ?
  154. ????} ?
  155. ????if($hour<10) ?
  156. ????{ ?
  157. ????????$hour="0$hour"; ?
  158. ????} ?
  159. ????if($day<10) ?
  160. ????{ ?
  161. ????????$day="0$day"; ?
  162. ????} ?
  163. ????if($mon<10) ?
  164. ????{ ?
  165. ????????$mon="0$mon"; ?
  166. ????} ?
  167. ????$year+=1900; ?
  168. ????my?$str="$year-$mon-$day_$hour:$min"; ?
  169. }?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读