Ruby 中的扩展日志文件格式解析器

发布于 2024-09-11 08:36:14 字数 475 浏览 2 评论 0原文

我正在寻找适用于 W3C 扩展日志文件格式的 ruby​​ 解析器。

http://www.w3.org/TR/WD-logfile.html

理想情况下,它会根据日志文件中的字段生成一个多维数组。我正在考虑类似于 FasterCSV (http://fastercsv.rubyforge.org/) 处理 CSV 的方式文件。

有谁知道这样的图书馆是否存在?如果没有,有人可以就我如何构建一个提供建议吗?

我非常确定我可以弄清楚将文本文件转换为数组的字符串操作。我最关心的是处理大量日志文件(因此我可能需要将数据流回磁盘或其他东西)。

真挚地, 卡梅伦

I'm looking for a ruby parser for the W3C Extended Log File Format.

http://www.w3.org/TR/WD-logfile.html

Ideally it would generate a multidimensional array based on the fields in the log file. I'm thinking something similar to how FasterCSV (http://fastercsv.rubyforge.org/) handles CSV files.

Does anyone know if such a library exists? If not could anyone provide advice on how I would build one?

I am pretty sure I can figure out the string manipulation to convert the text file into an array. I'm mostly concerned about handling massive log files (so potentially I'd need to stream the data back to disk or something).

Sincerely,
Cameron

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

三月梨花 2024-09-18 08:36:14

让我们从强制性请求开始,看看您已经尝试过什么。

处理日志文件时,可伸缩性是一个大问题,因为它们可能会变得非常大。扩展格式比标准日志格式小,但您仍然必须意识到消耗大量 RAM 的可能性。

您可以使用正则表达式或简单的子字符串提取。子字符串提取速度更快,但缺乏酷感。

require 'benchmark'

TIME_REGEX     = /(\d\d:\d\d:\d\d)/
ACTION_REGEX   = /(\w+)/
FILEPATH_REGEX = /(\S+)/

ary = %(#Version: 1.0
#Date: 12-Jan-1996 00:00:00
#Fields: time cs-method cs-uri
00:34:23 GET /foo/bar.html
12:21:16 GET /foo/bar.html
12:45:52 GET /foo/bar.html
12:57:34 GET /foo/bar.html
).split(/\n+/)

n = 50000
Benchmark.bm(6) do |x|
  x.report('regex') do
    n.times do
      ary.each do |l|
        next if l[/^#/]
        l.strip!
        # l[/^ #{ TIME_REGEX } \s #{ ACTION_REGEX } \s #{ FILEPATH_REGEX } $/ix]
        # l =~ /^ #{ TIME_REGEX } \s #{ ACTION_REGEX } \s #{ FILEPATH_REGEX } $/ix
        l =~ /^ #{ TIME_REGEX } \s #{ ACTION_REGEX } \s #{ FILEPATH_REGEX } $/iox
        timestamp, action, filepath = $1, $2, $3
      end
    end
  end

  x.report('substr') do
    n.times do
      ary.each do |l|  
        next if l[/^#/]
        l.strip!
        timestamp = l[0, 8]
        action    = l[9, 3]
        filepath  = l[14 .. -1]
      end
    end
  end
end

# >>             user     system      total        real
# >> regex   1.220000   0.000000   1.220000 (  1.235210)
# >> substr  0.800000   0.010000   0.810000 (  0.804276)

尝试运行不同的正则表达式,看看细微的变化如何在运行时产生巨大的差异。

在基准代码的正则表达式和子字符串版本中,您可以提取 ary.each do 循环作为您要查找的内容的基础。

Let's start with the obligatory request to see what you have tried.

Scalability is a big issue when dealing with log files because they can get very big. The extended format is smaller than the standard log format but still you have to be aware of the potential for consumption of mass quantities of RAM.

You can use regular expressions or simple substring extracts. Substring extracts are faster but lack the cool-factor.

require 'benchmark'

TIME_REGEX     = /(\d\d:\d\d:\d\d)/
ACTION_REGEX   = /(\w+)/
FILEPATH_REGEX = /(\S+)/

ary = %(#Version: 1.0
#Date: 12-Jan-1996 00:00:00
#Fields: time cs-method cs-uri
00:34:23 GET /foo/bar.html
12:21:16 GET /foo/bar.html
12:45:52 GET /foo/bar.html
12:57:34 GET /foo/bar.html
).split(/\n+/)

n = 50000
Benchmark.bm(6) do |x|
  x.report('regex') do
    n.times do
      ary.each do |l|
        next if l[/^#/]
        l.strip!
        # l[/^ #{ TIME_REGEX } \s #{ ACTION_REGEX } \s #{ FILEPATH_REGEX } $/ix]
        # l =~ /^ #{ TIME_REGEX } \s #{ ACTION_REGEX } \s #{ FILEPATH_REGEX } $/ix
        l =~ /^ #{ TIME_REGEX } \s #{ ACTION_REGEX } \s #{ FILEPATH_REGEX } $/iox
        timestamp, action, filepath = $1, $2, $3
      end
    end
  end

  x.report('substr') do
    n.times do
      ary.each do |l|  
        next if l[/^#/]
        l.strip!
        timestamp = l[0, 8]
        action    = l[9, 3]
        filepath  = l[14 .. -1]
      end
    end
  end
end

# >>             user     system      total        real
# >> regex   1.220000   0.000000   1.220000 (  1.235210)
# >> substr  0.800000   0.010000   0.810000 (  0.804276)

Try running the different regular expressions to see how subtle changes can make a big difference in run-time.

In both the regex and substring versions of the benchmark code you can extract the ary.each do loops for the basis of what you are looking for.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文