#!/usr/bin/env ruby require "pp" class RailsLog class ServerRequest attr_reader :raw_data,:ip,:date,:time,:http_type,:session_id,:parameters,:method,:controller,:request_per_second attr_reader :total_request_time,:total_db_time,:total_render_time,:requested_uri,:response_code,:date_time attr_reader :renders,:sql_statements,:stacktrace,:error_message,:log_body def initialize(raw_string) @raw_data=raw_string #data that might not be there in the parse @request_per_second = '' @total_request_time = '' @total_render_time = '' @total_db_time = '' @requested_uri = '' @response_code = '' @error_message = '' @stacktrace = [] parse_data end def <=>(other) date_time <=> other.date_time end def error? @error_message!="" end private def parse_data temp_array = @raw_data.match(/\(for.*\)/).to_s.gsub(/\(|\)/,"").split @ip = temp_array[1] @date = temp_array[3] @time = temp_array[4] @date_time = DateTime.parse(@date+" "+@time) if @date && @time @http_type = @raw_data.match(/\[(GET|POST|PUT|DELETE|HEAD|OPTION)\]/).to_s.gsub(/\[|\]/,"").downcase @session_id = @raw_data.match(/Session ID: .*/).to_s @parameters = @raw_data.match(/Parameters: \{.*\}/).to_s.match(/\{.*\}/).to_s temp_array = @raw_data.match(/Processing [^\s]*/).to_s.split("#") @method = temp_array.last @controller = temp_array[0].split.last temp_raw_data = @raw_data.gsub(/Processing.*Parameters: \{[^\}]*\}/m,"") if regx= temp_raw_data.match(/Completed.*\]/m) complete_line=regx.to_s.split('|') temp_raw_data.sub!(/Completed.*\]/m,"") @request_per_second =complete_line[0].match(/\((\d*|,\d*)/).to_s.sub('(','').to_i if complete_line[0] @total_request_time = complete_line[0].split('(').first.split.last if complete_line[0] @total_render_time = complete_line[1].split('(').first.split.last if complete_line[1] @total_db_time = complete_line[2].split('(').first.split.last if complete_line[2] @requested_uri = complete_line[3].split.last.gsub(/(\[|\])/,"") if complete_line[3] @response_code = complete_line[3].split('[').first.strip if complete_line[3] end #should be just raw message @log_body = temp_raw_data @renders = temp_raw_data.scan(/Rendering .*/) @sql_statements = temp_raw_data.scan(/1m.*/) if message = temp_raw_data.match(/^\w(\w|:)*Error\s\(.*\):/m) @error_message = message #an array @stacktrace = temp_raw_data.match(/^\w(\w|:)*Error\s\(.*\):.*\n/m).to_s.split("\n").delete_if{|line| !line.match(/:\d*:/)} end end end attr_reader :file class << self def parse(file) RailsLog.new(file) end end def initialize(log_file) @file = log_file @requests = [] load_requests end def request_list @requests end def total_errors @requests.select{|x| x.error?}.size end def size @requests.size end def average_request_time count = 0 time = 0.0 @requests.each{|x| if x.total_request_time!="" time += x.total_request_time.to_f count += 1 end } puts time puts count time/count end alias_method :count,:size def error_precentage total_errors/size.to_f end def session_id_list @requests.collect{|x| x.session_id}.uniq end def requested_uri_count hash ={} @requests.each{|x| if hash[x.requested_uri] hash[x.requested_uri]+=1 else hash[x.requested_uri]=1 end } hash end private def load_requests f = File.open(@file,"r") string=f.read f.close string.split("Processing ").each{|request| @requests.push(ServerRequest.new("Processing "+request)) } end end x = RailsLog.new("/home/sbecker/svn/development.log") puts x.request_list[1].method puts x.error_precentage puts x.average_request_time puts x.session_id_list.size pp x.requested_uri_count