Class: RequestLogAnalyzer::Tracker::Traffic

Inherits:
Base
  • Object
show all
Defined in:
lib/request_log_analyzer/tracker/traffic.rb

Overview

Analyze the average and total traffic of requests

Options

  • :amount The amount of lines in the report

  • :category Proc that handles request categorization for given fileformat (REQUEST_CATEGORIZER)

  • :traffic The field containing the duration in the request hash.

  • :if Proc that has to return !nil for a request to be passed to the tracker.

  • :line_type The line type that contains the duration field (determined by the category proc).

  • :title Title do be displayed above the report

  • :unless Handle request if this proc is false for the handled request.

Instance Attribute Summary collapse

Attributes inherited from Base

#options

Instance Method Summary collapse

Methods inherited from Base

#finalize, #initialize, #setup_should_update_checks!, #should_update?

Constructor Details

This class inherits a constructor from RequestLogAnalyzer::Tracker::Base

Instance Attribute Details

#categoriesObject (readonly)

Returns the value of attribute categories.



15
16
17
# File 'lib/request_log_analyzer/tracker/traffic.rb', line 15

def categories
  @categories
end

Instance Method Details

#average_traffic(cat) ⇒ Object

Get the average duration of a specific category. cat The category



68
69
70
# File 'lib/request_log_analyzer/tracker/traffic.rb', line 68

def average_traffic(cat)
  categories[cat][:cumulative].to_f / categories[cat][:hits]  
end

#cumulative_traffic(cat) ⇒ Object

Get the total duration of a specific category. cat The category



50
51
52
# File 'lib/request_log_analyzer/tracker/traffic.rb', line 50

def cumulative_traffic(cat)
  categories[cat][:cumulative]
end

#format_traffic(bytes) ⇒ Object

Formats the traffic number using x B/kB/MB/GB etc notation



138
139
140
141
142
143
144
145
146
147
# File 'lib/request_log_analyzer/tracker/traffic.rb', line 138

def format_traffic(bytes)
  return "0 B" if bytes.zero?
  case Math.log10(bytes).floor
  when  1...4  then '%d B'  % bytes
  when  4...7  then '%d kB' % (bytes / 1000)
  when  7...10 then '%d MB' % (bytes / 1000_000)
  when 10...13 then '%d GB' % (bytes / 1000_000_000)
  else              '%d TB' % (bytes / 1000_000_000_000)
  end
end

#hits(cat) ⇒ Object

Get the number of hits of a specific category. cat The category



44
45
46
# File 'lib/request_log_analyzer/tracker/traffic.rb', line 44

def hits(cat)
  categories[cat][:hits]
end

#max_traffic(cat) ⇒ Object

Get the maximum duration of a specific category. cat The category



62
63
64
# File 'lib/request_log_analyzer/tracker/traffic.rb', line 62

def max_traffic(cat)
  categories[cat][:max]
end

#min_traffic(cat) ⇒ Object

Get the minimal duration of a specific category. cat The category



56
57
58
# File 'lib/request_log_analyzer/tracker/traffic.rb', line 56

def min_traffic(cat)
  categories[cat][:min]
end

#overall_average_trafficObject

Get the average duration of a all categories.



73
74
75
# File 'lib/request_log_analyzer/tracker/traffic.rb', line 73

def overall_average_traffic
  overall_cumulative_duration.to_f / overall_hits
end

#overall_cumulative_trafficObject

Get the cumlative duration of a all categories.



78
79
80
# File 'lib/request_log_analyzer/tracker/traffic.rb', line 78

def overall_cumulative_traffic
  categories.inject(0) { |sum, (name, cat)| sum + cat[:cumulative] }  
end

#overall_hitsObject

Get the total hits of a all categories.



83
84
85
# File 'lib/request_log_analyzer/tracker/traffic.rb', line 83

def overall_hits
  categories.inject(0) { |sum, (name, cat)| sum + cat[:hits] }
end

#prepareObject

Check if duration and catagory option have been received,



18
19
20
21
22
23
24
25
# File 'lib/request_log_analyzer/tracker/traffic.rb', line 18

def prepare
  raise "No traffic field set up for category tracker #{self.inspect}" unless options[:traffic]
  raise "No categorizer set up for duration tracker #{self.inspect}" unless options[:category]

  @categorizer = options[:category].respond_to?(:call) ? options[:category] : lambda { |request| request[options[:category]] }
  @trafficizer = options[:traffic].respond_to?(:call)  ? options[:traffic]  : lambda { |request| request[options[:traffic]]  }
  @categories = {}
end

#report(output) ⇒ Object

