module Base
# Parse a log file
class LogParser
LOG_LINES = {}
# LogParser initializer
# file The fileobject this LogParser wil operate on.
def initialize(file, options = {})
@file_name = file
@options = options
@file_size = File.size(@file_name)
self.initialize_hook(options) if self.respond_to?(:initialize_hook)
end
def progress(&block)
@progress_handler = block
end
# Output a warning
# message The warning message (object)
def warn(message)
puts " -> " + message.to_s
end
def convert_value(value, type)
return case type
when :string; value.to_s
when :int; value.to_i
when :sec; value.to_f
when :msec; value.to_f / 1000
when :timestamp; value.to_s # TODO: fix me?
else
warn("Unkwn type encountered: #{type}")
value
end
end
# Finds a log line and then parses the information in the line.
# Yields a hash containing the information found.
# *line_types The log line types to look for (defaults to LOG_LINES.keys).
# Yeilds a Hash when it encounters a chunk of information.
def each(*line_types, &block)
log_lines_hash = self.class::LOG_LINES
# parse everything by default
line_types = log_lines_hash.keys if line_types.empty?
File.open(@file_name) do |file|
file.each_line do |line|
@progress_handler.call(file.pos, @file_size) if @progress_handler
line_types.each do |line_type|
if log_lines_hash[line_type][:teaser] =~ line
if log_lines_hash[line_type][:regexp] =~ line
captures = $~.captures
request = { :type => line_type, :line => file.lineno }
log_lines_hash[line_type][:params].each_with_index do |paramhash, index|
paramhash.each { |key, type| request[key] = convert_value(captures[index], type) } unless captures[index].nil?
end
yield(request) if block_given?
else
warn("Unparsable #{line_type} line: " + line[0..79]) unless line_type == :failed
end
end
end
end
@progress_handler.call(:finished, @file_size) if @progress_handler
end
end
end
end