lackac-request-log-analyzer 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README +132 -0
- data/Rakefile +72 -0
- data/TODO +18 -0
- data/bin/request-log-analyzer +115 -0
- data/bin/request-log-database +81 -0
- data/lib/base/log_parser.rb +68 -0
- data/lib/base/record_inserter.rb +139 -0
- data/lib/base/summarizer.rb +71 -0
- data/lib/bashcolorizer.rb +60 -0
- data/lib/command_line/arguments.rb +129 -0
- data/lib/command_line/exceptions.rb +37 -0
- data/lib/command_line/flag.rb +51 -0
- data/lib/merb_analyzer/log_parser.rb +26 -0
- data/lib/merb_analyzer/summarizer.rb +61 -0
- data/lib/rails_analyzer/log_parser.rb +25 -0
- data/lib/rails_analyzer/record_inserter.rb +39 -0
- data/lib/rails_analyzer/summarizer.rb +67 -0
- data/lib/ruby-progressbar/progressbar.en.rd +103 -0
- data/lib/ruby-progressbar/progressbar.ja.rd +100 -0
- data/lib/ruby-progressbar/progressbar.rb +236 -0
- data/output/blockers.rb +11 -0
- data/output/errors.rb +9 -0
- data/output/hourly_spread.rb +28 -0
- data/output/mean_db_time.rb +7 -0
- data/output/mean_rendering_time.rb +7 -0
- data/output/mean_time.rb +7 -0
- data/output/most_requested.rb +6 -0
- data/output/timespan.rb +15 -0
- data/output/total_db_time.rb +6 -0
- data/output/total_time.rb +6 -0
- data/output/usage.rb +15 -0
- data/test/log_fragments/fragment_1.log +59 -0
- data/test/log_fragments/fragment_2.log +5 -0
- data/test/log_fragments/merb_1.log +84 -0
- data/test/merb_log_parser_test.rb +39 -0
- data/test/rails_log_parser_test.rb +86 -0
- data/test/record_inserter_test.rb +45 -0
- data/test/tasks.rake +8 -0
- metadata +105 -0
data/output/blockers.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# Print requests that took more than a second to complete, sorted by their frequency.
|
2
|
+
amount = $arguments[:amount] || 10
|
3
|
+
|
4
|
+
puts
|
5
|
+
puts "Mongrel process blockers (> #{$summarizer.blocker_duration} seconds)"
|
6
|
+
puts green("========================================================================")
|
7
|
+
|
8
|
+
$summarizer.sort_blockers_by(:count).reverse[0, amount.to_i].each do |a|
|
9
|
+
puts "%-50s: %10.03fs [#{green("%d requests")}]" % [a[0], a[1][:total_time], a[1][:count]]
|
10
|
+
end
|
11
|
+
|
data/output/errors.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# Print errors that occured often
|
2
|
+
amount = $arguments[:amount] || 10
|
3
|
+
puts
|
4
|
+
puts "Errors"
|
5
|
+
puts green("========================================================================")
|
6
|
+
$summarizer.sort_errors_by(:count).reverse[0, amount.to_i].each do |a|
|
7
|
+
puts "%s: [#{green("%d requests")}]" % [a[0] + 'Error', a[1][:count]]
|
8
|
+
puts blue(' -> ' + (a[1][:exception_strings].invert[ a[1][:exception_strings].values.max ])[0..79])
|
9
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Draws a graph containing the average amound of requests per hour per day
|
2
|
+
if $summarizer.request_time_graph?
|
3
|
+
|
4
|
+
max_request_graph = $summarizer.request_time_graph.max / $summarizer.duration
|
5
|
+
deviation = max_request_graph / 20
|
6
|
+
deviation = 1 if deviation == 0
|
7
|
+
color_cutoff = 15
|
8
|
+
|
9
|
+
puts
|
10
|
+
puts "Requests graph - average per day per hour"
|
11
|
+
puts green("========================================================================")
|
12
|
+
|
13
|
+
(0..23).each do |a|
|
14
|
+
requests = $summarizer.request_time_graph[a] / $summarizer.duration
|
15
|
+
display_chars = requests / deviation
|
16
|
+
|
17
|
+
if display_chars >= color_cutoff
|
18
|
+
display_chars_string = green(' ' * color_cutoff) + red(' ' * (display_chars - color_cutoff))
|
19
|
+
else
|
20
|
+
display_chars_string = green(' ' * display_chars)
|
21
|
+
end
|
22
|
+
|
23
|
+
puts "#{a.to_s.rjust(10)}:00 - #{('[' + requests.to_s + ' req.]').ljust(15)} : #{display_chars_string}"
|
24
|
+
end
|
25
|
+
else
|
26
|
+
puts
|
27
|
+
puts "Hourly spread not available"
|
28
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# Prints a table sorted by the highest database times.
|
2
|
+
amount = $arguments[:amount] || 10
|
3
|
+
puts
|
4
|
+
puts "Top #{amount} worst DB offenders - mean time"
|
5
|
+
puts green("========================================================================")
|
6
|
+
print_table($summarizer, :mean_db_time, amount)
|
7
|
+
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# Prints a table showing the slowest renderes
|
2
|
+
amount = $arguments[:amount] || 10
|
3
|
+
puts
|
4
|
+
puts "Top #{amount} slow renderers - mean time"
|
5
|
+
puts green("========================================================================")
|
6
|
+
print_table($summarizer, :mean_rendering_time, amount)
|
7
|
+
|
data/output/mean_time.rb
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
# Prints table sorted by the duration of the requests
|
2
|
+
amount = $arguments[:amount] || 10
|
3
|
+
puts
|
4
|
+
puts "Top #{amount} actions by time - per request mean"
|
5
|
+
puts green("========================================================================")
|
6
|
+
|
7
|
+
print_table($summarizer, :mean_time, amount)
|
@@ -0,0 +1,6 @@
|
|
1
|
+
# Prints a table sorted by the most frequently requested actions
|
2
|
+
amount = $arguments[:amount] || 10
|
3
|
+
puts
|
4
|
+
puts "Top #{amount} most requested actions"
|
5
|
+
puts green("========================================================================")
|
6
|
+
print_table($summarizer, :count, amount)
|
data/output/timespan.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# Prints the total timespan found in the parsed log files.
|
2
|
+
puts
|
3
|
+
puts green("========================================================================")
|
4
|
+
|
5
|
+
if $summarizer.has_timestamps?
|
6
|
+
puts "Timestamp first request: #{$summarizer.first_request_at}"
|
7
|
+
puts "Timestamp last request: #{$summarizer.last_request_at}"
|
8
|
+
puts "Total time analyzed: #{$summarizer.duration} days"
|
9
|
+
end
|
10
|
+
|
11
|
+
methods_print_array = []
|
12
|
+
$summarizer.methods.each do |key, value|
|
13
|
+
methods_print_array << "%s (%s)" % [key, green(((value * 100) / $summarizer.request_count).to_s + '%')]
|
14
|
+
end
|
15
|
+
puts 'Methods: ' + methods_print_array.join(', ') + '.'
|
@@ -0,0 +1,6 @@
|
|
1
|
+
# Prints a list of the actions that spend most of their time waiting for database results.
|
2
|
+
amount = $arguments[:amount] || 10
|
3
|
+
puts
|
4
|
+
puts "Top #{amount} worst DB offenders - cumulative time"
|
5
|
+
puts green("========================================================================")
|
6
|
+
print_table($summarizer, :total_db_time, amount)
|
@@ -0,0 +1,6 @@
|
|
1
|
+
# Prints a list ordered by the requests that took the most time in total.
|
2
|
+
amount = $arguments[:amount] || 10
|
3
|
+
puts
|
4
|
+
puts "Top #{amount} actions by time - cumulative"
|
5
|
+
puts green("========================================================================")
|
6
|
+
print_table($summarizer, :total_time, amount)
|
data/output/usage.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# Prints usage table
|
2
|
+
puts "Usage: request-log-analyzer [LOGFILES*] <OPTIONS>"
|
3
|
+
puts
|
4
|
+
puts "Options:"
|
5
|
+
puts " --fast, -t: Only use completed requests"
|
6
|
+
puts " --guess-database-time, -g: Guesses the database duration of requests"
|
7
|
+
puts " --output, -o: Comma-separated list of reports to show"
|
8
|
+
puts " --amount, -c: Displays the top <amount> elements in the reports"
|
9
|
+
puts " --colorize, -z: Fancy bash coloring"
|
10
|
+
puts " --merb, -m: Parse merb logfiles"
|
11
|
+
puts
|
12
|
+
puts "Examples:"
|
13
|
+
puts " request-log-analyzer development.log"
|
14
|
+
puts " request-log-analyzer mongrel.0.log mongrel.1.log mongrel.2.log -g -f -o mean_time,most_requested,blockers -c 20 -z"
|
15
|
+
puts
|
@@ -0,0 +1,59 @@
|
|
1
|
+
Processing DashboardController#index (for 130.89.162.199 at 2008-08-14 21:16:25) [GET]
|
2
|
+
Session ID: BAh7CToMcmVmZXJlciIbL3ByaXNjaWxsYS9wZW9wbGUvMjM1MCIKZmxhc2hJ
|
3
|
+
QzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNoSGFzaHsABjoKQHVz
|
4
|
+
ZWR7ADoNbGFuZ3VhZ2VvOhNMb2NhbGU6Ok9iamVjdBI6CUB3aW4wOg1AY291
|
5
|
+
bnRyeSIHTkw6CkBoYXNoaf3L2Js6DkBvcmlnX3N0ciIKbmwtTkw6DUBpc28z
|
6
|
+
MDY2MDoNQGNoYXJzZXQiClVURi04Og5AbGFuZ3VhZ2UiB25sOg5AbW9kaWZp
|
7
|
+
ZXIwOgtAcG9zaXgiCm5sX05MOg1AZ2VuZXJhbCIKbmxfTkw6DUB2YXJpYW50
|
8
|
+
MDoOQGZhbGxiYWNrMDoMQHNjcmlwdDA6DnBlcnNvbl9pZGkCMgc=--7918aed37151c13360cd370c37b541f136146fbd
|
9
|
+
Parameters: {"action"=>"index", "controller"=>"dashboard"}
|
10
|
+
Set language to: nl_NL
|
11
|
+
Rendering template within layouts/priscilla
|
12
|
+
Rendering dashboard/index
|
13
|
+
Completed in 0.22699 (4 reqs/sec) | Rendering: 0.02667 (11%) | DB: 0.03057 (13%) | 200 OK [https://www.example.com/]
|
14
|
+
|
15
|
+
|
16
|
+
Processing PeopleController#index (for 130.89.162.199 at 2008-08-14 21:16:30) [GET]
|
17
|
+
Session ID: BAh7CSIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo
|
18
|
+
SGFzaHsABjoKQHVzZWR7ADoMcmVmZXJlciIQL3ByaXNjaWxsYS86DnBlcnNv
|
19
|
+
bl9pZGkCMgc6DWxhbmd1YWdlbzoTTG9jYWxlOjpPYmplY3QSOg1AY291bnRy
|
20
|
+
eSIHTkw6CUB3aW4wOg5Ab3JpZ19zdHIiCm5sLU5MOgpAaGFzaGn9y9ibOg5A
|
21
|
+
bGFuZ3VhZ2UiB25sOg1AY2hhcnNldCIKVVRGLTg6DUBpc28zMDY2MDoOQG1v
|
22
|
+
ZGlmaWVyMDoLQHBvc2l4IgpubF9OTDoNQHZhcmlhbnQwOg1AZ2VuZXJhbCIK
|
23
|
+
bmxfTkw6DEBzY3JpcHQwOg5AZmFsbGJhY2sw--48cbe3788ef27f6005f8e999610a42af6e90ffb3
|
24
|
+
Parameters: {"commit"=>"Zoek", "action"=>"index", "q"=>"gaby", "controller"=>"people"}
|
25
|
+
Set language to: nl_NL
|
26
|
+
Redirected to https://www.example.com/people/2545
|
27
|
+
Completed in 0.04759 (21 reqs/sec) | DB: 0.03719 (78%) | 302 Found [https://www.example.com/people?q=gaby&commit=Zoek]
|
28
|
+
|
29
|
+
|
30
|
+
Processing PeopleController#show (for 130.89.162.199 at 2008-08-14 21:16:30) [GET]
|
31
|
+
Session ID: BAh7CToMcmVmZXJlciIpL3ByaXNjaWxsYS9wZW9wbGU/cT1nYWJ5JmNvbW1p
|
32
|
+
dD1ab2VrIgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVyOjpGbGFzaDo6Rmxh
|
33
|
+
c2hIYXNoewAGOgpAdXNlZHsAOg1sYW5ndWFnZW86E0xvY2FsZTo6T2JqZWN0
|
34
|
+
EjoJQHdpbjA6DUBjb3VudHJ5IgdOTDoKQGhhc2hp/cvYmzoOQG9yaWdfc3Ry
|
35
|
+
IgpubC1OTDoNQGlzbzMwNjYwOg1AY2hhcnNldCIKVVRGLTg6DkBsYW5ndWFn
|
36
|
+
ZSIHbmw6DkBtb2RpZmllcjA6C0Bwb3NpeCIKbmxfTkw6DUBnZW5lcmFsIgpu
|
37
|
+
bF9OTDoNQHZhcmlhbnQwOg5AZmFsbGJhY2swOgxAc2NyaXB0MDoOcGVyc29u
|
38
|
+
X2lkaQIyBw==--3ad1948559448522a49d289a2a89dc7ccbe8847a
|
39
|
+
Parameters: {"action"=>"show", "id"=>"2545", "controller"=>"people"}
|
40
|
+
Set language to: nl_NL
|
41
|
+
Rendering template within layouts/priscilla
|
42
|
+
Rendering people/show
|
43
|
+
person: Gaby Somers, study_year: 2008/2009
|
44
|
+
Completed in 0.29077 (3 reqs/sec) | Rendering: 0.24187 (83%) | DB: 0.04030 (13%) | 200 OK [https://www.example.com/people/2545]
|
45
|
+
|
46
|
+
|
47
|
+
Processing PeopleController#picture (for 130.89.162.199 at 2008-08-14 21:16:35) [GET]
|
48
|
+
Session ID: BAh7CSIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo
|
49
|
+
SGFzaHsABjoKQHVzZWR7ADoMcmVmZXJlciIbL3ByaXNjaWxsYS9wZW9wbGUv
|
50
|
+
MjU0NToOcGVyc29uX2lkaQIyBzoNbGFuZ3VhZ2VvOhNMb2NhbGU6Ok9iamVj
|
51
|
+
dBI6DUBjb3VudHJ5IgdOTDoJQHdpbjA6DkBvcmlnX3N0ciIKbmwtTkw6CkBo
|
52
|
+
YXNoaf3L2Js6DkBsYW5ndWFnZSIHbmw6DUBjaGFyc2V0IgpVVEYtODoNQGlz
|
53
|
+
bzMwNjYwOg5AbW9kaWZpZXIwOgtAcG9zaXgiCm5sX05MOg1AdmFyaWFudDA6
|
54
|
+
DUBnZW5lcmFsIgpubF9OTDoMQHNjcmlwdDA6DkBmYWxsYmFjazA=--797a33f280a482647111397d138d0918f2658167
|
55
|
+
Parameters: {"action"=>"picture", "id"=>"2545", "controller"=>"people"}
|
56
|
+
Set language to: nl_NL
|
57
|
+
Rendering template within layouts/priscilla
|
58
|
+
Rendering people/picture
|
59
|
+
Completed in 0.05383 (18 reqs/sec) | Rendering: 0.04622 (85%) | DB: 0.00206 (3%) | 200 OK [https://www.example.com/people/2545/picture]
|
@@ -0,0 +1,5 @@
|
|
1
|
+
Jul 13 06:25:58 10.1.1.32 app_p [1957]: Processing EmployeeController#index (for 10.1.1.33 at 2008-07-13 06:25:58) [GET]
|
2
|
+
Jul 13 06:25:58 10.1.1.32 app_p [1957]: Session ID: bd1810833653be11c38ad1e5675635bd
|
3
|
+
Jul 13 06:25:58 10.1.1.32 app_p [1957]: Parameters: {"format"=>"xml", "action"=>"index}
|
4
|
+
Jul 13 06:25:58 10.1.1.32 app_p [1957]: Rendering employees
|
5
|
+
Jul 13 06:25:58 10.1.1.32 app_p [1957]: Completed in 0.21665 (4 reqs/sec) | Rendering: 0.00926 (4%) | DB: 0.00000 (0%) | 200 OK [http://example.com/employee.xml]
|
@@ -0,0 +1,84 @@
|
|
1
|
+
~ Loaded DEVELOPMENT Environment...
|
2
|
+
~ Connecting to database...
|
3
|
+
~ loading gem 'merb_datamapper' ...
|
4
|
+
~ loading gem 'gettext' ...
|
5
|
+
~ loading gem 'merb_helpers' ...
|
6
|
+
~ loading gem 'merb-assets' ...
|
7
|
+
~ loading gem 'merb-action-args' ...
|
8
|
+
~ loading gem 'merb-mailer' ...
|
9
|
+
~ loading gem 'merb_param_protection' ...
|
10
|
+
~ loading gem 'merb_has_flash' ...
|
11
|
+
~ loading gem 'merb_forgery_protection' ...
|
12
|
+
~ loading gem 'dm-validations' ...
|
13
|
+
~ loading gem 'dm-timestamps' ...
|
14
|
+
~ loading gem 'dm-migrations' ...
|
15
|
+
~ loading gem 'dm-aggregates' ...
|
16
|
+
~ loading gem 'dm-adjust' ...
|
17
|
+
~ loading gem 'dm-serializer' ...
|
18
|
+
~ loading gem 'dm-constraints' ...
|
19
|
+
~ loading gem 'dm-timeline' ...
|
20
|
+
~ loading gem 'dm-searchable' ...
|
21
|
+
~ loading gem 'dm-audited' ...
|
22
|
+
~ loading gem 'lib/extensions' ...
|
23
|
+
~ loading gem 'lib/authenticated_system/authenticated_dependencies' ...
|
24
|
+
~ Compiling routes...
|
25
|
+
~ Using 'share-nothing' cookie sessions (4kb limit per client)
|
26
|
+
~ Using Mongrel adapter
|
27
|
+
~ Started request handling: Fri Aug 29 11:10:23 +0200 2008
|
28
|
+
~ Params: {"_method"=>"delete", "authenticity_token"=>"[FILTERED]", "action"=>"destroy", "method"=>"delete", "controller"=>"session"}
|
29
|
+
~ Cookie deleted: auth_token => nil
|
30
|
+
~ Redirecting to: / (302)
|
31
|
+
~ {:dispatch_time=>0.243424, :after_filters_time=>6.9e-05, :before_filters_time=>0.213213, :action_time=>0.241652}
|
32
|
+
~
|
33
|
+
|
34
|
+
~ Started request handling: Fri Aug 29 11:10:23 +0200 2008
|
35
|
+
~ Params: {"action"=>"index", "controller"=>"dashboard"}
|
36
|
+
~ Redirecting to: /login (302)
|
37
|
+
~ {:dispatch_time=>0.002649, :after_filters_time=>7.4e-05, :action_time=>0.001951}
|
38
|
+
~
|
39
|
+
|
40
|
+
~ Started request handling: Fri Aug 29 11:10:23 +0200 2008
|
41
|
+
~ Params: {"action"=>"create", "controller"=>"session"}
|
42
|
+
~ {:dispatch_time=>0.006117, :after_filters_time=>6.1e-05, :before_filters_time=>0.000712, :action_time=>0.005833}
|
43
|
+
~
|
44
|
+
|
45
|
+
~ Started request handling: Fri Aug 29 11:10:27 +0200 2008
|
46
|
+
~ Params: {"authenticity_token"=>"[FILTERED]", "action"=>"create", "controller"=>"session", "login"=>"username", "password"=>"[FILTERED]", "remember_me"=>"0"}
|
47
|
+
~ Redirecting to: / (302)
|
48
|
+
~ {:dispatch_time=>0.006652, :after_filters_time=>0.000143, :before_filters_time=>0.000861, :action_time=>0.006171}
|
49
|
+
~
|
50
|
+
|
51
|
+
~ Started request handling: Fri Aug 29 11:10:27 +0200 2008
|
52
|
+
~ Params: {"action"=>"index", "controller"=>"dashboard"}
|
53
|
+
~ Redirecting to: /dashboard (302)
|
54
|
+
~ {:dispatch_time=>0.008241, :after_filters_time=>0.000126, :before_filters_time=>0.002632, :action_time=>0.007711}
|
55
|
+
~
|
56
|
+
|
57
|
+
~ Started request handling: Fri Aug 29 11:10:27 +0200 2008
|
58
|
+
~ Params: {"action"=>"index", "namespace"=>"dashboard", "controller"=>"dashboard"}
|
59
|
+
~ {:dispatch_time=>0.009458, :after_filters_time=>0.000103, :before_filters_time=>0.00266, :action_time=>0.008742}
|
60
|
+
~
|
61
|
+
|
62
|
+
~ Started request handling: Fri Aug 29 11:10:29 +0200 2008
|
63
|
+
~ Params: {"format"=>nil, "action"=>"index", "namespace"=>"dashboard", "controller"=>"employees"}
|
64
|
+
~ {:dispatch_time=>0.102725, :after_filters_time=>0.000115, :before_filters_time=>0.00411, :action_time=>0.101836}
|
65
|
+
~
|
66
|
+
|
67
|
+
~ Started request handling: Fri Aug 29 11:10:30 +0200 2008
|
68
|
+
~ Params: {"format"=>nil, "action"=>"index", "namespace"=>"dashboard", "controller"=>"organisations"}
|
69
|
+
~ {:dispatch_time=>0.042575, :after_filters_time=>8.9e-05, :before_filters_time=>0.004267, :action_time=>0.041762}
|
70
|
+
~
|
71
|
+
|
72
|
+
~ Started request handling: Fri Aug 29 11:10:31 +0200 2008
|
73
|
+
~ Params: {"action"=>"index", "namespace"=>"dashboard", "controller"=>"dashboard"}
|
74
|
+
~ {:dispatch_time=>0.010311, :after_filters_time=>8.0e-05, :before_filters_time=>0.003195, :action_time=>0.009567}
|
75
|
+
~
|
76
|
+
|
77
|
+
~ Started request handling: Fri Aug 29 11:10:33 +0200 2008
|
78
|
+
~ Params: {"format"=>nil, "action"=>"index", "namespace"=>"dashboard", "controller"=>"employees"}
|
79
|
+
~ {:dispatch_time=>0.012913, :after_filters_time=>7.1e-05, :before_filters_time=>0.004422, :action_time=>0.012141}
|
80
|
+
~
|
81
|
+
|
82
|
+
~ Started request handling: Fri Aug 29 11:10:35 +0200 2008
|
83
|
+
~ Params: {"action"=>"new", "namespace"=>"dashboard", "controller"=>"employees"}
|
84
|
+
~ {:dispatch_time=>0.013051, :after_filters_time=>7.8e-05, :before_filters_time=>0.003576, :action_time=>0.011773}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
require "#{File.dirname(__FILE__)}/../lib/base/log_parser"
|
4
|
+
require "#{File.dirname(__FILE__)}/../lib/merb_analyzer/log_parser"
|
5
|
+
|
6
|
+
class MerbLogParserTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def fragment_file(number)
|
9
|
+
"#{File.dirname(__FILE__)}/log_fragments/merb_#{number}.log"
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_parse_started_merb_fragment
|
13
|
+
requests = []
|
14
|
+
parser = MerbAnalyzer::LogParser.new(fragment_file(1)).each(:started) do |request|
|
15
|
+
requests << request
|
16
|
+
end
|
17
|
+
assert_equal requests[0][:timestamp], "Fri Aug 29 11:10:23 +0200 2008"
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_parse_completed_merb_fragment
|
21
|
+
requests = []
|
22
|
+
parser = MerbAnalyzer::LogParser.new(fragment_file(1)).each(:completed) do |request|
|
23
|
+
requests << request
|
24
|
+
end
|
25
|
+
|
26
|
+
assert_equal requests[0][:action_time], 0.241652
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_parse_params_merb_fragment
|
30
|
+
requests = []
|
31
|
+
parser = MerbAnalyzer::LogParser.new(fragment_file(1)).each(:params) do |request|
|
32
|
+
requests << request
|
33
|
+
end
|
34
|
+
|
35
|
+
assert_match '"controller"=>"session"', requests[0][:raw_hash]
|
36
|
+
assert_match '"action"=>"destroy"', requests[0][:raw_hash]
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
require "#{File.dirname(__FILE__)}/../lib/base/log_parser"
|
4
|
+
require "#{File.dirname(__FILE__)}/../lib/rails_analyzer/log_parser"
|
5
|
+
|
6
|
+
class RailsLogParserTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def fragment_file(number)
|
9
|
+
"#{File.dirname(__FILE__)}/log_fragments/fragment_#{number}.log"
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
def test_progress_messages
|
14
|
+
log_file = fragment_file(1)
|
15
|
+
|
16
|
+
finished_encountered = false
|
17
|
+
file_size = File.size(log_file)
|
18
|
+
|
19
|
+
previous_pos = -1
|
20
|
+
parser = RailsAnalyzer::LogParser.new(log_file)
|
21
|
+
parser.progress do |pos, total|
|
22
|
+
assert_equal file_size, total
|
23
|
+
if pos == :finished
|
24
|
+
finished_encountered = true
|
25
|
+
else
|
26
|
+
assert pos <= total
|
27
|
+
assert pos > previous_pos
|
28
|
+
previous_pos = pos
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# now parse the file
|
33
|
+
parser.each(:started) { }
|
34
|
+
|
35
|
+
assert finished_encountered, "A finished event should have been fired"
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_parse_mongrel_log_fragment
|
39
|
+
count = 0
|
40
|
+
parser = RailsAnalyzer::LogParser.new(fragment_file(1)).each(:started) { count += 1 }
|
41
|
+
assert_equal 4, count
|
42
|
+
|
43
|
+
count = 0
|
44
|
+
parser = RailsAnalyzer::LogParser.new(fragment_file(1)).each(:completed) { count += 1 }
|
45
|
+
assert_equal 4, count
|
46
|
+
|
47
|
+
count = 0
|
48
|
+
parser = RailsAnalyzer::LogParser.new(fragment_file(1)).each(:started, :completed) { count += 1 }
|
49
|
+
assert_equal 8, count
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_parse_syslog_fragment
|
53
|
+
count = 0
|
54
|
+
parser = RailsAnalyzer::LogParser.new(fragment_file(2)).each(:started) { count += 1 }
|
55
|
+
assert_equal 1, count
|
56
|
+
|
57
|
+
count = 0
|
58
|
+
parser = RailsAnalyzer::LogParser.new(fragment_file(2)).each(:completed) { count += 1 }
|
59
|
+
assert_equal 1, count
|
60
|
+
|
61
|
+
count = 0
|
62
|
+
parser = RailsAnalyzer::LogParser.new(fragment_file(2)).each(:started, :completed) { count += 1 }
|
63
|
+
assert_equal 2, count
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_parse_syslog_fragment_content
|
67
|
+
# this test only works because there is only one requests in the fragment
|
68
|
+
parser = RailsAnalyzer::LogParser.new(fragment_file(2)).each(:started) do |request|
|
69
|
+
assert_equal "EmployeeController", request[:controller]
|
70
|
+
assert_equal "index", request[:action]
|
71
|
+
assert_equal "GET", request[:method]
|
72
|
+
assert_equal '10.1.1.33', request[:ip]
|
73
|
+
assert_equal '2008-07-13 06:25:58', request[:timestamp]
|
74
|
+
end
|
75
|
+
|
76
|
+
parser = RailsAnalyzer::LogParser.new(fragment_file(2)).each(:completed) do |request|
|
77
|
+
assert_equal "http://example.com/employee.xml", request[:url]
|
78
|
+
assert_equal 200, request[:status]
|
79
|
+
assert_equal 0.21665, request[:duration]
|
80
|
+
assert_equal 0.00926, request[:rendering]
|
81
|
+
assert_equal 0.0, request[:db]
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
require "#{File.dirname(__FILE__)}/../lib/base/log_parser"
|
4
|
+
require "#{File.dirname(__FILE__)}/../lib/base/record_inserter"
|
5
|
+
|
6
|
+
require "#{File.dirname(__FILE__)}/../lib/rails_analyzer/log_parser"
|
7
|
+
require "#{File.dirname(__FILE__)}/../lib/rails_analyzer/record_inserter"
|
8
|
+
|
9
|
+
class RecordInserterTest < Test::Unit::TestCase
|
10
|
+
|
11
|
+
def fragment_file(number)
|
12
|
+
"#{File.dirname(__FILE__)}/log_fragments/fragment_#{number}.log"
|
13
|
+
end
|
14
|
+
|
15
|
+
def setup
|
16
|
+
File.delete('_tmp.db') if File.exist?('_tmp.db')
|
17
|
+
end
|
18
|
+
|
19
|
+
def teardown
|
20
|
+
File.delete('_tmp.db') if File.exist?('_tmp.db')
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_insert_log_fragment
|
24
|
+
|
25
|
+
db = RailsAnalyzer::RecordInserter.insert_batch_into('_tmp.db') do |batch|
|
26
|
+
RailsAnalyzer::LogParser.new(fragment_file(1)).each { |request| batch.insert(request) }
|
27
|
+
end
|
28
|
+
|
29
|
+
assert_equal 4, db.database.get_first_value("SELECT COUNT(*) FROM started_requests").to_i
|
30
|
+
assert_equal 4, db.database.get_first_value("SELECT COUNT(*) FROM completed_requests").to_i
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_insert_multiple_fragments
|
34
|
+
RailsAnalyzer::RecordInserter.insert_batch_into('_tmp.db') do |batch|
|
35
|
+
RailsAnalyzer::LogParser.new(fragment_file(1)).each { |request| batch.insert(request) }
|
36
|
+
end
|
37
|
+
|
38
|
+
db = RailsAnalyzer::RecordInserter.insert_batch_into('_tmp.db') do |batch|
|
39
|
+
RailsAnalyzer::LogParser.new(fragment_file(2)).each { |request| batch.insert(request) }
|
40
|
+
end
|
41
|
+
assert_equal 5, db.database.get_first_value("SELECT COUNT(*) FROM started_requests").to_i
|
42
|
+
assert_equal 5, db.database.get_first_value("SELECT COUNT(*) FROM completed_requests").to_i
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|