gpt4 book ai didi

ruby - 在 Ruby 中解析 A​​pache 格式的 URL

转载 作者:太空宇宙 更新时间:2023-11-03 18:30:03 26 4
gpt4 key购买 nike

我如何获取 Apache 通用日志文件并以整洁的直方图形式列出其中的所有 URL,例如:

/favicon.ico                      ##
/manual/mod/mod_autoindex.html #
/ruby/faq/Windows/ ##
/ruby/faq/Windows/index.html #
/ruby/faq/Windows/RubyonRails #
/ruby/rubymain.html #
/robots.txt ########

测试文件示例:

65.54.188.137 - - [03/Sep/2006:03:50:20 -0400] "GET /~longa/geomed/ppa/doc/localg/localg.htm HTTP/1.0" 200 24834
65.54.188.137 - - [03/Sep/2006:03:50:32 -0400] "GET /~longa/geomed/modules/sv/scen1.html HTTP/1.0" 200 1919
65.54.188.137 - - [03/Sep/2006:03:53:51 -0400] "GET /~longa/xlispstat/code/statistics/introstat/axis/code/axisDens.lsp HTTP/1.0" 200 15962
65.54.188.137 - - [03/Sep/2006:04:03:03 -0400] "GET /~longa/geomed/modules/cluster/lab/nm.pop HTTP/1.0" 200 66302
65.54.188.137 - - [03/Sep/2006:04:11:15 -0400] "GET /~longa/geomed/data/france/names.txt HTTP/1.0" 200 20706
74.129.13.176 - - [03/Sep/2006:04:14:35 -0400] "GET /~jbyoder/ambiguouslyyours/ambig.rss HTTP/1.1" 304 -

这是我现在拥有的(但我不确定如何制作直方图):

...
---

$apache_line = /\A(?<ip_address>\S+) \S+ \S+ \[(?<time>[^\]]+)\] "(?<method>GET|POST) (?<url>\S+) \S+?" (?<status>\d+) (?<bytes>\S+)/
$parts = apache_line.match(file)
$p parts[:ip_address], parts[:status], parts[:method], parts[:url]

def get_url(file)
hits = Hash.new {|h,k| h[k]=0}
File.read(file).to_a.each do |line|
while $p parts[:url]
if k = k
h[k]+=1
puts "%-15s %s" % [k,'#'*h[k]]
end
end
end

...
---

这是完整的问题:http://pastebin.com/GRPS6cTZ伪代码就可以了。

最佳答案

  1. 您可以创建一个散列,将每个路径映射到命中数。为方便起见,我建议在请求以前未见过的路径时使用将值设置为 0 的哈希。例如:

    hits = Hash.new{ |h,k| h[k]=0 }
    ...
    hits["/favicon.ico"] += 1
    hits["/ruby/faq/Windows/"] += 1
    hits["/favicon.ico"] += 1
    p hits
    #=> {"/favicon.ico"=>2, "/ruby/faq/Windows/"=>1}
  2. 如果日志文件真的很大,与其将整个文件塞进内存,不如一次处理一行。 (查看 File 类的方法。)

  3. 因为 Apache 日志文件格式没有标准分隔符,我建议使用正则表达式来获取每一行并将其分成您想要的 block 。假设您使用的是 Ruby 1.9,稍后我将使用命名捕获来干净地访问这些方法。例如:

    apache_line = /\A(?<ip_address>\S+) \S+ \S+ \[(?<time>[^\]]+)\] "(?<method>GET|POST) (?<url>\S+) \S+?" (?<status>\d+) (?<bytes>\S+)/
    ...
    parts = apache_line.match(log_line)
    p parts[:ip_address], parts[:status], parts[:method], parts[:url]
  4. 您可能希望选择根据状态代码过滤这些。例如,您是否希望在图表中包含有人输入错误的所有 404 匹配项?如果您没有将所有行都存入内存,则不会使用 Array#select 而是在循环期间跳过它们。

  5. 收集完所有匹配项后,就可以写出结果了。一些有用的提示:

    1. Hash#keys 可以一次为您提供数组(路径)的所有键。您可能想用相同数量的空格写出所有路径,因此您需要找出最长的路径。也许您想将路径 map 到它们的长度,然后获取 max 元素,或者您可能想使用 max_by找到最长的路径,然后找到它的长度。

    2. 虽然极客,但使用 sprintfString#% 是布置格式化报告的好方法。例如:

      puts "%-15s %s" % ["Hello","####"]
      #=> "Hello ####"
    3. 就像您需要找到最长的名称以获得良好的格式一样,您可能想要找到点击次数最多的 URL,这样您就可以将最长的哈希值扩展到该值。 Hash#values 将为您提供一个包含所有值的数组。或者,您可能要求一个 # 必须始终代表 100 次匹配,或者类似的东西。

    4. 请注意,String#* 可让您通过重复创建字符串:

      p '#'*10
      #=> "##########"

如果您对代码有具体问题,请提出更多问题!

关于ruby - 在 Ruby 中解析 A​​pache 格式的 URL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5560796/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com