Расширенный анализатор формата файла журнала в Ruby - PullRequest
1 голос
/ 27 июля 2010

Я ищу анализатор ruby ​​для расширенного формата файла журнала W3C.

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

В идеале он должен генерировать многомерный массив на основе полей в файле журнала.Я думаю о чем-то похожем на то, как FasterCSV (http://fastercsv.rubyforge.org/) обрабатывает CSV-файлы.

Кто-нибудь знает, существует ли такая библиотека? Если нет, то кто-нибудь может дать совет, как мне ее создать?*

Я почти уверен, что смогу разобраться с манипуляциями со строками, чтобы преобразовать текстовый файл в массив. Я в основном озабочен обработкой больших файлов журналов (поэтому, возможно, мне придется передавать данные обратно на диск или что-то в этом роде)).

С уважением, Кэмерон

1 Ответ

0 голосов
/ 27 июля 2010

Давайте начнем с обязательного запроса, чтобы посмотреть, что вы пытались.

Масштабируемость является большой проблемой при работе с файлами журналов, потому что они могут стать очень большими.Расширенный формат меньше стандартного формата журнала, но все же вы должны знать о возможности использования массовых объемов оперативной памяти.

Вы можете использовать регулярные выражения или простые извлечения подстрок.Извлечения подстроки выполняются быстрее, но им не хватает крутого фактора.

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 в зависимости от того, что вы ищете.

...