讓我們開始強制性要求看你有沒有嘗試過的東西。
可伸縮性在處理日誌文件時是一個大問題,因爲它們可能會變得非常大。擴展格式比標準日誌格式要小,但您仍然需要意識到消耗大量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
循環以找到所需的基礎。
我想知道關於\ t字符在行之間的分割。我實際上並不解析apache日誌。我想通常解析用擴展日誌文件格式寫的東西。 – camwest 2010-07-27 13:22:45
如果文件是嚴格擴展的日誌文件格式,那麼在選項卡上分割應該可以正常工作......直到有人變得可愛並添加一個字段,然後在該字段內添加一個選項卡。在這種情況下,使用顯式字段長度或正則表達式分割字段將更好。 – 2010-07-27 18:22:37
根據此處的規範:僅鼓勵https://www.w3.org/TR/WD-logfile.html 選項卡作爲字段分隔符。從規範:「字段被空白分開,鼓勵使用製表符爲此目的。」 – 2016-05-26 19:14:14