production_log_analyzer 1.1.0 → 1.2.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/README CHANGED
@@ -26,7 +26,7 @@ http://rubyforge.org/frs/?group_id=586
26
26
 
27
27
  Either:
28
28
 
29
- A syslogd that doesn't suck. This means that +man syslog.conf+ shows a
29
+ A syslogd that doesn't suck. This means that syslog.conf(5) shows a
30
30
  !prog specification. (FreeBSD's syslogd doesn't suck, but OS X's syslogd
31
31
  does.)
32
32
 
@@ -62,60 +62,96 @@ If you want, you can run it from a cron something like this:
62
62
 
63
63
  /usr/bin/gzip -dc /var/log/production.log.0.gz | /usr/local/bin/pl_analyze /dev/stdin
64
64
 
65
+ Or, have pl_analyze email you (which is preferred, because tabs get preserved):
66
+
67
+ /usr/bin/gzip -dc /var/log/production.log.0.gz | /usr/local/bin/pl_analyze /dev/stdin -e devnull@robotcoop.com -s "pl_analyze for `date -v-1d "+%D"`"
68
+
65
69
  In the future, pl_analyze will be able to read from STDIN.
66
70
 
67
71
  = Sample output
68
72
 
69
- Average Request Time: 0.279874593327209
70
- Request Time Std Dev: 0.351590385021209
71
-
72
- Slowest Request Times:
73
- ZeitgeistController#goals took 30.889858s
74
- ZeitgeistController#goals took 29.657513s
75
- EntriesController#save_comment took 20.499292s
76
- AccountController#create took 19.539545s
77
- EntriesController#save_comment took 15.46844s
78
- ZeitgeistController#goals took 14.814086s
79
- ZeitgeistController#goals took 13.943129s
80
- ZeitgeistController#goals took 13.113908s
81
- ZeitgeistController#completed_goals took 12.776777s
82
- ZeitgeistController#goals took 12.32529s
83
-
84
- Average DB Time: 0.0649204642242509
85
- DB Time Std Dev: 0.214050667483775
86
-
87
- Slowest Total DB Times:
88
- ZeitgeistController#goals took 30.797014s
89
- ZeitgeistController#goals took 29.567076s
90
- ZeitgeistController#goals took 14.709733s
91
- ZeitgeistController#goals took 13.84484s
92
- ZeitgeistController#goals took 12.968071s
93
- ZeitgeistController#completed_goals took 12.400506s
94
- ZeitgeistController#goals took 12.241167s
95
- ZeitgeistController#goals took 11.561719s
96
- ZeitgeistController#goals took 11.445382s
97
- ZeitgeistController#goals took 11.085795s
98
-
99
- Average Render Time: 0.128757978789508
100
- Render Time Std Dev: 0.131171213785894
101
-
102
- Slowest Total Render Times:
103
- TeamsController#progress took 4.698406s
104
- TeamsController#progress took 4.679505s
105
- PeopleController#doing_same_things took 3.628557s
106
- ThingsController#view took 3.34039s
107
- ThingsController#view took 2.096405s
108
- RssController#goals took 1.759452s
109
- EntriesController#view took 1.423261s
110
- ThingsController#view took 1.422453s
111
- ThingsController#people took 1.377157s
112
- PeopleController#view took 1.195831s
73
+ Request Times Summary: Count Avg Std Dev Min Max
74
+ ALL REQUESTS: 11 0.576 0.508 0.000 1.470
75
+
76
+ ThingsController#view: 3 0.716 0.387 0.396 1.260
77
+ TeamsController#progress: 2 0.841 0.629 0.212 1.470
78
+ RssController#uber: 2 0.035 0.000 0.035 0.035
79
+ PeopleController#progress: 2 0.489 0.489 0.000 0.977
80
+ PeopleController#view: 2 0.731 0.371 0.360 1.102
81
+
82
+ Average Request Time: 0.634
83
+ Request Time Std Dev: 0.498
84
+
85
+ Slowest Request Times:
86
+ TeamsController#progress took 1.470s
87
+ ThingsController#view took 1.260s
88
+ PeopleController#view took 1.102s
89
+ PeopleController#progress took 0.977s
90
+ ThingsController#view took 0.492s
91
+ ThingsController#view took 0.396s
92
+ PeopleController#view took 0.360s
93
+ TeamsController#progress took 0.212s
94
+ RssController#uber took 0.035s
95
+ RssController#uber took 0.035s
96
+
97
+ ------------------------------------------------------------------------
98
+
99
+ DB Times Summary: Count Avg Std Dev Min Max
100
+ ALL REQUESTS: 11 0.366 0.393 0.000 1.144
101
+
102
+ ThingsController#view: 3 0.403 0.362 0.122 0.914
103
+ TeamsController#progress: 2 0.646 0.497 0.149 1.144
104
+ RssController#uber: 2 0.008 0.000 0.008 0.008
105
+ PeopleController#progress: 2 0.415 0.415 0.000 0.830
106
+ PeopleController#view: 2 0.338 0.149 0.189 0.486
107
+
108
+ Average DB Time: 0.402
109
+ DB Time Std Dev: 0.394
110
+
111
+ Slowest Total DB Times:
112
+ TeamsController#progress took 1.144s
113
+ ThingsController#view took 0.914s
114
+ PeopleController#progress took 0.830s
115
+ PeopleController#view took 0.486s
116
+ PeopleController#view took 0.189s
117
+ ThingsController#view took 0.173s
118
+ TeamsController#progress took 0.149s
119
+ ThingsController#view took 0.122s
120
+ RssController#uber took 0.008s
121
+ RssController#uber took 0.008s
122
+
123
+ ------------------------------------------------------------------------
124
+
125
+ Render Times Summary: Count Avg Std Dev Min Max
126
+ ALL REQUESTS: 11 0.219 0.253 0.000 0.695
127
+
128
+ ThingsController#view: 3 0.270 0.171 0.108 0.506
129
+ TeamsController#progress: 2 0.000 0.000 0.000 0.000
130
+ RssController#uber: 2 0.012 0.000 0.012 0.012
131
+ PeopleController#progress: 2 0.302 0.302 0.000 0.604
132
+ PeopleController#view: 2 0.487 0.209 0.278 0.695
133
+
134
+ Average Render Time: 0.302
135
+ Render Time Std Dev: 0.251
136
+
137
+ Slowest Total Render Times:
138
+ PeopleController#view took 0.695s
139
+ PeopleController#progress took 0.604s
140
+ ThingsController#view took 0.506s
141
+ PeopleController#view took 0.278s
142
+ ThingsController#view took 0.197s
143
+ ThingsController#view took 0.108s
144
+ RssController#uber took 0.012s
145
+ RssController#uber took 0.012s
146
+ TeamsController#progress took 0.000s
147
+ TeamsController#progress took 0.000s
113
148
 
