nbogie-production_log_analyzer 1.5.1.1 → 1.5.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gemtest ADDED
File without changes
data/History.txt CHANGED
@@ -1,3 +1,7 @@
1
+ === 1.5.1.2
2
+
3
+ * Add tool to diff reports, to see what actions got faster or slower, etc.
4
+
1
5
  === 1.5.1.1
2
6
 
3
7
  * Groups by http verb (GET/PUT/POST/DELETE/HEAD)
data/README.txt CHANGED
@@ -138,6 +138,33 @@ In the future, pl_analyze will be able to read from STDIN.
138
138
  TeamsController#progress took 0.000s
139
139
  TeamsController#progress took 0.000s
140
140
 
141
+ There's an experimental report-differ which you can invoke as follows:
142
+
143
+ ruby -Ilib report_differ.rb report_b.txt report_a.txt > report_diff.txt
144
+
145
+ Sample diff output
146
+
147
+ Request_Times_Summary: Count Avg Max
148
+ ALL_REQUESTS +1.4(16515->22909) -2.2(0.405->0.18) -1.6(59.678->37.721)
149
+
150
+ SleepwalkersController#update.PUT.xml +1.4(6249->8793) -1.1(0.079->0.07) -2.7(8.328->3.103)
151
+ SleepwalkersController#update.PUT.csv +1.4(6245->8807) -1.0(0.099->0.097) +1.2(2.536->3.02)
152
+ SleepwalkersController#show.GET +1.4(509->710) -1.2(0.072->0.061) -2.3(3.505->1.504)
153
+ SleepwalkersController#show.GET.json +1.4(496->702) -1.2(0.076->0.064) -7.3(4.874->0.663)
154
+ AccomplicesController#history.GET.csv +1.4(470->680) -3.3(5.35->1.618) -1.5(20.681->13.692)
155
+ WindsController#feeds.GET +1.4(237->320) -1.1(0.201->0.183) +1.5(1.304->1.989)
156
+ ScamsController#show.GET +1.3(236->317) -3.0(11.793->3.869) -1.6(59.678->37.721)
157
+ SleepwalkersController#update.PUT -1.1(9->8) -1.1(0.051->0.047) -1.2(0.09->0.076)
158
+ AccomplicesController#show.GET.xml 1.0(2->2) -1.0(0.102->0.1) -1.0(0.184->0.179)
159
+ ScamsController#map.GET +6.0(2->12) -3.5(1.075->0.305) +1.1(2.008->2.112)
160
+ WindsController#feeds.GET.atom 1.0(1->1) -1.1(0.061->0.058) -1.1(0.061->0.058)
161
+ ScamsController#tag.GET.rss 1.0(1->1) -1.0(0.134->0.129) -1.0(0.134->0.129)
162
+
163
+ Unmatched_Actions:
164
+
165
+ ScamsController#index.GET.json only in report_a.txt
166
+ Api::V1::MisinterpretationsController#destroy.DELETE. only in report_a.txt
167
+
141
168
  == What's missing
142
169
 
143
170
  * More reports
data/Rakefile CHANGED
@@ -8,7 +8,7 @@ Hoe.plugin :email, :perforce # not on minitest yet
8
8
  Hoe.spec 'nbogie-production_log_analyzer' do
9
9
  developer 'Eric Hodel', 'drbrain@segment7.net'
10
10
  self.name = 'nbogie-production_log_analyzer'
11
- self.version = '1.5.1.1'
11
+ self.version = '1.5.1.2'
12
12
 
13
13
  extra_deps << ['rails_analyzer_tools', '>= 1.4.0']
14
14
  end
