request-log-analyzer 1.0.4 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,6 +9,7 @@ module RequestLogAnalyzer::Filter
9
9
 
10
10
  attr_reader :field, :value, :mode
11
11
 
12
+ # Setup mode, field and value.
12
13
  def prepare
13
14
  @mode = (@options[:mode] || :accept).to_sym
14
15
  @field = @options[:field].to_sym
@@ -21,6 +22,10 @@ module RequestLogAnalyzer::Filter
21
22
  end
22
23
  end
23
24
 
25
+ # Keep request if @mode == :select and request has the field and value.
26
+ # Drop request if @mode == :reject and request has the field and value.
27
+ # Returns nil otherwise.
28
+ # <tt>request</tt> Request Object
24
29
  def filter(request)
25
30
  return nil unless request
26
31
 
@@ -8,12 +8,19 @@ module RequestLogAnalyzer::Filter
8
8
 
9
9
  attr_reader :before, :after
10
10
 
11
+ # Convert the timestamp to the correct formats for quick timestamp comparisons.
12
+ # These are stored in the before and after attr_reader fields.
11
13
  def prepare
12
- # Convert the timestamp to the correct formats for quick timestamp comparisons
13
14
  @after = @options[:after].strftime('%Y%m%d%H%M%S').to_i if options[:after]
14
15
  @before = @options[:before].strftime('%Y%m%d%H%M%S').to_i if options[:before]
15
16
  end
16
17
 
18
+ # Returns request if:
19
+ # * @after <= request.timestamp <= @before
20
+ # * @after <= request.timestamp
21
+ # * request.timestamp <= @before
22
+ # Returns nil otherwise
23
+ # <tt>request</tt> Request object.
17
24
  def filter(request)
18
25
  return nil unless request
19
26
 