114
149
  = What's missing
115
150
 
116
151
  * More reports
117
152
  * Command line arguments including:
118
- * Number of lines to report
153
+ * Help
119
154
  * What type of log file you've got (if somebody sends patches with tests)
155
+ * Read from STDIN
120
156
  * Lots more
121
157
 
data/Rakefile CHANGED
@@ -9,7 +9,7 @@ $VERBOSE = nil
9
9
 
10
10
  spec = Gem::Specification.new do |s|
11
11
  s.name = "production_log_analyzer"
12
- s.version = "1.1.0"
12
+ s.version = "1.2.0"
13
13
  s.summary = "Extracts statistics from Rails production logs"
14
14
  s.author = "Eric Hodel"
15
15
  s.email = "hodel@robotcoop.com"
@@ -5,46 +5,31 @@ require 'production_log/analyzer'
5
5
  file_name = ARGV.shift
6
6
 
7
7
  if file_name.nil? then
8
- puts "Usage: #{$0} file_name"
8
+ puts "Usage: #{$0} file_name [-e email_recipient [-s subject]] [count]"
9
9
  exit 1
10
10
  end
11
11
 
12
- analyzer = Analyzer.new file_name
13
- analyzer.process
12
+ email_recipient = nil
13
+ subject = nil
14
14
 