@@ -0,0 +1,178 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+
5
+ require 'report/report_parser'
6
+ require 'report/report_differ'
7
+
8
+ class TestReportDiffer < Test::Unit::TestCase
9
+
10
+ def file_data(filename)
11
+ 'test/example_data/' + filename
12
+ end
13
+
14
+ def setup
15
+ @differ = ReportDiffer.new
16
+ report_filenames = ['report_a', 'report_b'].map do |keyname|
17
+ "test/example_data/#{keyname}.txt"
18
+ end
19
+ create_reports()
20
+ #ReportDiffer.compare_files(report_filenames[0], report_filenames[1])
21
+ end
22
+
23
+
24
+ def test_initialization
25
+ differ = ReportDiffer.new
26
+ end
27
+
28
+ def test_compute_difference_in_values()
29
+ data = [
30
+ #when increasing
31
+ [100, 1000, 10],
32
+ [100, 200, 2],
33
+ [100, 130, 1.3],
34
+ #when same
35
+ [100, 100, 1],
36
+ [0,0, 1],
37
+ #when lessening
38
+ [100, 90, -1.11],
39
+ [100, 50, -2],
40
+ [100, 10, -10],
41
+ #when one number is zero - not sure what we should return here.
42
+ [0.00, 1, 999999],
43
+ [1, 0.00, -999999],
44
+ ]
45
+ data.each do |group|
46
+ va, vb, expected = group
47
+ actual = @differ.compute_difference_in_values(va, vb)
48
+ assert_equal(expected, actual, "for #{va}->#{vb}")
49
+ end
50
+ end
51
+
52
+
53
+ def test_compare
54
+ threshold = 1.2
55
+ actual=@differ.compare(@report_a, @report_b, threshold)
56
+ assert_not_nil actual
57
+ expected = {
58
+ :summary_diff=>
59
+ {
60
+ :diff_count=>{:change => -1.11, :from => 100, :to => 90},
61
+ :diff_avg_time=>{:change => 1.5, :from => 10, :to => 15},
62
+ :diff_min_time=>{:change => 1, :from => 0.1, :to => 0.1},
63
+ :diff_max_time=>{:change => 2.0, :from => 20.0, :to => 40.0},
64
+ :diff_std_dev=>{:change => 3.0, :from => 2.0, :to => 6.0}},
65
+ :request_diffs=>
66
+ {"MyCon#MyAc.get.xml"=>
67
+ {
68
+ :diff_count=>{:change => 1.1, :from => 100, :to => 110},
69
+ :diff_avg_time=>{:change => 1.2, :from => 100, :to => 120},
70
+ :diff_std_dev=>{:change => 1.3, :from => 100, :to => 130},
71
+ :diff_min_time=>{:change => 1.4, :from => 100, :to => 140},
72
+ :diff_max_time=>{:change => 1.5, :from => 100, :to => 150} }},
73
+ :unmatched_actions => [],
74
+ :threshold => threshold
75
+ }
76
+
77
+
78
+ assert_equal(expected, actual)
79
+
80
+ ra1 = Request.create('MyCon','MyAc2',600,1,1,1,1)
81
+ rb1 = Request.create('MyCon','MyAc2',610,1,1,1,1)
82
+ ra2 = Request.create('MyCon','MyAc3',50,1,1,1,1)
83
+ rb2 = Request.create('MyCon','MyAc3',50,1,1,1,1)
84
+ @report_a.requests << ra1 << ra2
85
+ @report_b.requests << rb1 << rb2
86
+ assert_equal 3, @report_a.requests.size
87
+
88
+ actual=@differ.compare(@report_a, @report_b, threshold)
89
+ end
90
+ def test_prepare_report()
91
+ diff_data = @differ.compare(@report_a, @report_b)
92
+ report_text = @differ.prepare_report(diff_data)
93
+ #TODO: check report text as as we expect
94
+ ##puts report_text
95
+ end
96
+
97
+ def test_matched_requests_values_ab
98
+ matches = @differ.find_matched_actions(@report_a, @report_b)
99
+ assert_equal 1, matches.size
100
+ assert_equal [100, 110], matches.first.values_ab(:count)
101
+ assert_equal [100, 120], matches.first.values_ab(:avg_time)
102
+ assert_equal [100, 130], matches.first.values_ab(:std_dev)
103
+ assert_equal [100, 140], matches.first.values_ab(:min_time)
104
+ assert_equal [100, 150], matches.first.values_ab(:max_time)
105
+ end
106
+
107
+ def test_find_matched_actions
108
+ matches = @differ.find_matched_actions(@report_a, @report_b)
109
+ assert_equal 1, matches.size
110
+ the_match=matches.first
111
+ assert_equal [@report_a.requests.first, @report_b.requests.first], [the_match.request1, the_match.request2]
112
+
113
+ #with one of the reports having NO requests
114
+ @report_a.requests.clear
115
+ assert_equal 0, @differ.find_matched_actions(@report_a, @report_b).size
116
+ end
117
+
118
+ def test_find_unmatched_actions
119
+ #initially, should return empty list - all match
120
+ assert_equal [], @differ.find_unmatched_actions(@report_a, @report_b)
121
+ #add a request to only one report - should find it
122
+ odd_req = Request.create('MyCon','UniqueAction',110,120,130,140,150)
123
+ @report_a.requests << odd_req
124
+ unmatcheds = @differ.find_unmatched_actions(@report_a, @report_b)
125
+ assert_equal 1, unmatcheds.size
126
+ assert_equal 'UniqueAction', unmatcheds.first.request.action
127
+ assert_equal @report_a, unmatcheds.first.report
128
+
129
+ #add another request (only to rep b)
130
+ odd_req2 = Request.create('UniqueCon','MyAc',110,120,130,140,150)
131
+ @report_b.requests << odd_req2
132
+ unmatcheds = @differ.find_unmatched_actions(@report_a, @report_b)
133
+ assert_equal 2, unmatcheds.size
134
+ assert_equal 'UniqueAction', unmatcheds.first.request.action
135
+ assert_equal @report_a, unmatcheds.first.report
136
+ assert_equal 'UniqueCon', unmatcheds.last.request.controller
137
+ assert_equal @report_b, unmatcheds.last.report
138
+ end
139
+
140
+ def test_compare_summaries
141
+ actual=@differ.compare_summaries(@report_a, @report_b)
142
+ assert_equal(
143
+ {
144
+ :diff_count=>{:change => -1.11, :from => 100, :to => 90},
145
+ :diff_avg_time=>{:change => 1.5, :from => 10, :to => 15},
146
+ :diff_std_dev=>{:change => 3.0, :from => 2.0, :to => 6.0},
147
+ :diff_min_time=>{:change => 1, :from => 0.1, :to => 0.1},
148
+ :diff_max_time=>{:change => 2.0, :from => 20.0, :to => 40.0},
149
+ }, actual)
150
+ end
151
+
152
+ #populate @report_a, @report_b
153
+ def create_reports
154
+ ra = Report.new
155
+ ra.summary.count=100
156
+ ra.summary.avg_time=10.0
157
+ ra.summary.std_dev=2.0
158
+ ra.summary.min_time=0.1
159
+ ra.summary.max_time=20.0
160
+
161
+ ca1 = Request.create('MyCon','MyAc',100,100,100,100,100, {:verb=>'get',:format =>'xml'})
162
+ cb1 = Request.create('MyCon','MyAc',110,120,130,140,150, {:verb=>'get',:format =>'xml'})
163
+ ra.requests << ca1
164
+
165
+ rb = Report.new
166
+ rb.summary.count=90
167
+ rb.summary.avg_time=15.0
168
+ rb.summary.std_dev=6
169
+ rb.summary.min_time=0.1
170
+ rb.summary.max_time=40.0
171
+ rb.requests << cb1
172
+ @report_a = ra
173
+ @report_b = rb
174
+ end
175
+
176
+
177
+ end
178
+
@@ -0,0 +1,140 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+
5
+ require 'report/report_parser'
6
+
7
+ class TestReportParser < Test::Unit::TestCase
8
+
9
+ def file_data(filename)
10
+ 'test/example_data/' + filename
11
+ end
12
+
13
+ def setup
14
+ @parser = ReportParser.new
15
+ end
16
+
17
+ def test_initialization
18
+ parser = ReportParser.new
19
+ end
20
+
21
+ def test_can_parse_report
22
+ content = File.read(file_data('example.txt'))
23
+
24
+ result = @parser.parse("my report name", content)
25
+ assert_not_nil(result)
26
+ assert_equal("my report name", result.name)
27
+ assert_equal(8, result.requests.size)
28
+ expected_controllers= %w(
29
+ FooController
30
+ FooController
31
+ FooController
32
+ FooController
33
+ BarController
34
+ HealthController
35
+ QuxController
36
+ UsersController)
37
+ assert_equal(expected_controllers, result.requests.map{|rq| rq.controller})
38
+ end
39
+
40
+ def test_can_extract_from_all_requests
41
+ content = File.read(file_data('example.txt'))
42
+ result = @parser.parse("whatever", content)
43
+ assert_equal(11830,result.summary.count)
44
+ assert_equal(0.185,result.summary.avg_time)
45
+ assert_equal(0.212,result.summary.std_dev)
46
+ assert_equal(0.001,result.summary.min_time)
47
+ assert_equal(3.553,result.summary.max_time)
48
+ end
49
+
50
+ def test_can_parse_a_request
51
+ line = "ApiFooController#update.PUT.xml: 3557 0.144 0.137 0.059 3.212"
52
+ request = @parser.parse_request(line)
53
+ assert_equal("ApiFooController",request.controller)
54
+ assert_equal("update",request.action)
55
+ assert_equal("PUT",request.verb)
56
+ assert_equal("xml",request.format)
57
+ assert_equal(3557,request.count)
58
+ assert_equal(0.144,request.avg_time)
59
+ assert_equal(0.137,request.std_dev)
60
+ assert_equal(0.059,request.min_time)
61
+ assert_equal(3.212,request.max_time)
62
+ end
63
+
64
+ def test_should_normalize_request_format_to_lowercase
65
+ line = "ApiFooController#update.PUT.XmL: 3557 0.144 0.137 0.059 3.212"
66
+ request = @parser.parse_request(line)
67
+ assert_equal("xml",request.format)
68
+ end
69
+
70
+ def test_should_normalize_request_verb_to_uppercase
71
+ line = "ApiFooController#update.puT.xml: 3557 0.144 0.137 0.059 3.212"
72
+ request = @parser.parse_request(line)
73
+ assert_equal("PUT",request.verb)
74
+ end
75
+
76
+ def test_should_parse_request_having_no_format
77
+ line = "ApiFooController#update.GET: 3557 0.144 0.137 0.059 3.212"
78
+ request = @parser.parse_request(line)
79
+ assert_equal("GET",request.verb)
80
+ assert_nil(request.format)
81
+ assert_equal(0.144,request.avg_time)
82
+ end
83
+
84
+ def test_can_parse_a_request_having_module_named_controller_name
85
+ line = "Api::V1::FooController#show.GET: 11707 0.107 0.263 0.015 19.075"
86
+ request = @parser.parse_request(line)
87
+ assert_equal("Api::V1::FooController",request.controller)
88
+ end
89
+
90
+ def test_should_parse_a_few_lines
91
+ should_parse "QuxController#index.GET.rss: 5 0.241 0.078 0.121 0.367"
92
+ end
93
+
94
+ def should_parse(line)
95
+ @parser.parse_request(line)
96
+ end
97
+
98
+ end
99
+
100
+ class TestRequest < Test::Unit::TestCase
101
+ def test_remembers_its_values
102
+ r = Request.new
103
+ r.controller = "somecontroller"
104
+ r.action = "someaction"
105
+ r.verb = "GET"
106
+ r.format = "xml"
107
+ r.count = 100
108
+ r.avg_time = 1.123
109
+ r.std_dev = 0.22
110
+ r.min_time = 3.33
111
+ r.max_time = 10.10
112
+ assert_equal("somecontroller",r.controller)
113
+ assert_equal("someaction",r.action)
114
+ assert_equal("GET",r.verb)
115
+ assert_equal("xml",r.format)
116
+ assert_equal(3.33,r.min_time)
117
+ assert_equal(10.10,r.max_time)
118
+ assert_equal(1.123,r.avg_time)
119
+ assert_equal(0.22,r.std_dev)
120
+ end
121
+
122
+ def test_create
123
+ req = Request.create('Con','Ac',1,2,3,4,5, {:verb=>'get',:format =>'xml'})
124
+ assert_equal('Con', req.controller)
125
+ assert_equal('Ac', req.action)
126
+ assert_equal(1, req.count)
127
+ assert_equal(2, req.avg_time)
128
+ assert_equal(3, req.std_dev)
129
+ assert_equal(4, req.min_time)
130
+ assert_equal(5, req.max_time)
131
+ end
132
+
133
+ def test_should_not_fixup_already_fixed_up_name
134
+ r = Request.new
135
+ r.controller = "Api::V1::GraultController"
136
+ r.fixup_controller_name!
137
+ assert_equal("Api::V1::GraultController",r.controller)
138
+ end
139
+ end
140
+
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nbogie-production_log_analyzer
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
4
+ hash: 119
5
+ prerelease:
5
6
  segments:
