module RequestLogAnalyzer::Tracker # Get highest count of a specific attribute class Count < Base include RequestLogAnalyzer::Tracker::StatisticsTracking attr_reader :categories def prepare raise "No categorizer set up for category tracker #{self.inspect}" unless options[:category] raise "No field to count has been set up #{self.inspect}" unless options[:field] @categorizer = create_lambda(options[:category]) @counter = create_lambda(options[:field]) @categories = {} end # Get the duration information fron the request and store it in the different categories. # request The request. def update(request) category = @categorizer.call(request) count = @counter.call(request) update_statistics(category, count) if count.kind_of?(Numeric) && !category.nil? end def report(output) sortings = output.options[:sort] || [:sum, :mean] sortings.each do |report| case report when :mean report_table(output, :mean, :title => "#{title} - sorted by mean") when :stddev report_table(output, :stddev, :title => "#{title} - sorted by standard deviation") when :sum report_table(output, :sum, :title => "#{title} - sorted by sum") when :hits report_table(output, :hits, :title => "#{title} - sorted by hits") else raise "Unknown duration report specified: #{report}!" end end end # Block function to build a result table using a provided sorting function. # output The output object. # amount The number of rows in the report table (default 10). # === Options # * :title The title of the table # * :sort The key to sort on (:hits, :cumulative, :average, :min or :max) def report_table(output, sort, options = {}, &block) output.puts top_categories = output.slice_results(sorted_by(sort)) output.with_style(:top_line => true) do output.table(*statistics_header(:title => options[:title],:highlight => sort)) do |rows| top_categories.each { |(cat, info)| rows.push(statistics_row(cat)) } end end output.puts end # Format an int to a nice string with decimal seperation. # Also see http://en.wikipedia.org/wiki/Terabyte # count the value to reduce def display_value(count) return "- " if count.nil? return "0 " if count.zero? case Math.log10(count).floor when 1...4 then '%d ' % count when 4...7 then '%dk' % (count / 1000) when 7...10 then '%dM' % (count / 1000_000) when 10...13 then '%dG' % (count / 1000_000_000) when 13...16 then '%dT' % (count / 1000_000_000_000) else '%dP' % (count / 1000_000_000_000_000) end end # Returns the title of this tracker for reports def title options[:title] || 'Total' end # Returns all the categories and the tracked duration as a hash than can be exported to YAML def to_yaml_object return nil if @categories.empty? @categories end end end