15
- count = ARGV.shift
16
- count = count.nil? ? 10 : count.to_i
17
-
18
- request_times = analyzer.slowest_request_times(count).map do |time, name|
19
- "\t#{name} took #{time}s"
15
+ if ARGV.first == '-e' then
16
+ ARGV.shift # -e
17
+ email_recipient = ARGV.shift
20
18
  end
21
19
 
22
- puts "Average Request Time: #{analyzer.average_request_time}"
23
- puts "Request Time Std Dev: #{analyzer.request_time_std_dev}"
24
- puts
25
- puts "Slowest Request Times:"
26
- puts request_times.join($/)
27
- puts
28
-
29
- db_times = analyzer.slowest_db_times(count).map do |time, name|
30
- "\t#{name} took #{time}s"
20
+ if email_recipient and ARGV.first == '-s' then
21
+ ARGV.shift # -s
22
+ subject = ARGV.shift
31
23
  end
32
24
 
33
- puts "Average DB Time: #{analyzer.average_db_time}"
34
- puts "DB Time Std Dev: #{analyzer.db_time_std_dev}"
35
- puts
36
- puts "Slowest Total DB Times:"
37
- puts db_times.join($/)
38
- puts
39
-
40
- render_times = analyzer.slowest_render_times(count).map do |time, name|
41
- "\t#{name} took #{time}s"
25
+ count = ARGV.shift
26
+ count = count.nil? ? 10 : Integer(count)
27
+
28
+ if email_recipient.nil? then
29
+ analyzer = Analyzer.new file_name
30
+ analyzer.process
31
+ puts analyzer.report(count)
32
+ else
33
+ Analyzer.email file_name, email_recipient, subject, count
42
34
  end
43
35
 
44
- puts "Average Render Time: #{analyzer.average_render_time}"
45
- puts "Render Time Std Dev: #{analyzer.render_time_std_dev}"
46
- puts
47
- puts "Slowest Total Render Times:"
48
- puts render_times.join($/)
49
- puts
50
-
@@ -1,4 +1,4 @@
1
- #!/usr/local/bin/ruby -w
1
+ $TESTING = false unless defined? $TESTING
2
2
 
3
3
  require 'production_log/parser'
4
4
 
@@ -131,7 +131,36 @@ class Analyzer
131
131
 
132
132
  attr_reader :render_times
133
133
 
134
- # attr_reader :query_times
134
+ ##
135
+ # Generates and sends an email report with lots of fun stuff in it. This
136
+ # way, Mail.app will behave when given tabs (I hope).
137
+
138
+ def self.email(file_name, recipient, subject, count = 10)
139
+ analyzer = self.new file_name
140
+ analyzer.process
141
+ body = analyzer.report(count)
142
+
143
+ email = self.envelope(recipient, subject)
144
+ email << nil
145
+ email << "<pre>#{body}</pre>"
146
+ email = email.join($/) << $/
147
+
148
+ return email if $TESTING
149
+
150
+ IO.popen("/usr/sbin/sendmail -i -t", "w+") do |sm|
151
+ sm.print email
152
+ sm.flush
153
+ end
154
+ end
155
+
156
+ def self.envelope(recipient, subject = nil) # :nodoc:
157
+ envelope = {}
158
+ envelope['To'] = recipient
159
+ envelope['Subject'] = subject || "pl_analyze"
160
+ envelope['Content-Type'] = "text/html"
161
+
162
+ return envelope.map { |(k,v)| "#{k}: #{v}" }
163
+ end
135
164
 
136
165
  ##
137
166
  # Creates a new Analyzer that will read data from +logfile_name+.
@@ -154,9 +183,6 @@ class Analyzer
154
183
  @request_times[entry_page] << entry.request_time
155
184
  @db_times[entry_page] << entry.db_time
156
185
  @render_times[entry_page] << entry.render_time
157
- # entry.queries.each do |name, time, sql|
158
- # @query_times[entry_page] << time
159
- # end
160
186
  end
161
187
  end
162
188
  end
@@ -165,93 +191,166 @@ class Analyzer
165
191
  # The average total request time for all requests.
166
192
 
167
193
  def average_request_time
168
- times = @request_times.values.flatten
169
- times.delete 0
170
- return times.average
194
+ return time_average(@request_times)
171
195
  end
172
196
 
173
197
  ##