6
7
  - 1
7
8
  - 5
8
9
  - 1
9
- - 1
10
- version: 1.5.1.1
10
+ - 2
11
+ version: 1.5.1.2
11
12
  platform: ruby
12
13
  authors:
13
14
  - Eric Hodel
@@ -15,16 +16,17 @@ autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2010-06-10 00:00:00 +01:00
19
- default_executable:
19
+ date: 2011-07-07 00:00:00 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: rails_analyzer_tools
23
23
  prerelease: false
24
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
25
26
  requirements:
26
27
  - - ">="
27
28
  - !ruby/object:Gem::Version
29
+ hash: 7
28
30
  segments:
29
31
  - 1
30
32
  - 4
@@ -33,33 +35,21 @@ dependencies:
33
35
  type: :runtime
34
36
  version_requirements: *id001
35
37
  - !ruby/object:Gem::Dependency
36
- name: rubyforge
38
+ name: hoe
37
39
  prerelease: false
38
40
  requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
39
42
  requirements:
40
43
  - - ">="
41
44
  - !ruby/object:Gem::Version
45
+ hash: 35
42
46
  segments:
43
47
  - 2
44
- - 0
48
+ - 9
45
49
  - 4
46
- version: 2.0.4
50
+ version: 2.9.4
47
51
  type: :development