@@ -0,0 +1,158 @@
1
+ class RequestLogAnalyzer::Output::FixedWidth < RequestLogAnalyzer::Output
2
+
3
+ module Monochrome
4
+ def colorize(text, *options)
5
+ text
6
+ end
7
+ end
8
+
9
+ module Color
10
+
11
+ STYLES = { :normal => 0, :bold => 1, :underscore => 4, :blink => 5, :inverse => 7, :concealed => 8 }
12
+ COLORS = { :black => 0, :blue => 4, :green => 2, :cyan => 6, :red => 1, :purple => 5, :brown => 3, :white => 7 }
13
+
14
+ def colorize(text, *options)
15
+
16
+ font_style = ''
17
+ foreground_color = '0'
18
+ background_color = ''
19
+
20
+ options.each do |option|
21
+ if option.kind_of?(Symbol)
22
+ foreground_color = "3#{COLORS[option]}" if COLORS.include?(option)
23
+ font_style = "#{STYLES[option]};" if STYLES.include?(option)
24
+ elsif option.kind_of?(Hash)
25
+ options.each do |key, value|
26
+ case key
27
+ when :color; foreground_color = "3#{COLORS[value]}" if COLORS.include?(value)
28
+ when :background; background_color = "4#{COLORS[value]};" if COLORS.include?(value)
29
+ when :on; background_color = "4#{COLORS[value]};" if COLORS.include?(value)
30
+ when :style; font_style = "#{STYLES[value]};" if STYLES.include?(value)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ return "\e[#{background_color}#{font_style}#{foreground_color}m#{text}\e[0m"
36
+ end
37
+
38
+ end
39
+
40
+ attr_reader :characters
41
+
42
+ CHARACTERS = {
43
+ :ascii => { :horizontal_line => '-', :vertical_line => '|', :block => '=' },
44
+ :utf => { :horizontal_line => '━', :vertical_line => '┃', :block => '░' }
45
+ }
46
+
47
+ def initialize(io, options = {})
48
+ super(io, options)
49
+ @options[:width] ||= 80
50
+ @options[:characters] ||= :utf
51
+ @characters = CHARACTERS[@options[:characters]]
52
+
53
+ color_module = @options[:color] ? Color : Monochrome
54
+ (class << self; self; end).send(:include, color_module)
55
+ end
56
+
57
+ def print(str)
58
+ @io << str
59
+ end
60
+
61
+ alias :<< :print
62
+
63
+ def puts(str = '')
64
+ @io << str << "\n"
65
+ end
66
+
67
+ def title(title)
68
+ puts
69
+ puts colorize(title, :bold, :white)
70
+ line(:green)
71
+ end
72
+
73
+ def line(*font)
74
+ puts colorize(characters[:horizontal_line] * @options[:width], *font)
75
+ end
76
+
77
+ def link(text, url = nil)
78
+ if url.nil?
79
+ colorize(text, :blue, :bold)
80
+ else
81
+ "#{text} (#{colorize(url, :blue, :bold)})"
82
+ end
83
+ end
84
+
85
+ def table(*columns, &block)
86
+
87
+ rows = Array.new
88
+ yield(rows)
89
+
90
+ # determine maximum cell widths
91
+ max_cell_widths = rows.inject(Array.new(columns.length, 0)) do |result, row|
92
+ lengths = row.map { |column| column.to_s.length }
93
+ result.each_with_index { |length, index| result[index] = ([length, lengths[index]].max rescue length) }
94
+ end
95
+ columns.each_with_index { |col, index| col[:actual_width] ||= max_cell_widths[index] }
96
+
97
+ # determine actual column width
98
+ column_widths = columns.map do |column|
99
+ if column[:width] == :rest
100
+ nil
101
+ elsif column[:width]
102
+ column[:width]
103
+ elsif column[:min_width]
104
+ [column[:min_width], column[:actual_width]].max
105
+ elsif column[:max_width]
106
+ [column[:max_width], column[:actual_width]].min
107
+ else
108
+ column[:actual_width]
109
+ end
110
+ end
111
+
112
+ if column_widths.include?(nil)
113
+ width_left = options[:width] - ((columns.length - 1) * (style[:cell_separator] ? 3 : 1)) - column_widths.compact.inject(0) { |sum, col| sum + col}
114
+ column_widths[column_widths.index(nil)] = width_left
115
+ end
116
+
117
+ # Print table header
118
+ if table_has_header?(columns)
119
+ column_titles = []
120
+ columns.each_with_index do |column, index|
121
+ width = column_widths[index]
122
+ alignment = (column[:align] == :right ? '' : '-')
123
+ column_titles.push(colorize("%#{alignment}#{width}s" % column[:title].to_s[0...width], :bold))
124
+ end
125
+
126
+ puts
127
+ puts column_titles.join(style[:cell_separator] ? " #{characters[:vertical_line]} " : ' ')
128
+ line(:green)
129
+ end
130
+
131
+ rows.each do |row|
132
+ row_values = []
133
+ columns.each_with_index do |column, index|
134
+ width = column_widths[index]
135
+ case column[:type]
136
+ when :ratio
137
+ if width > 4
138
+ if column[:treshold] && column[:treshold] < row[index].to_f
139
+ bar = ''
140
+ bar << characters[:block] * (width.to_f * column[:treshold]).round
141
+ bar << colorize(characters[:block] * (width.to_f * (row[index].to_f - column[:treshold])).round, :red)
142
+ row_values.push(bar)
143
+ else
144
+ row_values.push(characters[:block] * (width.to_f * row[index].to_f).round)
145
+ end
146
+ else
147
+ row_values.push('')
148
+ end
149
+ else
150
+ alignment = (columns[index][:align] == :right ? '' : '-')
151
+ row_values.push("%#{alignment}#{width}s" % row[index].to_s[0...width])
152
+ end
153
+ end
154
+ puts row_values.join(style[:cell_separator] ? " #{characters[:vertical_line]} " : ' ')
155
+ end
156
+ end
157
+
158
+ end
@@ -0,0 +1,80 @@
1
+ class RequestLogAnalyzer::Output::HTML < RequestLogAnalyzer::Output
2
+
3
+ # def initialize(io, options = {})
4
+ # super(io, options)
5
+ # end
6
+
7
+ def print(str)
8
+ @io << str
9
+ end
10
+
11
+ alias :<< :print
12
+
13
+ def puts(str = '')
14
+ @io << str << "<br />\n"
15
+ end
16
+
17
+ def title(title)
18
+ @io.puts(tag(:h2, title))
19
+ end
20
+
21
+ def line(*font)
22
+ @io.puts(tag(:hr))
23
+ end
24
+
25
+ def link(text, url = nil)
26
+ url = text if url.nil?
27
+ tag(:a, text, :href => url)
28
+ end
29
+
30
+ def table(*columns, &block)
31
+ rows = Array.new
32
+ yield(rows)
33
+
34
+ @io << tag(:table) do |content|
35
+ if table_has_header?(columns)
36
+ content << tag(:tr) do
37
+ columns.map { |col| tag(:th, col[:title]) }.join("\n")
38
+ end
39
+ end
40
+
41
+ rows.each do |row|
42
+ content << tag(:tr) do
43
+ row.map { |cell| tag(:td, cell) }.join("\n")
44
+ end
45
+ end
46
+ end
47
+
48
+ end
49
+
50
+ def header
51
+ @io << "<html>"
52
+ @io << tag(:head) do |headers|
53
+ headers << tag(:title, 'Request-log-analyzer report')
54
+ end
55
+ @io << '<body>'
56
+ end
57
+
58
+ def footer
59
+ @io << "</body></html>\n"
60
+ end
61
+
62
+ protected
63
+
64
+ def tag(tag, content = nil, attributes = nil)
65
+ if block_given?
66
+ attributes = content.nil? ? '' : ' ' + content.map { |(key, value)| "#{key}=\"#{value}\"" }.join(' ')
67
+ content_string = ''
68
+ content = yield(content_string)
69
+ content = content_string unless content_string.empty?
70
+ "<#{tag}#{attributes}>#{content}</#{tag}>"
71
+ else
72
+ attributes = attributes.nil? ? '' : ' ' + attributes.map { |(key, value)| "#{key}=\"#{value}\"" }.join(' ')
73
+ if content.nil?
74
+ "<#{tag}#{attributes} />"
75
+ else
76
+ "<#{tag}#{attributes}>#{content}</#{tag}>"
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,39 @@
1
+ module RequestLogAnalyzer
2
+
3
+ class Output
4
+
5
+ attr_accessor :io, :options, :style
6
+
7
+ def self.const_missing(const)
8
+ filename = const.to_s.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').tr("-", "_").downcase
9
+ require File.dirname(__FILE__) + '/output/' + filename
10
+ self.const_get(const)
11
+ end
12
+
13
+ def initialize(io, options = {})
14
+ @io = io
15
+ @options = options
16
+ @style = options[:style] || { :cell_separator => true, :table_border => false }
17
+ end
18
+
19
+ def with_style(temp_style = {})
20
+ old_style = @style
21
+ @style = @style.merge(temp_style)
22
+ yield(self) if block_given?
23
+ @style = old_style
24
+ end
25
+
26
+ def header
27
+ end
28
+
29
+ def footer
30
+ end
31
+
32
+ protected
33
+
34
+ def table_has_header?(columns)
35
+ columns.any? { |column| !column[:title].nil? }
36
+ end
37
+
38
+ end
39
+ end
@@ -44,7 +44,7 @@ module RequestLogAnalyzer
44
44
  return true