174
198
  # The standard deviation of the total request time for all requests.
175
199
 
176
200
  def request_time_std_dev
177
- times = @request_times.values.flatten
178
- times.delete 0
179
- return times.standard_deviation
201
+ return time_std_dev(@request_times)
180
202
  end
181
203
 
182
204
  ##
183
205
  # The +limit+ slowest total request times.
184
206
 
185
207
  def slowest_request_times(limit = 10)
186
- slowest_times = SlowestTimes.new limit
187
-
188
- @request_times.each do |name, times|
189
- times.each do |time|
190
- slowest_times << [time, name]
191
- end
192
- end
193
-
194
- return slowest_times.sort_by { |time, name| time }.reverse
208
+ return slowest_times(@request_times, limit)
195
209
  end
196
210
 
197
211
  ##
198
212
  # The average total database time for all requests.
199
213
 
200
214
  def average_db_time
201
- times = @db_times.values.flatten
202
- times.delete 0
203
- return times.average
215
+ return time_average(@db_times)
204
216
  end
205
217
 
206
218
  ##
207
219
  # The standard deviation of the total database time for all requests.
208
220
 
209
221
  def db_time_std_dev
210
- times = @db_times.values.flatten
211
- times.delete 0
212
- return times.standard_deviation
222
+ return time_std_dev(@db_times)
213
223
  end
214
224
 
215
225
  ##
216
226
  # The +limit+ slowest total database times.
217
227
 
218
228
  def slowest_db_times(limit = 10)
219
- slowest_times = SlowestTimes.new limit
220
-
221
- @db_times.each do |name, times|
222
- times.each do |time|
223
- slowest_times << [time, name]
224
- end
225
- end
226
-
227
- return slowest_times.sort_by { |time, name| time }.reverse
229
+ return slowest_times(@db_times, limit)
228
230
  end
229
231
 
230
232
  ##
231
233
  # The average total render time for all requests.
232
234
 
233
235
  def average_render_time
234
- times = @render_times.values.flatten
235
- times.delete 0
236
- return times.average
236
+ return time_average(@render_times)
237
237
  end
238
238
 
239
239
  ##
240
240
  # The standard deviation of the total render time for all requests.
241
241
 
242
242
  def render_time_std_dev
243
- times = @render_times.values.flatten
244
- times.delete 0
245
- return times.standard_deviation
243
+ return time_std_dev(@render_times)
246
244
  end
247
245
 
248
246
  ##
249
247
  # The +limit+ slowest total render times for all requests.
250
248
 
251
249
  def slowest_render_times(limit = 10)
