production_log_analyzer 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/LICENSE +27 -0
- data/Manifest.txt +11 -0
- data/README +121 -0
- data/Rakefile +62 -0
- data/bin/pl_analyze +50 -0
- data/lib/production_log/analyzer.rb +266 -0
- data/lib/production_log/parser.rb +144 -0
- data/lib/production_log/syslog_logger.rb +121 -0
- data/test/test.syslog.log +255 -0
- data/test/test_analyzer.rb +183 -0
- data/test/test_parser.rb +140 -0
- metadata +48 -0
@@ -0,0 +1,183 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
require 'production_log/analyzer'
|
6
|
+
|
7
|
+
class TestEnumerable < Test::Unit::TestCase
|
8
|
+
|
9
|
+
def test_sum
|
10
|
+
assert_equal 45, (1..9).sum
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_average
|
14
|
+
# Ranges don't have a length
|
15
|
+
assert_in_delta 5.0, (1..9).to_a.average, 0.01
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_sample_variance
|
19
|
+
assert_in_delta 6.6666, (1..9).to_a.sample_variance, 0.0001
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_standard_deviation
|
23
|
+
assert_in_delta 2.5819, (1..9).to_a.standard_deviation, 0.0001
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
class TestSizedList < Test::Unit::TestCase
|
29
|
+
|
30
|
+
def setup
|
31
|
+
@list = SizedList.new 10 do |arr,|
|
32
|
+
arr.delete_at 0
|
33
|
+
true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_append
|
38
|
+
assert_equal [], @list.entries
|
39
|
+
|
40
|
+
(1..10).each { |i| @list << i }
|
41
|
+
assert_equal 10, @list.length
|
42
|
+
assert_equal((1..10).to_a, @list.entries)
|
43
|
+
|
44
|
+
@list << 11
|
45
|
+
assert_equal 10, @list.length
|
46
|
+
assert_equal((2..11).to_a, @list.entries)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
class TestSlowestTimes < Test::Unit::TestCase
|
52
|
+
|
53
|
+
def setup
|
54
|
+
@list = SlowestTimes.new 10
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_that_it_works
|
58
|
+
expected = []
|
59
|
+
|
60
|
+
10.downto(1) do |i|
|
61
|
+
@list << [i, nil]
|
62
|
+
expected << [i, nil]
|
63
|
+
end
|
64
|
+
|
65
|
+
assert_equal expected, @list.entries
|
66
|
+
|
67
|
+
@list << [11, nil]
|
68
|
+
expected.pop
|
69
|
+
expected.push [11, nil]
|
70
|
+
|
71
|
+
assert_equal 10, @list.length
|
72
|
+
assert_equal expected, @list.entries
|
73
|
+
|
74
|
+
@list << [0, nil]
|
75
|
+
|
76
|
+
assert_equal expected, @list.entries
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
class TestAnalyzer < Test::Unit::TestCase
|
82
|
+
|
83
|
+
def setup
|
84
|
+
@analyzer = Analyzer.new 'test/test.syslog.log'
|
85
|
+
@analyzer.process
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_logfile_name
|
89
|
+
assert_equal 'test/test.syslog.log', @analyzer.logfile_name
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_process
|
93
|
+
expected_request_times = {
|
94
|
+
"PeopleController#view" => [1.102098, 0.36021],
|
95
|
+
"ThingsController#view" => [0.396183, 0.49176, 1.259728],
|
96
|
+
"TeamsController#progress" => [1.469788, 0.211973],
|
97
|
+
"RssController#uber" => [0.034519, 0.034519],
|
98
|
+
"PeopleController#progress" => [0.977398, 0]
|
99
|
+
}
|
100
|
+
assert_equal expected_request_times, @analyzer.request_times
|
101
|
+
|
102
|
+
expected_db_times = {
|
103
|
+
"PeopleController#view" => [0.486258, 0.189119],
|
104
|
+
"ThingsController#view" => [0.122158, 0.172767, 0.914192],
|
105
|
+
"TeamsController#progress" => [1.143577, 0.149357],
|
106
|
+
"RssController#uber" => [0.007962, 0.007962],
|
107
|
+
"PeopleController#progress" => [0.830409, 0]
|
108
|
+
}
|
109
|
+
assert_equal expected_db_times, @analyzer.db_times
|
110
|
+
|
111
|
+
expected_render_times = {
|
112
|
+
"PeopleController#view" => [0.695476, 0.277921],
|
113
|
+
"ThingsController#view" => [0.107987, 0.197126, 0.505973],
|
114
|
+
"TeamsController#progress" => [0, 0],
|
115
|
+
"RssController#uber" => [0.01177, 0.01177],
|
116
|
+
"PeopleController#progress" => [0.604444, 0]
|
117
|
+
}
|
118
|
+
assert_equal expected_render_times, @analyzer.render_times
|
119
|
+
|
120
|
+
# expected_query_times = {
|
121
|
+
# }
|
122
|
+
# assert_equal expected_query_times, @analyzer.query_times
|
123
|
+
end
|
124
|
+
|
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
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_average_request_time
|
137
|
+
assert_in_delta 0.6338176, @analyzer.average_request_time, 0.0000001
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_request_time_std_dev
|
141
|
+
assert_in_delta 0.4975667, @analyzer.request_time_std_dev, 0.0000001
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_slowest_db_times
|
145
|
+
times = @analyzer.slowest_db_times 3
|
146
|
+
assert_equal 3, times.length
|
147
|
+
expected = [
|
148
|
+
[1.143577, "TeamsController#progress"],
|
149
|
+
[0.914192, "ThingsController#view"],
|
150
|
+
[0.830409, "PeopleController#progress"]
|
151
|
+
]
|
152
|
+
assert_equal expected, times
|
153
|
+
end
|
154
|
+
|
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
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_slowest_render_times
|
164
|
+
times = @analyzer.slowest_render_times 3
|
165
|
+
assert_equal 3, times.length
|
166
|
+
expected = [
|
167
|
+
[0.695476, "PeopleController#view"],
|
168
|
+
[0.604444, "PeopleController#progress"],
|
169
|
+
[0.505973, "ThingsController#view"]
|
170
|
+
]
|
171
|
+
assert_equal expected, times
|
172
|
+
end
|
173
|
+
|
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
|
+
end
|
183
|
+
|
data/test/test_parser.rb
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
$TESTING = true
|
4
|
+
|
5
|
+
require 'tempfile'
|
6
|
+
require 'test/unit'
|
7
|
+
require 'stringio'
|
8
|
+
|
9
|
+
require 'production_log/parser'
|
10
|
+
|
11
|
+
class TestLogEntry < Test::Unit::TestCase
|
12
|
+
|
13
|
+
def setup
|
14
|
+
@entry = LogParser::LogEntry.new <<EOF
|
15
|
+
Processing TwinklerController#index (for 81.109.96.173 at Wed Dec 01 16:01:56 CST 2004)
|
16
|
+
Parameters: {\"action\"=>\"index\", \"controller\"=>\"twinkler\"}
|
17
|
+
Browser Load First (0.001114) SELECT * FROM browsers WHERE ubid = 'ixsXHgUo7U9PJGgBzr7e9ocaDOc=' LIMIT 1
|
18
|
+
Goal Count (0.001762) SELECT COUNT(*) FROM goals WHERE browser_id = '96181' and is_active = 1
|
19
|
+
Rendering twinkler/index within layouts/default
|
20
|
+
Rendering layouts/default (200 OK)
|
21
|
+
Completed in 0.616122 (1 reqs/sec) | Rendering: 0.242475 (39%) | DB: 0.002876 (0%)
|
22
|
+
EOF
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_parse
|
26
|
+
request = <<EOF
|
27
|
+
Processing RssController#uber (for 67.18.200.5 at Mon Mar 07 00:00:25 CST 2005)
|
28
|
+
Parameters: {:id=>"author", :"rss/uber/author.html/uber/author"=>nil, :action=>"uber", :username=>"looch", :controller=>"rss"}
|
29
|
+
Cookie set: auth=dc%2FGUP20BwziF%2BApGecc0pXB0PF0obi55az63ubAFtsnOOdJPkhfJH2U09yuzQD3WtdmWnydLzFcRA78kwi7Gw%3D%3D; path=/; expires=Thu, 05 Mar 2015 06:00:25 GMT
|
30
|
+
Cookie set: ubid=kF05DqFH%2F9hRCOxTz%2Bfb8Q7UV%2FI%3D; path=/; expires=Thu, 05 Mar 2015 06:00:25 GMT
|
31
|
+
Browser Load (0.003963) SELECT * FROM browsers WHERE ubid = 'kF05DqFH/9hRCOxTz+fb8Q7UV/I=' LIMIT 1
|
32
|
+
Person Load (0.002445) SELECT * FROM people WHERE username = 'looch' AND active = '1' LIMIT 1
|
33
|
+
ProfileImage Load (0.001554) SELECT * FROM profile_images WHERE id = 2782 LIMIT 1
|
34
|
+
Rendering rss/rss2.0 (200 OK)
|
35
|
+
Completed in 0.034519 (28 reqs/sec) | Rendering: 0.011770 (34%) | DB: 0.007962 (23%)
|
36
|
+
EOF
|
37
|
+
request = request.split "\n"
|
38
|
+
|
39
|
+
entry = LogParser::LogEntry.new []
|
40
|
+
|
41
|
+
entry.parse request
|
42
|
+
assert_kind_of LogParser::LogEntry, entry
|
43
|
+
assert_equal "RssController#uber", entry.page
|
44
|
+
assert_equal 3, entry.queries.length
|
45
|
+
assert_equal ['Browser Load', 0.003963], entry.queries.first
|
46
|
+
assert_equal 0.034519, entry.request_time
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_page
|
50
|
+
assert_equal "TwinklerController#index", @entry.page
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_ip
|
54
|
+
assert_equal "81.109.96.173", @entry.ip
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_time
|
58
|
+
assert_equal "Wed Dec 01 16:01:56 CST 2004", @entry.time
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_queries
|
62
|
+
expected = []
|
63
|
+
expected << ["Browser Load First", 0.001114]
|
64
|
+
expected << ["Goal Count", 0.001762]
|
65
|
+
assert_equal expected, @entry.queries
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_request_time
|
69
|
+
assert_equal 0.616122, @entry.request_time
|
70
|
+
|
71
|
+
@entry = LogParser::LogEntry.new "Processing TwinklerController#add_thing (for 144.164.232.114 at Wed Dec 01 16:01:56 CST 2004)
|
72
|
+
Completed in 0.261485 (3 reqs/sec) | DB: 0.009325 (3%)"
|
73
|
+
|
74
|
+
assert_equal 0.261485, @entry.request_time
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_render_time
|
78
|
+
assert_equal 0.242475, @entry.render_time
|
79
|
+
|
80
|
+
@entry = LogParser::LogEntry.new "Processing TwinklerController#add_thing (for 144.164.232.114 at Wed Dec 01 16:01:56 CST 2004)
|
81
|
+
Completed in 0.261485 (3 reqs/sec) | DB: 0.009325 (3%)"
|
82
|
+
|
83
|
+
assert_equal 0, @entry.render_time
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_db_time
|
87
|
+
assert_equal 0.002876, @entry.db_time
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
class TestLogParser <Test::Unit::TestCase
|
93
|
+
|
94
|
+
def test_class_parse
|
95
|
+
log = StringIO.new <<EOF
|
96
|
+
Mar 7 00:00:25 online1 rails[59628]: Processing RssController#uber (for 67.18.200.5 at Mon Mar 07 00:00:25 CST 2005)
|
97
|
+
Mar 7 00:00:25 online1 rails[59628]: Parameters: {:id=>"author", :"rss/uber/author.html/uber/author"=>nil, :action=>"uber", :username=>"looch", :controller=>"rss"}
|
98
|
+
Mar 7 00:00:25 online1 rails[59628]: Cookie set: auth=dc%2FGUP20BwziF%2BApGecc0pXB0PF0obi55az63ubAFtsnOOdJPkhfJH2U09yuzQD3WtdmWnydLzFcRA78kwi7Gw%3D%3D; path=/; expires=Thu, 05 Mar 2015 06:00:25 GMT
|
99
|
+
Mar 7 00:00:25 online1 rails[59628]: Cookie set: ubid=kF05DqFH%2F9hRCOxTz%2Bfb8Q7UV%2FI%3D; path=/; expires=Thu, 05 Mar 2015 06:00:25 GMT
|
100
|
+
Mar 7 00:00:25 online1 rails[59628]: Browser Load (0.003963) SELECT * FROM browsers WHERE ubid = 'kF05DqFH/9hRCOxTz+fb8Q7UV/I=' LIMIT 1
|
101
|
+
Mar 7 00:00:25 online1 rails[59628]: Person Load (0.002445) SELECT * FROM people WHERE username = 'looch' AND active = '1' LIMIT 1
|
102
|
+
Mar 7 00:00:25 online1 rails[59628]: ProfileImage Load (0.001554) SELECT * FROM profile_images WHERE id = 2782 LIMIT 1
|
103
|
+
Mar 7 00:00:25 online1 rails[59628]: Rendering rss/rss2.0 (200 OK)
|
104
|
+
Mar 7 00:00:25 online1 rails[59628]: Completed in 0.034519 (28 reqs/sec) | Rendering: 0.011770 (34%) | DB: 0.007962 (23%)
|
105
|
+
EOF
|
106
|
+
|
107
|
+
entries = []
|
108
|
+
|
109
|
+
LogParser.parse log do |entry|
|
110
|
+
entries << entry
|
111
|
+
end
|
112
|
+
|
113
|
+
assert_equal 1, entries.length
|
114
|
+
assert_equal 'RssController#uber', entries.first.page
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_class_parse_multi
|
118
|
+
entries = []
|
119
|
+
File.open 'test/test.syslog.log' do |fp|
|
120
|
+
LogParser.parse fp do |entry|
|
121
|
+
entries << entry
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
assert_equal 11, entries.length
|
126
|
+
assert_equal 'RssController#uber', entries.first.page
|
127
|
+
|
128
|
+
redirect = entries[5]
|
129
|
+
assert_equal 'TeamsController#progress', redirect.page
|
130
|
+
assert_equal 0, redirect.render_time
|
131
|
+
|
132
|
+
last = entries.last
|
133
|
+
assert_equal 'PeopleController#progress', last.page
|
134
|
+
assert_equal 0, last.request_time
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
# vim: ts=4 sts=4 sw=4
|
140
|
+
|
metadata
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.6
|
3
|
+
specification_version: 1
|
4
|
+
name: production_log_analyzer
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 1.1.0
|
7
|
+
date: 2005-03-30
|
8
|
+
summary: Extracts statistics from Rails production logs
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: hodel@robotcoop.com
|
12
|
+
homepage:
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire:
|
16
|
+
default_executable: pl_analyze
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
-
|
22
|
+
- ">"
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.0.0
|
25
|
+
version:
|
26
|
+
platform: ruby
|
27
|
+
authors:
|
28
|
+
- Eric Hodel
|
29
|
+
files:
|
30
|
+
- Rakefile
|
31
|
+
- README
|
32
|
+
- LICENSE
|
33
|
+
- Manifest.txt
|
34
|
+
- bin/pl_analyze
|
35
|
+
- lib/production_log/analyzer.rb
|
36
|
+
- lib/production_log/parser.rb
|
37
|
+
- lib/production_log/syslog_logger.rb
|
38
|
+
- test/test.syslog.log
|
39
|
+
- test/test_analyzer.rb
|
40
|
+
- test/test_parser.rb
|
41
|
+
test_files: []
|
42
|
+
rdoc_options: []
|
43
|
+
extra_rdoc_files: []
|
44
|
+
executables:
|
45
|
+
- pl_analyze
|
46
|
+
extensions: []
|
47
|
+
requirements: []
|
48
|
+
dependencies: []
|