45
45
  end
46
46
 
47
- def report(output=STDOUT, report_width = 80, color = false)
47
+ def report(output)
48
48
  output << self.inspect
49
49
  output << "\n"
50
50
  end
@@ -14,11 +14,11 @@ module RequestLogAnalyzer::Tracker
14
14
  #
15
15
  # Example output:
16
16
  # HTTP methods
17
- # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
18
- # GET 22248 hits (46.2%) ┃░░░░░░░░░░░░░░░░░
19
- # PUT 13685 hits (28.4%) ┃░░░░░░░░░░░
20
- # POST 11662 hits (24.2%) ┃░░░░░░░░░
21
- # DELETE 512 hits (1.1%)
17
+ # ----------------------------------------------------------------------
18
+ # GET | 22248 hits (46.2%) |░░░░░░░░░░░░░░░░░
19
+ # PUT | 13685 hits (28.4%) |░░░░░░░░░░░
20
+ # POST | 11662 hits (24.2%) |░░░░░░░░░
21
+ # DELETE | 512 hits (1.1%) |
22
22
  class Category < RequestLogAnalyzer::Tracker::Base
23
23
 
24
24
  attr_reader :categories
@@ -39,12 +39,9 @@ module RequestLogAnalyzer::Tracker
39
39
  end
40
40
  end
41
41
 
42
- def report(output = STDOUT, report_width = 80, color = false)
43
- if options[:title]
44
- output << "\n#{options[:title]}\n"
45
- output << green(('━' * report_width), color) + "\n"
46
- end
47
-
42
+ def report(output)
43
+ output.title(options[:title]) if options[:title]
44
+
48
45
  if @categories.empty?
49
46
  output << "None found.\n"
50
47
  else