250
+ return slowest_times(@render_times, limit)
251
+ end
252
+
253
+ ##
254
+ # A list of count/min/max/avg/std dev for request times.
255
+
256
+ def request_times_summary
257
+ return summarize("Request Times", @request_times)
258
+ end
259
+
260
+ ##
261
+ # A list of count/min/max/avg/std dev for database times.
262
+
263
+ def db_times_summary
264
+ return summarize("DB Times", @db_times)
265
+ end
266
+
267
+ ##
268
+ # A list of count/min/max/avg/std dev for request times.
269
+
270
+ def render_times_summary
271
+ return summarize("Render Times", @render_times)
272
+ end
273
+
274
+ ##
275
+ # Builds a report containing +count+ slow items.
276
+
277
+ def report(count)
278
+ text = []
279
+
280
+ text << request_times_summary
281
+ text << nil
282
+ text << "Average Request Time: #{'%0.3f' % average_request_time}"
283
+ text << "Request Time Std Dev: #{'%0.3f' % request_time_std_dev}"
284
+ text << nil
285
+ text << "Slowest Request Times:"
286
+ slowest_request_times(count).each do |time, name|
287
+ text << "\t#{name} took #{'%0.3f' % time}s"
288
+ end
289
+ text << nil
290
+ text << "-" * 72
291
+ text << nil
292
+
293
+ text << db_times_summary
294
+ text << nil
295
+ text << "Average DB Time: #{'%0.3f' % average_db_time}"
296
+ text << "DB Time Std Dev: #{'%0.3f' % db_time_std_dev}"
297
+ text << nil
298
+ text << "Slowest Total DB Times:"
299
+ slowest_db_times(count).each do |time, name|
300
+ text << "\t#{name} took #{'%0.3f' % time}s"
301
+ end
302
+ text << nil
303
+ text << "-" * 72
304
+ text << nil
305
+
306
+
307
+ text << render_times_summary
308
+ text << nil
309
+ text << "Average Render Time: #{'%0.3f' % average_render_time}"
310
+ text << "Render Time Std Dev: #{'%0.3f' % render_time_std_dev}"
311
+ text << nil
312
+ text << "Slowest Total Render Times:"
313
+ slowest_render_times(count).each do |time, name|
314
+ text << "\t#{name} took #{'%0.3f' % time}s"
315
+ end
316
+ text << nil
317
+
318
+ return text.join($/)
319
+ end
320
+
321
+ private unless $TESTING
322
+
323
+ def summarize(title, records) # :nodoc:
324
+ record = nil
325
+ list = []
326
+
327
+ records.sort_by { |k,v| v.size}.reverse_each do |req, times|
328
+ record = [times.average, times.standard_deviation,
329
+ times.min, times.max]
330
+ record.map! { |v| "%0.3f" % v }
331
+ record.unshift ["#{pad_request_name req}", times.size]
332
+ list << record.join("\t")
333
+ end
334
+
335
+ list.unshift nil
336
+
337
+ times = records.values.flatten
338
+ record = [times.average, times.standard_deviation, times.min, times.max]
339
+ record.map! { |v| "%0.3f" % v }
340
+ record.unshift [pad_request_name('ALL REQUESTS'), times.size]
341
+ list.unshift record.join("\t")
342
+
343
+ record = [pad_request_name("#{title} Summary"), 'Count', 'Avg',
344
+ 'Std Dev', 'Min', 'Max']
345
+ list.unshift record.join("\t")
346
+
347
+ return list.join("\n")
348
+ end
349
+
350
+ def slowest_times(records, limit) # :nodoc:
252
351
  slowest_times = SlowestTimes.new limit
253
352
 
254
- @render_times.each do |name, times|
353
+ records.each do |name, times|
255
354
  times.each do |time|
256
355
  slowest_times << [time, name]
257
356
  end
@@ -260,6 +359,27 @@ class Analyzer
260
359
  return slowest_times.sort_by { |time, name| time }.reverse
261
360
  end
262
361
 
362
+ def time_average(records) # :nodoc:
363
+ times = records.values.flatten
364
+ times.delete 0
365
+ return times.average
366
+ end
367
+
368
+ def time_std_dev(records) # :nodoc:
369
+ times = records.values.flatten
370
+ times.delete 0
371
+ return times.standard_deviation
372
+ end
373
+
374
+ def longest_request_name # :nodoc:
375
+ @longest_req ||= @request_times.keys.map { |name| name.length + 1 }.max
376
+ end
377
+
378
+ def pad_request_name(name) # :nodoc:
379
+ name = name.dup << ':'
380
+ name += (' ' * (longest_request_name - name.length))
381
+ end
382
+
263
383
  end
264
384
 
265
385
  # vim: ts=4 sts=4 sw=4
@@ -1,5 +1,7 @@
1
1
  #!/usr/local/bin/ruby -w
2
2
 
3
+ $TESTING = true
4
+
3
5
  require 'test/unit'
4
6
 
5
7
  require 'production_log/analyzer'
@@ -85,6 +87,120 @@ class TestAnalyzer < Test::Unit::TestCase
85
87
  @analyzer.process
86
88
  end
87
89
 
