bleak_house 6 → 7
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/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
|