@@ -52,18 +49,12 @@ module RequestLogAnalyzer::Tracker
52
49
  total_hits = sorted_categories.inject(0) { |carry, item| carry + item[1] }
53
50
  sorted_categories = sorted_categories.slice(0...options[:amount]) if options[:amount]
54
51
 
55
- adjuster = color ? 33 : 24 # justifcation calcultaion is slight different when color codes are inserterted
56
- max_cat_length = [sorted_categories.map { |c| c[0].to_s.length }.max, report_width - adjuster].min
57
- sorted_categories.each do |(cat, count)|
58
- text = "%-#{max_cat_length+1}s┃%7d hits %s" % [cat.to_s[0..max_cat_length], count, (green("(%0.01f%%)", color) % [(count.to_f / total_hits) * 100])]
59
- space_left = report_width - (max_cat_length + adjuster + 3)
60
- if space_left > 3
61
- bar_chars = (space_left * (count.to_f / total_hits)).round
62
- output << "%-#{max_cat_length + adjuster}s %s%s" % [text, '┃', '░' * bar_chars] + "\n"
63
- else
64
- output << text + "\n"
52
+ output.table({:align => :left}, {:align => :right }, {:align => :right}, {:type => :ratio, :width => :rest}) do |rows|
53
+ sorted_categories.each do |(cat, count)|
54
+ rows << [cat, "#{count} hits", '%0.1f%%' % ((count.to_f / total_hits.to_f) * 100.0), (count.to_f / total_hits.to_f)]
65
55
  end
66
56
  end
57
+
67
58
  end
68
59
  end
69
60
 
@@ -2,7 +2,7 @@ module RequestLogAnalyzer::Tracker
2
2
 
3
3
  # Analyze the duration of a specific attribute
4
4
  #
5
- # Accepts the following options:
5
+ # Options:
6
6
  # * <tt>:line_type</tt> The line type that contains the duration field (determined by the category proc).
7
7
  # * <tt>:if</tt> Proc that has to return !nil for a request to be passed to the tracker.
8
8
  # * <tt>:title</tt> Title do be displayed above the report
@@ -13,11 +13,11 @@ module RequestLogAnalyzer::Tracker
13
13
  # The items in the update request hash are set during the creation of the Duration tracker.
14
14
  #
15
15
  # Example output:
16
- # Request duration - top 20 by cumulative time Hits Sum. | Avg.
17
- # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
18
- # EmployeeController#show.html [GET] 4742 4922.56s 1.04s
19
- # EmployeeController#update.html [POST] 4647 2731.23s 0.59s
20
- # EmployeeController#index.html [GET] 5802 1477.32s 0.25s
16
+ # Request duration - top 20 by cumulative time | Hits | Sum. | Avg.
17
+ # ---------------------------------------------------------------------------------
18
+ # EmployeeController#show.html [GET] | 4742 | 4922.56s | 1.04s
19
+ # EmployeeController#update.html [POST] | 4647 | 2731.23s | 0.59s
20
+ # EmployeeController#index.html [GET] | 5802 | 1477.32s | 0.25s
21
21
  # .............
22
22
  class Duration < RequestLogAnalyzer::Tracker::Base
23
23
  attr_reader :categories
@@ -40,25 +40,20 @@ module RequestLogAnalyzer::Tracker
40
40
  end
41
41
  end
42
42
 
43
- def report_table(output = STDOUT, amount = 10, options = {}, &block)
43
+ def report_table(output, amount = 10, options = {}, &block)
44
44
 
45
45
  top_categories = @categories.sort { |a, b| yield(b[1]) <=> yield(a[1]) }.slice(0...amount)
46
- max_cat_length = top_categories.map { |a| a[0].length }.max || 0
47
- space_left = [options[:report_width] - 33, [max_cat_length + 1, options[:title].length].max].min
48
-
49
- output << "\n"
50
- output << "%-#{space_left+1}s┃ Hits ┃ Sum. | Avg." % [options[:title][0...space_left]] + "\n"
51
- output << green('━' * options[:report_width], options[:color]) + "\n"
52
-
53
- top_categories.each do |(cat, info)|
54
- hits = info[:count]
55
- total = "%0.02f" % info[:total_duration]
56
- avg = "%0.02f" % (info[:total_duration] / info[:count])
57
- output << "%-#{space_left+1}s┃%8d ┃%9ss ┃%9ss" % [cat[0...space_left], hits, total, avg] + "\n"
46
+ output.table({:title => options[:title]}, {:title => 'Hits', :align => :right, :min_width => 4},
47
+ {:title => 'Cumulative', :align => :right, :min_width => 10}, {:title => 'Average', :align => :right, :min_width => 8}) do |rows|
48
+
49
+ top_categories.each do |(cat, info)|
50
+ rows << [cat, info[:count], "%0.02fs" % info[:total_duration], "%0.02fs" % (info[:total_duration] / info[:count])]
51
+ end
58
52
  end