90
+ def test_self_email
91
+ email = Analyzer.email('test/test.syslog.log', 'devnull@robotcoop.com',
92
+ nil, 1)
93
+ expected = <<-EOF
94
+ Subject: pl_analyze
95
+ To: devnull@robotcoop.com
96
+ Content-Type: text/html
97
+
98
+ <pre>Request Times Summary: Count Avg Std Dev Min Max
99
+ ALL REQUESTS: 11 0.576 0.508 0.000 1.470
100
+
101
+ ThingsController#view: 3 0.716 0.387 0.396 1.260
102
+ TeamsController#progress: 2 0.841 0.629 0.212 1.470
103
+ RssController#uber: 2 0.035 0.000 0.035 0.035
104
+ PeopleController#progress: 2 0.489 0.489 0.000 0.977
105
+ PeopleController#view: 2 0.731 0.371 0.360 1.102
106
+
107
+ Average Request Time: 0.634
108
+ Request Time Std Dev: 0.498
109
+
110
+ Slowest Request Times:
111
+ TeamsController#progress took 1.470s
112
+
113
+ ------------------------------------------------------------------------
114
+
115
+ DB Times Summary: Count Avg Std Dev Min Max
116
+ ALL REQUESTS: 11 0.366 0.393 0.000 1.144
117
+
118
+ ThingsController#view: 3 0.403 0.362 0.122 0.914
119
+ TeamsController#progress: 2 0.646 0.497 0.149 1.144
120
+ RssController#uber: 2 0.008 0.000 0.008 0.008
121
+ PeopleController#progress: 2 0.415 0.415 0.000 0.830
122
+ PeopleController#view: 2 0.338 0.149 0.189 0.486
123
+
124
+ Average DB Time: 0.402
125
+ DB Time Std Dev: 0.394
126
+
127
+ Slowest Total DB Times:
128
+ TeamsController#progress took 1.144s
129
+
130
+ ------------------------------------------------------------------------
131
+
132
+ Render Times Summary: Count Avg Std Dev Min Max
133
+ ALL REQUESTS: 11 0.219 0.253 0.000 0.695
134
+
135
+ ThingsController#view: 3 0.270 0.171 0.108 0.506
136
+ TeamsController#progress: 2 0.000 0.000 0.000 0.000
137
+ RssController#uber: 2 0.012 0.000 0.012 0.012
138
+ PeopleController#progress: 2 0.302 0.302 0.000 0.604
139
+ PeopleController#view: 2 0.487 0.209 0.278 0.695
140
+
141
+ Average Render Time: 0.302
142
+ Render Time Std Dev: 0.251
143
+
144
+ Slowest Total Render Times:
145
+ PeopleController#view took 0.695s
146
+ </pre>
147
+ EOF
148
+
149
+ assert_equal expected, email
150
+ end
151
+
152
+ def test_self_envelope
153
+ expected = [
154
+ "Subject: pl_analyze",
155
+ "To: devnull@example.com",
156
+ "Content-Type: text/html"
157
+ ]
158
+
159
+ assert_equal expected, Analyzer.envelope('devnull@example.com')
160
+ end
161
+
162
+ def test_self_envelope_subject
163
+ expected = [
164
+ "Subject: happy fancy boom",
165
+ "To: devnull@example.com",
166
+ "Content-Type: text/html"
167
+ ]
168
+
169
+ assert_equal(expected,
170
+ Analyzer.envelope('devnull@example.com', 'happy fancy boom'))
171
+ end
172
+
173
+ def test_average_db_time
174
+ assert_in_delta 0.4023761, @analyzer.average_db_time, 0.0000001
175
+ end
176
+
177
+ def test_average_render_time
178
+ assert_in_delta 0.3015584, @analyzer.average_render_time, 0.0000001
179
+ end
180
+
181
+ def test_average_request_time
182
+ assert_in_delta 0.6338176, @analyzer.average_request_time, 0.0000001
183
+ end
184
+
185
+ def test_db_time_std_dev
186
+ assert_in_delta 0.3941380, @analyzer.db_time_std_dev, 0.0000001
187
+ end
188
+
189
+ def test_db_times_summary
190
+ expected = <<EOF.strip
191
+ DB Times Summary: Count Avg Std Dev Min Max
192
+ ALL REQUESTS: 11 0.366 0.393 0.000 1.144
193
+
194
+ ThingsController#view: 3 0.403 0.362 0.122 0.914
195
+ TeamsController#progress: 2 0.646 0.497 0.149 1.144
196
+ RssController#uber: 2 0.008 0.000 0.008 0.008
197
+ PeopleController#progress: 2 0.415 0.415 0.000 0.830
198
+ PeopleController#view: 2 0.338 0.149 0.189 0.486
199
+ EOF
200
+
201
+ assert_equal expected, @analyzer.db_times_summary
202
+ end
203
+
88
204
  def test_logfile_name