Generate a request duration report to the given output object By default colulative and average duration are generated. Any options for the report should have been set during initialize. output The output object



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/request_log_analyzer/tracker/traffic.rb', line 153

def report(output)

  options[:report] ||= [:cumulative, :average]
  options[:top]    ||= 20
  
  options[:report].each do |report|
    case report
    when :average
      report_table(output, options[:top], :title => "#{title} - top #{options[:top]} by average", :sort => :average) { |cat| cat[:cumulative] / cat[:hits] }  
    when :cumulative
      report_table(output, options[:top], :title => "#{title} - top #{options[:top]} by sum", :sort => :cumulative) { |cat| cat[:cumulative] }
    when :hits
      report_table(output, options[:top], :title => "#{title} - top #{options[:top]} by hits", :sort => :hits) { |cat| cat[:hits] }
    else
      raise "Unknown duration report specified: #{report}!"
    end
  end
  
  output.puts
  output.puts "#{output.colorize(title, :white, :bold)} - observed total: " + output.colorize(format_traffic(overall_cumulative_traffic), :brown, :bold)
end

#report_table(output, amount = 10, options = {}, &block) ⇒ Object

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

* </tt>:title</tt> The title of the table
* </tt>:sort</tt> The key to sort on (:hits, :cumulative, :average, :min or :max)


118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/request_log_analyzer/tracker/traffic.rb', line 118

def report_table(output, amount = 10, options = {}, &block)
  
  output.title(options[:title])
  
  top_categories = @categories.sort { |a, b| yield(b[1]) <=> yield(a[1]) }.slice(0...amount)
  output.table({:title => 'Category', :width => :rest}, 
        {:title => 'Hits',       :align => :right, :highlight => (options[:sort] == :hits), :min_width => 4}, 
        {:title => 'Cumulative', :align => :right, :highlight => (options[:sort] == :cumulative), :min_width => 10}, 
        {:title => 'Average',    :align => :right, :highlight => (options[:sort] == :average), :min_width => 8},
        {:title => 'Min',        :align => :right, :highlight => (options[:sort] == :min)}, 
        {:title => 'Max',        :align => :right, :highlight => (options[:sort] == :max)}) do |rows|
  
    top_categories.each do |(cat, info)|
      rows << [cat, info[:hits], format_traffic(info[:cumulative]), format_traffic((info[:cumulative] / info[:hits]).round),
                format_traffic(info[:min]), format_traffic(info[:max])]
    end
  end
end

#sorted_by(by = nil) ⇒ Object

Return categories sorted by a given key. by The key.



104
105
106
107
108
109
110
# File 'lib/request_log_analyzer/tracker/traffic.rb', line 104

def sorted_by(by = nil) 
  if block_given?
    categories.sort { |a, b| yield(b[1]) <=> yield(a[1]) } 
  else
    categories.sort { |a, b| b[1][by] <=> a[1][by] } 
  end
end

#sorted_by_averageObject

Return categories sorted by cumulative duration.



98
99
100
# File 'lib/request_log_analyzer/tracker/traffic.rb', line 98

def sorted_by_average
  sorted_by { |cat| cat[:cumulative].to_f / cat[:hits] }
end

#sorted_by_cumulativeObject

Return categories sorted by cumulative duration.



93
94
95
# File 'lib/request_log_analyzer/tracker/traffic.rb', line 93

def sorted_by_cumulative
  sorted_by(:cumulative)
end

#sorted_by_hitsObject

Return categories sorted by hits.



88
89
90
# File 'lib/request_log_analyzer/tracker/traffic.rb', line 88

def sorted_by_hits
  sorted_by(:hits)
end

#titleObject

Returns the title of this tracker for reports



176
177
178
# File 'lib/request_log_analyzer/tracker/traffic.rb', line 176

def title
  options[:title]  || 'Request traffic'
end

#to_yaml_objectObject

Returns all the categories and the tracked duration as a hash than can be exported to YAML



181
182
183
184
# File 'lib/request_log_analyzer/tracker/traffic.rb', line 181

def to_yaml_object
  return nil if @categories.empty?
  @categories
end

#update(request) ⇒ Object

Get the duration information fron the request and store it in the different categories. request The request.



29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/request_log_analyzer/tracker/traffic.rb', line 29

def update(request)
  category = @categorizer.call(request)
  traffic  = @trafficizer.call(request)

  if traffic.kind_of?(Numeric) && !category.nil?
    @categories[category] ||= {:hits => 0, :cumulative => 0, :min => traffic, :max => traffic }
    @categories[category][:hits] += 1
    @categories[category][:cumulative] += traffic
    @categories[category][:min] = traffic if traffic < @categories[category][:min]
    @categories[category][:max] = traffic if traffic > @categories[category][:max]
  end
end