53
+
59
54
  end
60
55
 
61
- def report(output = STDOUT, report_width = 80, color = false)
56
+ def report(output)
62
57
 
63
58
  options[:title] ||= 'Request duration'
64
59
  options[:report] ||= [:total, :average]
@@ -67,11 +62,11 @@ module RequestLogAnalyzer::Tracker
67
62
  options[:report].each do |report|
68
63
  case report
69
64
  when :average
70
- report_table(output, options[:top], :title => "#{options[:title]} - top #{options[:top]} by average time", :color => color, :report_width => report_width) { |request| request[:total_duration] / request[:count] }
65
+ report_table(output, options[:top], :title => "#{options[:title]} - top #{options[:top]} by average time") { |request| request[:total_duration] / request[:count] }
71
66
  when :total
72
- report_table(output, options[:top], :title => "#{options[:title]} - top #{options[:top]} by cumulative time", :color => color, :report_width => report_width) { |request| request[:total_duration] }
67
+ report_table(output, options[:top], :title => "#{options[:title]} - top #{options[:top]} by cumulative time") { |request| request[:total_duration] }
73
68
  when :hits
74
- report_table(output, options[:top], :title => "#{options[:title]} - top #{options[:top]} by hits", :color => color, :report_width => report_width) { |request| request[:count] }
69
+ report_table(output, options[:top], :title => "#{options[:title]} - top #{options[:top]} by hits") { |request| request[:count] }
75
70
  else
76
71
  output << "Unknown duration report specified\n"
77
72
  end
@@ -12,7 +12,7 @@ module RequestLogAnalyzer::Tracker
12
12
  #
13
13
  # Example output:
14
14
  # Requests graph - average per day per hour
15
- # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
15
+ # --------------------------------------------------
16
16
  # 7:00 - 330 hits : ░░░░░░░
17
17
  # 8:00 - 704 hits : ░░░░░░░░░░░░░░░░░
18
18
  # 9:00 - 830 hits : ░░░░░░░░░░░░░░░░░░░░
@@ -44,37 +44,27 @@ module RequestLogAnalyzer::Tracker
44
44
  @last = timestamp if @last.nil? || timestamp > @last
45
45
  end
46
46
 
47
- def report(output = STDOUT, report_width = 80, color = false)
48
- output << "\n"
49
- output << "Requests graph - average per day per hour\n"
50
- output << green("━" * report_width, color) + "\n"
47
+ def report(output)
48
+ output.title("Requests graph - average per day per hour")
51
49
 