48
52
  version_requirements: *id002
49
- - !ruby/object:Gem::Dependency
50
- name: hoe
51
- prerelease: false
52
- requirement: &id003 !ruby/object:Gem::Requirement
53
- requirements:
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- segments:
57
- - 2
58
- - 6
59
- - 0
60
- version: 2.6.0
61
- type: :development
62
- version_requirements: *id003
63
53
  description: |-
64
54
  production_log_analyzer lets you find out which actions on a Rails
65
55
  site are slowing you down.
@@ -99,7 +89,9 @@ files:
99
89
  - test/test_action_grep.rb
100
90
  - test/test_analyzer.rb
101
91
  - test/test_parser.rb
102
- has_rdoc: true
92
+ - test/test_report_differ.rb
93
+ - test/test_report_parser.rb
94
+ - .gemtest
103
95
  homepage: http://seattlerb.rubyforge.org/production_log_analyzer
104
96
  licenses: []
105
97
 
@@ -110,27 +102,33 @@ rdoc_options:
110
102
  require_paths:
111
103
  - lib
112
104
  required_ruby_version: !ruby/object:Gem::Requirement
105
+ none: false
113
106
  requirements:
114
107
  - - ">="
115
108
  - !ruby/object:Gem::Version
109
+ hash: 3
116
110
  segments:
117
111
  - 0
118
112
  version: "0"
119
113
  required_rubygems_version: !ruby/object:Gem::Requirement
114
+ none: false
120
115
  requirements:
121
116
  - - ">="
122
117
  - !ruby/object:Gem::Version
118
+ hash: 3
123
119
  segments:
124
120
  - 0
125
121
  version: "0"
126
122
  requirements: []
127
123
 
128
124
  rubyforge_project: nbogie-production_log_analyzer
129
- rubygems_version: 1.3.6
125
+ rubygems_version: 1.8.5
130
126
  signing_key:
131
127
  specification_version: 3
132
128
  summary: production_log_analyzer lets you find out which actions on a Rails site are slowing you down
133
129
  test_files:
134
130
  - test/test_parser.rb
135
131
  - test/test_analyzer.rb
132
+ - test/test_report_differ.rb
136
133
  - test/test_action_grep.rb
134
+ - test/test_report_parser.rb