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.
- data/DESIGN +10 -0
- data/README.rdoc +3 -0
- data/bin/request-log-analyzer +3 -1
- data/lib/cli/progressbar.rb +182 -188
- data/lib/request_log_analyzer/aggregator/base.rb +1 -1
- data/lib/request_log_analyzer/aggregator/database.rb +4 -4
- data/lib/request_log_analyzer/aggregator/echo.rb +3 -5
- data/lib/request_log_analyzer/aggregator/summarizer.rb +26 -21
- data/lib/request_log_analyzer/controller.rb +18 -11
- data/lib/request_log_analyzer/filter/base.rb +3 -0
- data/lib/request_log_analyzer/filter/field.rb +5 -0
- data/lib/request_log_analyzer/filter/timespan.rb +8 -1
- data/lib/request_log_analyzer/output/fixed_width.rb +158 -0
- data/lib/request_log_analyzer/output/html.rb +80 -0
- data/lib/request_log_analyzer/output.rb +39 -0
- data/lib/request_log_analyzer/tracker/base.rb +1 -1
- data/lib/request_log_analyzer/tracker/category.rb +12 -21
- data/lib/request_log_analyzer/tracker/duration.rb +18 -23
- data/lib/request_log_analyzer/tracker/hourly_spread.rb +12 -22
- data/lib/request_log_analyzer/tracker/timespan.rb +10 -10
- data/lib/request_log_analyzer.rb +1 -1
- data/spec/controller_spec.rb +6 -2
- data/tasks/github-gem.rake +41 -7
- metadata +6 -3
- data/lib/cli/bashcolorizer.rb +0 -60
data/DESIGN
CHANGED
@@ -12,3 +12,13 @@ This allows you to easily add extra reports, filters and outputs.
|
|
12
12
|
|
13
13
|
3) Gather output from pipeline.
|
14
14
|
Controller.report
|
15
|
+
|
16
|
+
At the moment the supported sources are file and STDIN.
|
17
|
+
In the future we want to be able to have a generated request database as source.
|
18
|
+
This will make interactive downdrilling possible.
|
19
|
+
|
20
|
+
|
21
|
+
For the report generation output we now use the File and the STDOUT class, as they both support <<.
|
22
|
+
In the future we want to have a OutputFile, OutputSTDOUT and OutputHTML class, so that reports can generate
|
23
|
+
tables, lines and comments and push them into the output class.
|
24
|
+
|
data/README.rdoc
CHANGED
@@ -10,6 +10,8 @@ Merb to produce a performance report. Its purpose is to find what actions are be
|
|
10
10
|
* Fast
|
11
11
|
* MIT licensed
|
12
12
|
|
13
|
+
Request log analyzer was designed and built by Willem van Bergen and Bart ten Brinke.
|
14
|
+
|
13
15
|
== Installation
|
14
16
|
|
15
17
|
Install request-log-analyzer as a Ruby gem:
|
@@ -36,3 +38,4 @@ For more details and available command line options, see the project's wiki:http
|
|
36
38
|
|
37
39
|
* Project wiki at GitHub: http://wiki.github.com/wvanbergen/request-log-analyzer
|
38
40
|
* wvanbergen's blog posts: http://techblog.floorplanner.com/tag/request-log-analyzer
|
41
|
+
* bart ten brinke's blog posts: http://movesonrails.com
|
data/bin/request-log-analyzer
CHANGED
@@ -49,6 +49,7 @@ begin
|
|
49
49
|
command_line.option(:before)
|
50
50
|
|
51
51
|
command_line.switch(:boring, :b)
|
52
|
+
command_line.option(:output, :alias => :o, :default => 'FixedWidth')
|
52
53
|
command_line.option(:report_width, :default => terminal_width - 1)
|
53
54
|
|
54
55
|
command_line.switch(:debug)
|
@@ -73,6 +74,7 @@ rescue CommandLine::Error => e
|
|
73
74
|
puts " --database <filename>, -d: Creates an SQLite3 database of all the parsed request information."
|
74
75
|
puts " --debug Print debug information while parsing."
|
75
76
|
puts " --file <filename> Output to file."
|
77
|
+
puts " --output <format> Output format. Supports 'HTML' and 'FixedWidth' (default)"
|
76
78
|
puts
|
77
79
|
puts "Examples:"
|
78
80
|
puts " request-log-analyzer development.log"
|
@@ -116,7 +118,7 @@ else
|
|
116
118
|
puts "Request log analyzer, by Willem van Bergen and Bart ten Brinke - Version 1.0\n\n"
|
117
119
|
|
118
120
|
# Run the request_log_analyzer!
|
119
|
-
RequestLogAnalyzer::Controller.build(arguments
|
121
|
+
RequestLogAnalyzer::Controller.build(arguments).run!
|
120
122
|
|
121
123
|
puts
|
122
124
|
puts "Thanks for using request-log-analyzer"
|
data/lib/cli/progressbar.rb
CHANGED
@@ -7,230 +7,224 @@
|
|
7
7
|
#
|
8
8
|
# You can redistribute it and/or modify it under the terms
|
9
9
|
# of Ruby's license.
|
10
|
-
#
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
11
|
+
module CommandLine
|
12
|
+
class ProgressBar
|
13
|
+
VERSION = "0.9"
|
14
|
+
|
15
|
+
def initialize (title, total, out = STDERR)
|
16
|
+
@title = title
|
17
|
+
@total = total
|
18
|
+
@out = out
|
19
|
+
@terminal_width = 80
|
20
|
+
@bar_mark = '='
|
21
|
+
@current = 0
|
22
|
+
@previous = 0
|
23
|
+
@finished_p = false
|
24
|
+
@start_time = Time.now
|
25
|
+
@previous_time = @start_time
|
26
|
+
@title_width = 24
|
27
|
+
@format = "%-#{@title_width}s %3d%% %s %s"
|
28
|
+
@format_arguments = [:title, :percentage, :bar, :stat]
|
29
|
+
clear
|
30
|
+
show
|
31
|
+
end
|
32
|
+
attr_reader :title
|
33
|
+
attr_reader :current
|
34
|
+
attr_reader :total
|
35
|
+
attr_accessor :start_time
|
36
|
+
|
37
|
+
private
|
38
|
+
def fmt_bar
|
39
|
+
bar_width = do_percentage * @terminal_width / 100
|
40
|
+
sprintf("[%s%s]",
|
41
|
+
@bar_mark * bar_width,
|
42
|
+
" " * (@terminal_width - bar_width))
|
43
|
+
end
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
def fmt_percentage
|
46
|
+
do_percentage
|
47
|
+
end
|
48
48
|
|
49
|
-
|
50
|
-
|
51
|
-
|
49
|
+
def fmt_stat
|
50
|
+
if @finished_p then elapsed else eta end
|
51
|
+
end
|
52
52
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
53
|
+
def fmt_stat_for_file_transfer
|
54
|
+
if @finished_p then
|
55
|
+
sprintf("%s %s %s", bytes, transfer_rate, elapsed)
|
56
|
+
else
|
57
|
+
sprintf("%s %s %s", bytes, transfer_rate, eta)
|
58
|
+
end
|
58
59
|
end
|
59
|
-
end
|
60
60
|
|
61
|
-
|
62
|
-
|
63
|
-
|
61
|
+
def fmt_title
|
62
|
+
@title[0,(@title_width - 1)] + ":"
|
63
|
+
end
|
64
64
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
65
|
+
def convert_bytes (bytes)
|
66
|
+
if bytes < 1024
|
67
|
+
sprintf("%6dB", bytes)
|
68
|
+
elsif bytes < 1024 * 1000 # 1000kb
|
69
|
+
sprintf("%5.1fKB", bytes.to_f / 1024)
|
70
|
+
elsif bytes < 1024 * 1024 * 1000 # 1000mb
|
71
|
+
sprintf("%5.1fMB", bytes.to_f / 1024 / 1024)
|
72
|
+
else
|
73
|
+
sprintf("%5.1fGB", bytes.to_f / 1024 / 1024 / 1024)
|
74
|
+
end
|
74
75
|
end
|
75
|
-
end
|
76
76
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
77
|
+
def transfer_rate
|
78
|
+
bytes_per_second = @current.to_f / (Time.now - @start_time)
|
79
|
+
sprintf("%s/s", convert_bytes(bytes_per_second))
|
80
|
+
end
|
81
81
|
|
82
|
-
|
83
|
-
|
84
|
-
|
82
|
+
def bytes
|
83
|
+
convert_bytes(@current)
|
84
|
+
end
|
85
85
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
86
|
+
def format_time (t)
|
87
|
+
t = t.to_i
|
88
|
+
sec = t % 60
|
89
|
+
min = (t / 60) % 60
|
90
|
+
hour = t / 3600
|
91
|
+
sprintf("%02d:%02d:%02d", hour, min, sec);
|
92
|
+
end
|
93
93
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
94
|
+
# ETA stands for Estimated Time of Arrival.
|
95
|
+
def eta
|
96
|
+
if @current == 0
|
97
|
+
"ETA: --:--:--"
|
98
|
+
else
|
99
|
+
elapsed = Time.now - @start_time
|
100
|
+
eta = elapsed * @total / @current - elapsed;
|
101
|
+
sprintf("ETA: %s", format_time(eta))
|
102
|
+
end
|
102
103
|
end
|
103
|
-
end
|
104
104
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
105
|
+
def elapsed
|
106
|
+
elapsed = Time.now - @start_time
|
107
|
+
sprintf("Time: %s", format_time(elapsed))
|
108
|
+
end
|
109
109
|
|
110
|
-
|
111
|
-
|
112
|
-
end
|
113
|
-
|
114
|
-
def do_percentage
|
115
|
-
if @total.zero?
|
116
|
-
100
|
117
|
-
else
|
118
|
-
@current * 100 / @total
|
110
|
+
def eol
|
111
|
+
if @finished_p then "\n" else "\r" end
|
119
112
|
end
|
120
|
-
end
|
121
113
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
begin
|
126
|
-
tiocgwinsz = 0x5413
|
127
|
-
data = [0, 0, 0, 0].pack("SSSS")
|
128
|
-
if @out.ioctl(tiocgwinsz, data) >= 0 then
|
129
|
-
rows, cols, xpixels, ypixels = data.unpack("SSSS")
|
130
|
-
if cols >= 0 then cols else default_width end
|
114
|
+
def do_percentage
|
115
|
+
if @total.zero?
|
116
|
+
100
|
131
117
|
else
|
132
|
-
|
118
|
+
@current * 100 / @total
|
133
119
|
end
|
134
|
-
rescue Exception
|
135
|
-
default_width
|
136
120
|
end
|
137
|
-
end
|
138
121
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
@terminal_width += width - line.length + 1
|
155
|
-
show
|
122
|
+
def get_width
|
123
|
+
# FIXME: I don't know how portable it is.
|
124
|
+
default_width = 80
|
125
|
+
begin
|
126
|
+
tiocgwinsz = 0x5413
|
127
|
+
data = [0, 0, 0, 0].pack("SSSS")
|
128
|
+
if @out.ioctl(tiocgwinsz, data) >= 0 then
|
129
|
+
rows, cols, xpixels, ypixels = data.unpack("SSSS")
|
130
|
+
if cols >= 0 then cols else default_width end
|
131
|
+
else
|
132
|
+
default_width
|
133
|
+
end
|
134
|
+
rescue Exception
|
135
|
+
default_width
|
136
|
+
end
|
156
137
|
end
|
157
|
-
@previous_time = Time.now
|
158
|
-
end
|
159
138
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
139
|
+
def show
|
140
|
+
arguments = @format_arguments.map {|method|
|
141
|
+
method = sprintf("fmt_%s", method)
|
142
|
+
send(method)
|
143
|
+
}
|
144
|
+
line = sprintf(@format, *arguments)
|
145
|
+
|
146
|
+
width = get_width
|
147
|
+
if line.length == width - 1
|
148
|
+
@out.print(line + eol)
|
149
|
+
@out.flush
|
150
|
+
elsif line.length >= width
|
151
|
+
@terminal_width = [@terminal_width - (line.length - width + 1), 0].max
|
152
|
+
if @terminal_width == 0 then @out.print(line + eol) else show end
|
153
|
+
else # line.length < width - 1
|
154
|
+
@terminal_width += width - line.length + 1
|
155
|
+
show
|
156
|
+
end
|
157
|
+
@previous_time = Time.now
|
167
158
|
end
|
168
159
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
160
|
+
def show_if_needed
|
161
|
+
if @total.zero?
|
162
|
+
cur_percentage = 100
|
163
|
+
prev_percentage = 0
|
164
|
+
else
|
165
|
+
cur_percentage = (@current * 100 / @total).to_i
|
166
|
+
prev_percentage = (@previous * 100 / @total).to_i
|
167
|
+
end
|
168
|
+
|
169
|
+
# Use "!=" instead of ">" to support negative changes
|
170
|
+
if cur_percentage != prev_percentage ||
|
171
|
+
Time.now - @previous_time >= 1 || @finished_p
|
172
|
+
show
|
173
|
+
end
|
173
174
|
end
|
174
|
-
end
|
175
175
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
176
|
+
public
|
177
|
+
def clear
|
178
|
+
@out.print "\r"
|
179
|
+
@out.print(" " * (get_width - 1))
|
180
|
+
@out.print "\r"
|
181
|
+
end
|
182
182
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
183
|
+
def finish
|
184
|
+
@current = @total
|
185
|
+
@finished_p = true
|
186
|
+
show
|
187
|
+
end
|
188
188
|
|
189
|
-
|
190
|
-
|
191
|
-
|
189
|
+
def finished?
|
190
|
+
@finished_p
|
191
|
+
end
|
192
192
|
|
193
|
-
|
194
|
-
|
195
|
-
|
193
|
+
def file_transfer_mode
|
194
|
+
@format_arguments = [:title, :percentage, :bar, :stat_for_file_transfer]
|
195
|
+
end
|
196
196
|
|
197
|
-
|
198
|
-
|
199
|
-
|
197
|
+
def format= (format)
|
198
|
+
@format = format
|
199
|
+
end
|
200
200
|
|
201
|
-
|
202
|
-
|
203
|
-
|
201
|
+
def format_arguments= (arguments)
|
202
|
+
@format_arguments = arguments
|
203
|
+
end
|
204
204
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
205
|
+
def halt
|
206
|
+
@finished_p = true
|
207
|
+
show
|
208
|
+
end
|
209
209
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
210
|
+
def inc (step = 1)
|
211
|
+
@current += step
|
212
|
+
@current = @total if @current > @total
|
213
|
+
show_if_needed
|
214
|
+
@previous = @current
|
215
|
+
end
|
216
216
|
|
217
|
-
|
218
|
-
|
219
|
-
|
217
|
+
def set (count)
|
218
|
+
count = 0 if count < 0
|
219
|
+
count = @total if count > @total
|
220
220
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
def inspect
|
227
|
-
"#<ProgressBar:#{@current}/#{@total}>"
|
228
|
-
end
|
229
|
-
end
|
221
|
+
@current = count
|
222
|
+
show_if_needed
|
223
|
+
@previous = @current
|
224
|
+
end
|
230
225
|
|
231
|
-
|
232
|
-
|
233
|
-
|
226
|
+
def inspect
|
227
|
+
"#<ProgressBar:#{@current}/#{@total}>"
|
228
|
+
end
|
234
229
|
end
|
235
230
|
end
|
236
|
-
|
@@ -50,13 +50,13 @@ module RequestLogAnalyzer::Aggregator
|
|
50
50
|
end
|
51
51
|
|
52
52
|
# Prints a short report of what has been inserted into the database
|
53
|
-
def report(output
|
54
|
-
output
|
55
|
-
|
53
|
+
def report(output)
|
54
|
+
output.title('Request database created')
|
55
|
+
|
56
56
|
output << "A database file has been created with all parsed request information.\n"
|
57
57
|
output << "#{@request_count} requests have been added to the database.\n"
|
58
58
|
output << "To execute queries on this database, run the following command:\n"
|
59
|
-
output << " $ sqlite3 #{options[:database]}\n"
|
59
|
+
output << output.colorize(" $ sqlite3 #{options[:database]}\n", :bold)
|
60
60
|
output << "\n"
|
61
61
|
end
|
62
62
|
|
@@ -14,11 +14,9 @@ module RequestLogAnalyzer::Aggregator
|
|
14
14
|
@warnings << "WARNING #{type.inspect} on line #{lineno}: #{message}\n"
|
15
15
|
end
|
16
16
|
|
17
|
-
def report(output
|
18
|
-
output
|
19
|
-
output
|
20
|
-
output << green("━" * report_width, color) + "\n"
|
21
|
-
output << @warnings + "\n"
|
17
|
+
def report(output)
|
18
|
+
output.title("Warnings during parsing")
|
19
|
+
output.puts @warnings
|
22
20
|
end
|
23
21
|
|
24
22
|
end
|
@@ -67,36 +67,41 @@ module RequestLogAnalyzer::Aggregator
|
|
67
67
|
@trackers.each { |tracker| tracker.finalize }
|
68
68
|
end
|
69
69
|
|
70
|
-
def report(output
|
71
|
-
report_header(output
|
70
|
+
def report(output)
|
71
|
+
report_header(output)
|
72
72
|
if source.parsed_requests > 0
|
73
|
-
@trackers.each { |tracker| tracker.report(output
|
73
|
+
@trackers.each { |tracker| tracker.report(output) }
|
74
74
|
else
|
75
|
-
output
|
76
|
-
output
|
75
|
+
output.puts
|
76
|
+
output.puts('There were no requests analyzed.')
|
77
77
|
end
|
78
|
-
report_footer(output
|
78
|
+
report_footer(output)
|
79
79
|
end
|
80
80
|
|
81
|
-
def report_header(output
|
82
|
-
output
|
83
|
-
|
84
|
-
output
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
81
|
+
def report_header(output)
|
82
|
+
output.title("Request summary")
|
83
|
+
|
84
|
+
output.with_style(:cell_separator => false) do
|
85
|
+
output.table({:width => 20}, {:font => :bold}) do |rows|
|
86
|
+
rows << ['Parsed lines:', source.parsed_lines]
|
87
|
+
rows << ['Parsed request:', source.parsed_requests]
|
88
|
+
rows << ['Skipped lines:', source.skipped_lines]
|
89
|
+
|
90
|
+
rows << ["Warnings:", @warnings_encountered.map { |(key, value)| "#{key.inspect}: #{value}" }.join(', ')] if has_warnings?
|
91
|
+
end
|
89
92
|
end
|
90
93
|
output << "\n"
|
91
94
|
end
|
92
95
|
|
93
|
-
def report_footer(output
|
94
|
-
|
95
|
-
|
96
|
-
output
|
97
|
-
|
98
|
-
output
|
99
|
-
output
|
96
|
+
def report_footer(output)
|
97
|
+
if has_serious_warnings?
|
98
|
+
|
99
|
+
output.title("Parse warnings")
|
100
|
+
|
101
|
+
output.puts "Multiple warnings were encountered during parsing. Possibly, your logging "
|
102
|
+
output.puts "is not setup correctly. Visit this website for logging configuration tips:"
|
103
|
+
output.puts output.link("http://github.com/wvanbergen/request-log-analyzer/wikis/configure-logging")
|
104
|
+
output.puts
|
100
105
|
end
|
101
106
|
end
|
102
107
|
|
@@ -29,17 +29,19 @@ module RequestLogAnalyzer
|
|
29
29
|
# Builds a RequestLogAnalyzer::Controller given parsed command line arguments
|
30
30
|
# <tt>arguments<tt> A CommandLine::Arguments hash containing parsed commandline parameters.
|
31
31
|
# <rr>report_with</tt> Width of the report. Defaults to 80.
|
32
|
-
def self.build(arguments
|
33
|
-
|
34
|
-
options = { :report_width => arguments[:report_width].to_i, :output => STDOUT}
|
32
|
+
def self.build(arguments)
|
33
|
+
options = { }
|
35
34
|
|
36
35
|
options[:database] = arguments[:database] if arguments[:database]
|
37
36
|
options[:debug] = arguments[:debug]
|
38
|
-
options[:colorize] = !arguments[:boring]
|
39
37
|
|
38
|
+
output_class = RequestLogAnalyzer::Output::const_get(arguments[:output])
|
40
39
|
if arguments[:file]
|
41
|
-
|
42
|
-
options[:
|
40
|
+
output_file = File.new(arguments[:file], "w+")
|
41
|
+
options[:output] = output_class.new(output_file, :width => 80, :color => false, :characters => :ascii)
|
42
|
+
else
|
43
|
+
options[:output] = output_class.new(STDOUT, :width => arguments[:report_width].to_i,
|
44
|
+
:color => !arguments[:boring], :characters => (arguments[:boring] ? :ascii : :utf))
|
43
45
|
end
|
44
46
|
|
45
47
|
# Create the controller with the correct file format
|
@@ -129,7 +131,7 @@ module RequestLogAnalyzer
|
|
129
131
|
def handle_progress(message, value = nil)
|
130
132
|
case message
|
131
133
|
when :started
|
132
|
-
@progress_bar = ProgressBar.new(
|
134
|
+
@progress_bar = CommandLine::ProgressBar.new(File.basename(value), File.size(value))
|
133
135
|
when :finished
|
134
136
|
@progress_bar.finish
|
135
137
|
@progress_bar = nil
|
@@ -176,6 +178,8 @@ module RequestLogAnalyzer
|
|
176
178
|
# 6. Finalize Source
|
177
179
|
def run!
|
178
180
|
|
181
|
+
|
182
|
+
|
179
183
|
@filters.each { |filter| filter.prepare }
|
180
184
|
@aggregators.each { |agg| agg.prepare }
|
181
185
|
|
@@ -189,12 +193,15 @@ module RequestLogAnalyzer
|
|
189
193
|
puts "Caught interrupt! Stopped parsing."
|
190
194
|
end
|
191
195
|
|
192
|
-
puts "\n"
|
193
|
-
|
194
196
|
@aggregators.each { |agg| agg.finalize }
|
195
|
-
|
196
|
-
|
197
|
+
|
198
|
+
@output.header
|
199
|
+
@aggregators.each { |agg| agg.report(@output) }
|
200
|
+
@output.footer
|
201
|
+
|
197
202
|
@source.finalize
|
203
|
+
|
204
|
+
|
198
205
|
end
|
199
206
|
|
200
207
|
end
|
@@ -17,9 +17,12 @@ module RequestLogAnalyzer
|
|
17
17
|
register_file_format(format)
|
18
18
|
end
|
19
19
|
|
20
|
+
# Initialize the filter
|
20
21
|
def prepare
|
21
22
|
end
|
22
23
|
|
24
|
+
# Return the request if the request should be kept.
|
25
|
+
# Return nil otherwise.
|
23
26
|
def filter(request)
|
24
27
|
return nil unless request
|
25
28
|
return request
|