52
50
  if @request_time_graph == [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
53
51
  output << "None found.\n"
54
52
  return
55
53
  end
56
54
 
57
- first_date = DateTime.parse(@first.to_s, '%Y%m%d%H%M%S')
58
- last_date = DateTime.parse(@last.to_s, '%Y%m%d%H%M%S')
59
- days = (@last && @first) ? (last_date - first_date).ceil : 1
60
- deviation = @request_time_graph.max / 20
61
- deviation = 1 if deviation == 0
62
- color_cutoff = 15
55
+ first_date = DateTime.parse(@first.to_s, '%Y%m%d%H%M%S')
56
+ last_date = DateTime.parse(@last.to_s, '%Y%m%d%H%M%S')
57
+ days = (@last && @first) ? (last_date - first_date).ceil : 1
58
+ total_requests = @request_time_graph.inject(0) { |sum, value| sum + value }
63
59
 
64
- @request_time_graph.each_with_index do |requests, index|
65
- display_chars = requests / deviation
66
- request_today = requests / days
60
+ output.table({}, {:align => :right}, {:type => :ratio, :width => :rest, :treshold => 0.15}) do |rows|
61
+ @request_time_graph.each_with_index do |requests, index|
62
+ ratio = requests.to_f / total_requests.to_f
63
+ requests_per_day = requests / days
67
64
 
68
- if display_chars >= color_cutoff
69
- display_chars_string = green(('░' * color_cutoff), color) + red(('░' * (display_chars - color_cutoff)), color)
70
- else
71
- display_chars_string = green(('░' * display_chars), color)
65
+ rows << ["#{index.to_s.rjust(3)}:00", "#{requests_per_day} hits", ratio]
72
66
  end
73
-
74
- output << "#{index.to_s.rjust(3)}:00 - #{(request_today.to_s + ' hits').ljust(15)} : #{display_chars_string}\n"
75
67
  end
76
- output << "\n"
77
-
78
68
  end
79
69
  end
80
70
  end
@@ -31,23 +31,23 @@ module RequestLogAnalyzer::Tracker
31
31
  @last = timestamp if @last.nil? || timestamp > @last
32
32
  end
33
33
 
34
- def report(output = STDOUT, report_width = 80, color = false)
35
- if options[:title]
36
- output << "\n#{options[:title]}\n"
37
- output << green('━' * options[:title].length, color) + "\n"
38
- end
34
+ def report(output)
35
+ output.title(options[:title]) if options[:title]
39
36
 
40
37
  first_date = DateTime.parse(@first.to_s, '%Y%m%d%H%M%S') rescue nil
41
38
  last_date = DateTime.parse(@last.to_s, '%Y%m%d%H%M%S') rescue nil
42
39
 
43
40
  if @last && @first
44
41
  days = (@last && @first) ? (last_date - first_date).ceil : 1
45
-
46
- output << "First request: #{first_date.strftime('%Y-%m-%d %H:%M:%I')}\n"
47
- output << "Last request: #{last_date.strftime('%Y-%m-%d %H:%M:%I')}\n"
48
- output << "Total time analyzed: #{days} days\n"
42
+
43
+ output.with_style(:cell_separator => false) do
44
+ output.table({:width => 20}, {}) do |rows|
45
+ rows << ['First request:', first_date.strftime('%Y-%m-%d %H:%M:%I')]
46
+ rows << ['Last request:', last_date.strftime('%Y-%m-%d %H:%M:%I')]
47
+ rows << ['Total time analyzed:', "#{days} days"]
48
+ end
49
+ end
49
50
  end
50
- output << "\n"
51
51
 
52
52
  end
53
53
  end
@@ -1,6 +1,5 @@
1
1
  require 'date'
2
2
  require File.dirname(__FILE__) + '/cli/progressbar'
3
- require File.dirname(__FILE__) + '/cli/bashcolorizer'
4
3
 
5
4
  require File.dirname(__FILE__) + '/request_log_analyzer/file_format'
6
5
  require File.dirname(__FILE__) + '/request_log_analyzer/line_definition'
@@ -12,3 +11,4 @@ require File.dirname(__FILE__) + '/request_log_analyzer/filter/base'
12
11
  require File.dirname(__FILE__) + '/request_log_analyzer/controller'
13
12
  require File.dirname(__FILE__) + '/request_log_analyzer/source/base'
14
13
  require File.dirname(__FILE__) + '/request_log_analyzer/source/log_file'
14
+ require File.dirname(__FILE__) + '/request_log_analyzer/output'
@@ -10,9 +10,14 @@ describe RequestLogAnalyzer::Controller do
10
10
  # end
11
11
 
12
12
  it "should call the aggregators when run" do
13
+
14
+ mock_output = mock('output')
15
+ mock_output.should_receive(:header)
16
+ mock_output.should_receive(:footer)
17
+
13
18
  file_format = RequestLogAnalyzer::FileFormat.load(:rails)
14
19
  source = RequestLogAnalyzer::Source::LogFile.new(file_format, :source_files => log_fixture(:rails_1x))
15
- controller = RequestLogAnalyzer::Controller.new(source)
20
+ controller = RequestLogAnalyzer::Controller.new(source, :output => mock_output)
16
21
 
17
22
  mock_aggregator = mock('aggregator')
18
23
  mock_aggregator.should_receive(:prepare).once.ordered
@@ -26,7 +31,6 @@ describe RequestLogAnalyzer::Controller do
26
31
  another_mock_aggregator.should_receive(:finalize).once.ordered
27
32
  another_mock_aggregator.should_receive(:report).once.ordered
28
33
 
29
-
30
34
  controller.aggregators << mock_aggregator << another_mock_aggregator
31
35
  controller.run!
32
36
  end