89
205
  assert_equal 'test/test.syslog.log', @analyzer.logfile_name
90
206
  end
@@ -122,25 +238,126 @@ class TestAnalyzer < Test::Unit::TestCase
122
238
  # assert_equal expected_query_times, @analyzer.query_times
123
239
  end
124
240
 
125
- def test_slowest_request_times
126
- times = @analyzer.slowest_request_times 3
127
- assert_equal 3, times.length
128
- expected = [
129
- [1.469788, "TeamsController#progress"],
130
- [1.259728, "ThingsController#view"],
131
- [1.102098, "PeopleController#view"]
132
- ]
133
- assert_equal expected, times
241
+ def test_render_time_std_dev
242
+ assert_in_delta 0.2513925, @analyzer.render_time_std_dev, 0.0000001
134
243
  end
135
244
 
136
- def test_average_request_time
137
- assert_in_delta 0.6338176, @analyzer.average_request_time, 0.0000001
245
+ def test_render_times_summary
246
+ expected = <<EOF.strip
247
+ Render Times Summary: Count Avg Std Dev Min Max
248
+ ALL REQUESTS: 11 0.219 0.253 0.000 0.695
249
+
250
+ ThingsController#view: 3 0.270 0.171 0.108 0.506
251
+ TeamsController#progress: 2 0.000 0.000 0.000 0.000
252
+ RssController#uber: 2 0.012 0.000 0.012 0.012
253
+ PeopleController#progress: 2 0.302 0.302 0.000 0.604
254
+ PeopleController#view: 2 0.487 0.209 0.278 0.695
255
+ EOF
256
+
257
+ assert_equal expected, @analyzer.render_times_summary
258
+ end
259
+
260
+ def test_report
261
+ expected = <<-EOF
262
+ Request Times Summary: Count Avg Std Dev Min Max
263
+ ALL REQUESTS: 11 0.576 0.508 0.000 1.470
264
+
265
+ ThingsController#view: 3 0.716 0.387 0.396 1.260
266
+ TeamsController#progress: 2 0.841 0.629 0.212 1.470
267
+ RssController#uber: 2 0.035 0.000 0.035 0.035
268
+ PeopleController#progress: 2 0.489 0.489 0.000 0.977
269
+ PeopleController#view: 2 0.731 0.371 0.360 1.102
270
+
271
+ Average Request Time: 0.634
272
+ Request Time Std Dev: 0.498
273
+
274
+ Slowest Request Times:
275
+ TeamsController#progress took 1.470s
276
+ ThingsController#view took 1.260s
277
+ PeopleController#view took 1.102s
278
+ PeopleController#progress took 0.977s
279
+ ThingsController#view took 0.492s
280
+ ThingsController#view took 0.396s
281
+ PeopleController#view took 0.360s
282
+ TeamsController#progress took 0.212s
283
+ RssController#uber took 0.035s
284
+ RssController#uber took 0.035s
285
+
286
+ ------------------------------------------------------------------------
287
+
288
+ DB Times Summary: Count Avg Std Dev Min Max
289
+ ALL REQUESTS: 11 0.366 0.393 0.000 1.144
290
+
291
+ ThingsController#view: 3 0.403 0.362 0.122 0.914
292
+ TeamsController#progress: 2 0.646 0.497 0.149 1.144
293
+ RssController#uber: 2 0.008 0.000 0.008 0.008
294
+ PeopleController#progress: 2 0.415 0.415 0.000 0.830
295
+ PeopleController#view: 2 0.338 0.149 0.189 0.486
296
+
297
+ Average DB Time: 0.402
298
+ DB Time Std Dev: 0.394
299
+
300
+ Slowest Total DB Times:
301
+ TeamsController#progress took 1.144s
302
+ ThingsController#view took 0.914s
303
+ PeopleController#progress took 0.830s
304
+ PeopleController#view took 0.486s
305
+ PeopleController#view took 0.189s
306
+ ThingsController#view took 0.173s
307
+ TeamsController#progress took 0.149s
308
+ ThingsController#view took 0.122s
309
+ RssController#uber took 0.008s
310
+ RssController#uber took 0.008s
311
+
312
+ ------------------------------------------------------------------------
313
+
314
+ Render Times Summary: Count Avg Std Dev Min Max
315
+ ALL REQUESTS: 11 0.219 0.253 0.000 0.695
316
+
317
+ ThingsController#view: 3 0.270 0.171 0.108 0.506
318
+ TeamsController#progress: 2 0.000 0.000 0.000 0.000
319
+ RssController#uber: 2 0.012 0.000 0.012 0.012
320
+ PeopleController#progress: 2 0.302 0.302 0.000 0.604
321
+ PeopleController#view: 2 0.487 0.209 0.278 0.695
322
+
323
+ Average Render Time: 0.302
324
+ Render Time Std Dev: 0.251
325
+
326
+ Slowest Total Render Times:
327
+ PeopleController#view took 0.695s
328
+ PeopleController#progress took 0.604s
329
+ ThingsController#view took 0.506s
330
+ PeopleController#view took 0.278s
331
+ ThingsController#view took 0.197s
332
+ ThingsController#view took 0.108s
333
+ RssController#uber took 0.012s
334
+ RssController#uber took 0.012s
335
+ TeamsController#progress took 0.000s
336
+ TeamsController#progress took 0.000s
337
+ EOF
338
+
339
+ assert_equal expected, @analyzer.report(10)
138
340
  end
