bleak_house 6 → 7
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +1 -0
- data/Rakefile +4 -4
- data/lib/bleak_house/analyze.rb +48 -36
- data/lib/bleak_house/bleak_house.rb +2 -4
- data/lib/bleak_house/c.rb +6 -2
- data/lib/bleak_house/dispatcher.rb +0 -2
- data/lib/bleak_house/gruff_hacks.rb +1 -1
- data/tasks/bleak_house_tasks.rake +3 -1
- metadata +7 -8
data/CHANGELOG
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
|
2
2
|
BleakHouse Changelog
|
3
3
|
|
4
|
+
7. detect if core keys are present or not; fixes for analyzing non-rails apps
|
4
5
|
6. log heap usage, remove pure-ruby profiler
|
5
6
|
5.3. subtract rails core counts from action counts and convolve
|
6
7
|
5.2. change smoothing algorithm to be more intuitive and so mem usage is correct
|
data/Rakefile
CHANGED
@@ -15,7 +15,7 @@ begin
|
|
15
15
|
VERS = `cat CHANGELOG`[/^([\d\.]+)\. /, 1]
|
16
16
|
|
17
17
|
taskmsg = File.open(DIR + "/tasks/bleak_house_tasks.rake").readlines
|
18
|
-
taskmsg = taskmsg[0..3] + [taskmsg[
|
18
|
+
taskmsg = taskmsg[0..3] + [taskmsg[9][2..-1]] + taskmsg[12..-1]
|
19
19
|
|
20
20
|
echoe = Echoe.new("bleak_house", VERS) do |p|
|
21
21
|
p.author = "Evan Weaver"
|
@@ -35,9 +35,9 @@ begin
|
|
35
35
|
"
|
36
36
|
Thanks for installing Bleak House #{VERS}.
|
37
37
|
|
38
|
-
For each Rails app you want to profile, you will need to add the
|
39
|
-
rake task in RAILS_ROOT/lib/tasks/bleak_house_tasks.rake
|
40
|
-
the analyzer:
|
38
|
+
For each Rails app you want to profile, you will need to add the
|
39
|
+
following rake task in RAILS_ROOT/lib/tasks/bleak_house_tasks.rake
|
40
|
+
to be able to run the analyzer:
|
41
41
|
" + taskmsg.join(" ") + "\n"}
|
42
42
|
end
|
43
43
|
|
data/lib/bleak_house/analyze.rb
CHANGED
@@ -11,6 +11,7 @@ require 'gruff'
|
|
11
11
|
load "#{File.dirname(__FILE__)}/gruff_hacks.rb"
|
12
12
|
load "#{File.dirname(__FILE__)}/support_methods.rb"
|
13
13
|
|
14
|
+
Gruff::Base.send(:remove_const, "LEFT_MARGIN") # silence a warning
|
14
15
|
Gruff::Base::LEFT_MARGIN = 200
|
15
16
|
Gruff::Base::NEGATIVE_TOP_MARGIN = 30
|
16
17
|
Gruff::Base::MAX_LEGENDS = 28
|
@@ -21,7 +22,7 @@ class BleakHouse
|
|
21
22
|
SMOOTHNESS = ENV['SMOOTHNESS'].to_i.zero? ? 1 : ENV['SMOOTHNESS'].to_i
|
22
23
|
MEM_KEY = "memory usage"
|
23
24
|
HEAP_KEY = "heap usage"
|
24
|
-
|
25
|
+
CORE_KEY = "core rails"
|
25
26
|
|
26
27
|
def initialize(data, increments, name)
|
27
28
|
@data = data
|
@@ -92,23 +93,31 @@ class BleakHouse
|
|
92
93
|
unless File.exists? filename
|
93
94
|
puts "No data file found: #{filename}"
|
94
95
|
exit
|
95
|
-
end
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
core
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
96
|
+
end
|
97
|
+
puts "parsing data"
|
98
|
+
data = YAML.load_file(filename)
|
99
|
+
|
100
|
+
rootdir = File.dirname(filename) + "/bleak_house/"
|
101
|
+
FileUtils.rm_r(rootdir) rescue nil
|
102
|
+
Dir.mkdir(rootdir)
|
103
|
+
Dir.chdir(rootdir) do
|
104
|
+
|
105
|
+
labels = ["controller", "action"]
|
106
|
+
# autodetect need for rails snapshot conflation
|
107
|
+
if data.first.last.keys.first =~ /^#{CORE_KEY}::::/
|
108
|
+
# subtract core counts from action
|
109
|
+
data = data[0..(-1 - data.size % 2)]
|
110
|
+
data = data.in_groups_of(2).map do |frames|
|
111
|
+
core, action = frames.first, frames.last
|
112
|
+
action.data.each do |key, value|
|
113
|
+
action.data[key] = value - core.data[key[/::::(.*)/,1]].to_i
|
114
|
+
end
|
115
|
+
[action.time, core.data.merge(action.data)]
|
116
|
+
end
|
117
|
+
puts " conflated core rails snapshots with their actions"
|
118
|
+
else
|
119
|
+
puts " assuming custom snapshotting"
|
120
|
+
labels = ["tag", "subtag"]
|
112
121
|
end
|
113
122
|
|
114
123
|
# smooth
|
@@ -122,45 +131,48 @@ class BleakHouse
|
|
122
131
|
end
|
123
132
|
[Time.at(timestamp).strftime("%H:%M:%S"), values]
|
124
133
|
end
|
125
|
-
puts "#{data.size} frames after smoothing"
|
126
|
-
|
127
|
-
# generate initial controller graph
|
128
|
-
puts "entire app"
|
134
|
+
puts " #{data.size} frames after smoothing"
|
129
135
|
|
136
|
+
# scale memory/heap frames
|
130
137
|
controller_data, increments = aggregate(data, //, /^(.*?)($|\/|::::)/)
|
131
138
|
controller_data_without_specials = controller_data.dup
|
132
139
|
controller_data_without_specials.delete(MEM_KEY)
|
133
140
|
controller_data_without_specials.delete(HEAP_KEY)
|
134
141
|
[HEAP_KEY, MEM_KEY].each do |key|
|
135
|
-
# next unless controller_data[key]
|
136
142
|
scale_factor = controller_data_without_specials.values.flatten.to_i.max / controller_data[key].max.to_f * 0.8 rescue 1
|
137
143
|
controller_data[key] = controller_data[key].map{|x| (x * scale_factor).to_i }
|
138
144
|
end
|
139
|
-
|
145
|
+
|
146
|
+
# generate initial controller graph
|
147
|
+
puts(title = "objects by #{labels[0]}")
|
148
|
+
Analyze.new(controller_data, increments, title).draw
|
140
149
|
|
141
150
|
# in each controller, by action
|
142
151
|
controller_data.keys.each do |controller|
|
143
152
|
# next unless controller == HEAP_KEY
|
144
|
-
@
|
145
|
-
|
153
|
+
@mem = [MEM_KEY, HEAP_KEY].include? controller
|
154
|
+
@core = [CORE_KEY].include? controller
|
146
155
|
Dir.descend(controller) do
|
147
156
|
action_data, increments = aggregate(data, /^#{controller}($|\/|::::)/, /\/(.*?)($|\/|::::)/)
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
157
|
+
unless @core
|
158
|
+
puts(" " + (title = case controller
|
159
|
+
when MEM_KEY then "#{controller} in kilobytes"
|
160
|
+
when HEAP_KEY then "#{controller} in slots"
|
161
|
+
else "objects by #{labels[1]} in /#{controller}/"
|
162
|
+
end))
|
163
|
+
Analyze.new(action_data, increments, title).draw
|
164
|
+
end
|
165
|
+
|
154
166
|
# in each action, by object class
|
155
167
|
action_data.keys.each do |action|
|
156
168
|
action = "unknown" if action.to_s == ""
|
157
|
-
|
158
|
-
|
169
|
+
Dir.descend(@core ? "." : action) do
|
170
|
+
puts((@core ? " " : " ") + (title = "objects by class in #{@core ? CORE_KEY : "/#{controller}/#{action}"}"))
|
159
171
|
class_data, increments = aggregate(data, /^#{controller}#{"\/#{action}" unless action == "unknown"}($|\/|::::)/,
|
160
172
|
/::::(.*)/)
|
161
|
-
Analyze.new(class_data, increments,
|
173
|
+
Analyze.new(class_data, increments, title).draw
|
162
174
|
end
|
163
|
-
end unless @
|
175
|
+
end unless @mem
|
164
176
|
|
165
177
|
end
|
166
178
|
end
|
data/lib/bleak_house/c.rb
CHANGED
@@ -181,17 +181,21 @@ class BleakHouse
|
|
181
181
|
}
|
182
182
|
}
|
183
183
|
}
|
184
|
-
/* fprintf(obj_log, \" :\\"heap usage/ruby heaps\\": %i\\n", rb_gc_heaps_used()); */
|
185
184
|
fprintf(obj_log, \" :\\"heap usage/filled slots\\": %i\\n", filled_slots);
|
186
185
|
fprintf(obj_log, \" :\\"heap usage/free slots\\": %i\\n", free_slots);
|
187
186
|
for (j = 0; j < current_pos; j++) {
|
188
187
|
fprintf(obj_log, " :\\"%s\\": %i\\n", tags[j], counts[j]);
|
189
188
|
}
|
190
189
|
fclose(obj_log);
|
190
|
+
|
191
|
+
/* request GC run */
|
192
|
+
rb_funcall(rb_mGC, rb_intern("start"), 0);
|
193
|
+
/* to get a custom module: rb_const_get(parentModule, "ModuleName")
|
194
|
+
parent module can be something like rb_mKernel for the toplevel */
|
191
195
|
return Qtrue;
|
192
196
|
}
|
193
197
|
EOC
|
194
198
|
end
|
195
199
|
|
196
200
|
end
|
197
|
-
end
|
201
|
+
end
|
@@ -6,13 +6,11 @@ class Dispatcher
|
|
6
6
|
def prepare_application_with_bleak_house
|
7
7
|
prepare_application_without_bleak_house
|
8
8
|
BleakHouse::MEMLOGGER.snapshot(BleakHouse::LOGFILE, 'core rails', BleakHouse::WITH_SPECIALS)
|
9
|
-
GC.start if BleakHouse::GC
|
10
9
|
end
|
11
10
|
alias_method_chain :prepare_application, :bleak_house
|
12
11
|
|
13
12
|
def reset_after_dispatch_with_bleak_house
|
14
13
|
BleakHouse::MEMLOGGER.snapshot(BleakHouse::LOGFILE, BleakHouse.last_request_name || 'unknown', BleakHouse::WITH_SPECIALS)
|
15
|
-
GC.start if BleakHouse::GC
|
16
14
|
reset_after_dispatch_without_bleak_house
|
17
15
|
end
|
18
16
|
alias_method_chain :reset_after_dispatch, :bleak_house
|
@@ -15,7 +15,7 @@ class Gruff::Base
|
|
15
15
|
@legend_labels.each_with_index do |legend_label, index|
|
16
16
|
|
17
17
|
next if index > MAX_LEGENDS
|
18
|
-
legend_label = "
|
18
|
+
legend_label = "some not shown" if index == MAX_LEGENDS
|
19
19
|
|
20
20
|
# Draw label
|
21
21
|
@d.fill = @font_color
|
@@ -3,10 +3,12 @@ namespace :bleak_house do
|
|
3
3
|
desc 'Analyze and chart all data'
|
4
4
|
task :analyze do
|
5
5
|
begin
|
6
|
-
gem 'gruff', '= 0.2.8'
|
6
|
+
gem 'gruff', '= 0.2.8' # fail early if gruff is missing
|
7
7
|
require "#{File.dirname(__FILE__)}/../lib/bleak_house/analyze"
|
8
|
+
puts "loaded vendor/plugins version"
|
8
9
|
rescue LoadError
|
9
10
|
require 'bleak_house/analyze'
|
11
|
+
puts "loaded gem version"
|
10
12
|
end
|
11
13
|
BleakHouse::Analyze.build_all("#{RAILS_ROOT}/log/bleak_house_#{RAILS_ENV}.yaml.log")
|
12
14
|
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
|
|
3
3
|
specification_version: 1
|
4
4
|
name: bleak_house
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: "
|
7
|
-
date: 2007-05-
|
6
|
+
version: "7"
|
7
|
+
date: 2007-05-13 00:00:00 -07:00
|
8
8
|
summary: BleakHouse is a Rails plugin for finding memory leaks. It tracks ObjectSpace for your entire app, and produces charts of references by controller, by action, and by object class.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -27,17 +27,16 @@ signing_key:
|
|
27
27
|
cert_chain:
|
28
28
|
post_install_message: |+
|
29
29
|
|
30
|
-
Thanks for installing Bleak House
|
30
|
+
Thanks for installing Bleak House 7.
|
31
31
|
|
32
|
-
For each Rails app you want to profile, you will need to add the
|
33
|
-
rake task in RAILS_ROOT/lib/tasks/bleak_house_tasks.rake
|
34
|
-
the analyzer:
|
32
|
+
For each Rails app you want to profile, you will need to add the
|
33
|
+
following rake task in RAILS_ROOT/lib/tasks/bleak_house_tasks.rake
|
34
|
+
to be able to run the analyzer:
|
35
35
|
|
36
36
|
namespace :bleak_house do
|
37
37
|
desc 'Analyze and chart all data'
|
38
38
|
task :analyze do
|
39
|
-
|
40
|
-
end
|
39
|
+
require 'bleak_house/analyze'
|
41
40
|
BleakHouse::Analyze.build_all("#{RAILS_ROOT}/log/bleak_house_#{RAILS_ENV}.yaml.log")
|
42
41
|
end
|
43
42
|
end
|