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