139
341
 
140
342
  def test_request_time_std_dev
141
343
  assert_in_delta 0.4975667, @analyzer.request_time_std_dev, 0.0000001
142
344
  end
143
345
 
346
+ def test_request_times_summary
347
+ expected = <<EOF.strip
348
+ Request Times Summary: Count Avg Std Dev Min Max
349
+ ALL REQUESTS: 11 0.576 0.508 0.000 1.470
350
+
351
+ ThingsController#view: 3 0.716 0.387 0.396 1.260
352
+ TeamsController#progress: 2 0.841 0.629 0.212 1.470
353
+ RssController#uber: 2 0.035 0.000 0.035 0.035
354
+ PeopleController#progress: 2 0.489 0.489 0.000 0.977
355
+ PeopleController#view: 2 0.731 0.371 0.360 1.102
356
+ EOF
357
+
358
+ assert_equal expected, @analyzer.request_times_summary
359
+ end
360
+
144
361
  def test_slowest_db_times
145
362
  times = @analyzer.slowest_db_times 3
146
363
  assert_equal 3, times.length
@@ -152,12 +369,15 @@ class TestAnalyzer < Test::Unit::TestCase
152
369
  assert_equal expected, times
153
370
  end
154
371
 
155
- def test_average_db_time
156
- assert_in_delta 0.4023761, @analyzer.average_db_time, 0.0000001
157
- end
158
-
159
- def test_db_time_std_dev
160
- assert_in_delta 0.3941380, @analyzer.db_time_std_dev, 0.0000001
372
+ def test_slowest_request_times
373
+ times = @analyzer.slowest_request_times 3
374
+ assert_equal 3, times.length
375
+ expected = [
376
+ [1.469788, "TeamsController#progress"],
377
+ [1.259728, "ThingsController#view"],
378
+ [1.102098, "PeopleController#view"]
379
+ ]
380
+ assert_equal expected, times
161
381
  end
162
382
 
163
383
  def test_slowest_render_times
@@ -171,13 +391,5 @@ class TestAnalyzer < Test::Unit::TestCase
171
391
  assert_equal expected, times
172
392
  end
173
393
 
174
- def test_average_render_time
175
- assert_in_delta 0.3015584, @analyzer.average_render_time, 0.0000001
176
- end
177
-
178
- def test_render_time_std_dev
179
- assert_in_delta 0.2513925, @analyzer.render_time_std_dev, 0.0000001
180
- end
181
-
182
394
  end
183
395
 
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.8.6
2
+ rubygems_version: 0.8.10
3
3
  specification_version: 1
4
4
  name: production_log_analyzer
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.1.0
7
- date: 2005-03-30
6
+ version: 1.2.0
7
+ date: 2005-05-10
8
8
  summary: Extracts statistics from Rails production logs
9
9
  require_paths:
10
10
  - lib