lackac-request-log-analyzer 0.1.3
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/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
|