bleak_house 7.1 → 7.2

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.
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'dike'
5
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + "/../../lib")
6
+ require 'bleak_house'
7
+
8
+ Dike.logfactory("/tmp")
9
+ if ARGV[0]
10
+ Dike.finger
11
+ exec('cat /tmp/0')
12
+ else
13
+ BleakHouse.snapshot("/tmp/0")
14
+ exec("#{$LOAD_PATH.first}/../bin/bleak /tmp/0")
15
+ end
16
+
@@ -0,0 +1,6 @@
1
+
2
+ require 'test/unit'
3
+ require 'open-uri'
4
+
5
+ HERE = File.expand_path(File.dirname(__FILE__))
6
+ $LOAD_PATH << HERE
@@ -1,33 +1,58 @@
1
1
 
2
- DIR = File.dirname(__FILE__) + "/../../"
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + "/../../lib")
3
3
 
4
+ ENV['NO_EXIT_HANDLER'] = "1"
5
+
6
+ require 'bleak_house'
4
7
  require 'rubygems'
8
+ require 'echoe'
5
9
  require 'test/unit'
6
- require 'yaml'
7
-
10
+
8
11
  class BleakHouseTest < Test::Unit::TestCase
9
- require "#{DIR}lib/bleak_house/c"
10
12
 
11
- SNAPSHOT_FILE = "/tmp/bleak_house"
12
- SNAPS = {:c => SNAPSHOT_FILE + ".c.yaml",
13
- :ruby => SNAPSHOT_FILE + ".rb.yaml"}
13
+ # Match the default hook filename, for convenience
14
+ FILE = "/tmp/bleak.#{Process.pid}.000.dump"
14
15
 
15
16
  def setup
17
+ File.delete FILE rescue nil
16
18
  end
17
19
 
18
- def test_c_snapshot
19
- File.delete SNAPS[:c] rescue nil
20
- ::BleakHouse::CLogger.new.snapshot(SNAPS[:c], "c_test", true)
21
- assert File.exist?(SNAPS[:c])
22
- assert_nothing_raised do
23
- assert YAML.load_file(SNAPS[:c]).is_a?(Array)
24
- end
20
+ def test_snapshot
21
+ BleakHouse.snapshot(FILE)
22
+ assert File.exist?(FILE)
23
+ assert BleakHouse.heaps_used > 0
24
+ assert BleakHouse.heaps_length > 0
25
25
  end
26
-
27
- def test_c_raises
26
+
27
+ def test_snapshot_gc_runs
28
+ BleakHouse.snapshot(FILE, 0)
29
+ assert File.exist?(FILE)
30
+ assert BleakHouse.heaps_used > 0
31
+ assert BleakHouse.heaps_length > 0
32
+ end
33
+
34
+ def test_exception
28
35
  assert_raises(RuntimeError) do
29
- ::BleakHouse::CLogger.new.snapshot("/", "c_test", true)
30
- end
36
+ BleakHouse.snapshot("/")
37
+ end
31
38
  end
32
-
39
+
40
+ def test_analyze
41
+ BleakHouse.snapshot(FILE)
42
+ Dir.chdir(File.dirname(__FILE__) + "/../../bin") do
43
+ output = `./bleak #{FILE}`.split("\n")
44
+ # require 'ruby-debug/debugger'
45
+ assert_match(/top 20 most common/, output[0])
46
+ assert_match(/free heap/, output[3])
47
+ assert_match(/\d+ __null__:__null__:__node__/, output[5])
48
+ end
49
+ end
50
+
51
+ def test_signal
52
+ Echoe.silence do
53
+ system("kill -s SIGUSR2 #{Process.pid}")
54
+ end
55
+ assert File.exist?(FILE)
56
+ end
57
+
33
58
  end
metadata CHANGED
@@ -1,116 +1,112 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.4
3
- specification_version: 1
4
2
  name: bleak_house
5
3
  version: !ruby/object:Gem::Version
6
- version: "7.1"
7
- date: 2007-08-06 00:00:00 -04:00
8
- summary: A Rails plugin for finding memory leaks.
9
- require_paths:
10
- - lib
11
- email: ""
12
- homepage: http://blog.evanweaver.com/pages/code#bleak_house
13
- rubyforge_project: fauna
14
- description: A Rails plugin for finding memory leaks.
15
- autorequire:
16
- default_executable:
17
- bindir: bin
18
- has_rdoc: true
19
- required_ruby_version: !ruby/object:Gem::Version::Requirement
20
- requirements:
21
- - - ">"
22
- - !ruby/object:Gem::Version
23
- version: 0.0.0
24
- version:
4
+ version: "7.2"
25
5
  platform: ruby
26
- signing_key:
27
- cert_chain:
28
- post_install_message: |+
29
-
30
- Thanks for installing BleakHouse.
31
-
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
-
35
- namespace :bleak_house do
36
- desc 'Analyze and chart all data'
37
- task :analyze do
38
- require 'bleak_house/analyze'
39
- BleakHouse::Analyze.build_all("#{RAILS_ROOT}/log/bleak_house_#{RAILS_ENV}.yaml.log")
40
- end
41
- end
42
-
43
-
44
6
  authors:
45
7
  - Evan Weaver
46
- files:
47
- - test/unit/test_bleak_house.rb
48
- - test/misc/direct.rb
49
- - tasks/bleak_house_tasks.rake
50
- - patches/gc.c.patch
51
- - lib/bleak_house.rb
52
- - lib/bleak_house/support_methods.rb
53
- - lib/bleak_house/rake_task_redefine_task.rb
54
- - lib/bleak_house/gruff_hacks.rb
55
- - lib/bleak_house/dispatcher.rb
56
- - lib/bleak_house/c.rb
57
- - lib/bleak_house/bleak_house.rb
58
- - lib/bleak_house/analyze.rb
59
- - lib/bleak_house/action_controller.rb
60
- - install.rb
61
- - init.rb
62
- - Rakefile
63
- - README
64
- - Manifest
65
- - LICENSE_BSD
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDLjCCAhagAwIBAgIBADANBgkqhkiG9w0BAQUFADA9MQ0wCwYDVQQDDARldmFu
14
+ MRgwFgYKCZImiZPyLGQBGRYIY2xvdWRidXIxEjAQBgoJkiaJk/IsZAEZFgJzdDAe
15
+ Fw0wNzA5MTYxMDMzMDBaFw0wODA5MTUxMDMzMDBaMD0xDTALBgNVBAMMBGV2YW4x
16
+ GDAWBgoJkiaJk/IsZAEZFghjbG91ZGJ1cjESMBAGCgmSJomT8ixkARkWAnN0MIIB
17
+ IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5C0Io89nyApnr+PvbNFge9Vs
18
+ yRWAlGBUEMahpXp28VrrfXZT0rAW7JBo4PlCE3jl4nE4dzE6gAdItSycjTosrw7A
19
+ Ir5+xoyl4Vb35adv56TIQQXvNz+BzlqnkAY5JN0CSBRTQb6mxS3hFyD/h4qgDosj
20
+ R2RFVzHqSxCS8xq4Ny8uzOwOi+Xyu4w67fI5JvnPvMxqrlR1eaIQHmxnf76RzC46
21
+ QO5QhufjAYGGXd960XzbQsQyTDUYJzrvT7AdOfiyZzKQykKt8dEpDn+QPjFTnGnT
22
+ QmgJBX5WJN0lHF2l1sbv3gh4Kn1tZu+kTUqeXY6ShAoDTyvZRiFqQdwh8w2lTQID
23
+ AQABozkwNzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU+WqJz3xQ
24
+ XSea1hRvvHWcIMgeeC4wDQYJKoZIhvcNAQEFBQADggEBAGLZ75jfOEW8Nsl26CTt
25
+ JFrWxQTcQT/UljeefVE3xYr7lc9oQjbqO3FOyued3qW7TaNEtZfSHoYeUSMYbpw1
26
+ XAwocIPuSRFDGM4B+hgQGVDx8PMGiJKom4qLXjO40UZsR7QyN/u869Vj45LURm6h
27
+ MBcPeqCASI+WNprj9+uZa2kmHiitrFqqfMBNlm5IFbn9XeYSta9AHVvs5QQqV2m5
28
+ hIPfLqCyxsn/YgOGvo6iwyQTWyTswamaAC3HRWZxIS1sfn/Ssqa7E7oQMkv5FAXr
29
+ x5rKePfXINf8XTJczkl9OBEYdE9aNdJsJpXD0asLgGVwBICS5Bjohp6mizJcDC1+
30
+ yZ0=
31
+ -----END CERTIFICATE-----
32
+
33
+ date: 2009-11-18 00:00:00 -08:00
34
+ default_executable:
35
+ dependencies: []
36
+
37
+ description: A library for finding memory leaks.
38
+ email: ""
39
+ executables:
40
+ - bleak
41
+ extensions:
42
+ - ext/extconf.rb
43
+ extra_rdoc_files:
44
+ - CHANGELOG
66
45
  - LICENSE
46
+ - LICENSE_BSD
47
+ - README
48
+ - TODO
49
+ - ext/snapshot.c
50
+ - lib/bleak_house.rb
51
+ - lib/bleak_house/analyzer.rb
52
+ - lib/bleak_house/hook.rb
53
+ files:
67
54
  - CHANGELOG
68
- test_files:
55
+ - LICENSE
56
+ - LICENSE_BSD
57
+ - Manifest
58
+ - README
59
+ - Rakefile
60
+ - TODO
61
+ - bin/bleak
62
+ - ext/build_ruby.rb
63
+ - ext/build_snapshot.rb
64
+ - ext/extconf.rb
65
+ - ext/snapshot.c
66
+ - ext/snapshot.h
67
+ - lib/bleak_house.rb
68
+ - lib/bleak_house/analyzer.rb
69
+ - lib/bleak_house/hook.rb
70
+ - ruby/ruby-1.8.7-p174.tar.bz2
71
+ - ruby/ruby-1.8.7.patch
72
+ - test/benchmark/bench.rb
73
+ - test/test_helper.rb
69
74
  - test/unit/test_bleak_house.rb
70
- rdoc_options: []
71
-
72
- extra_rdoc_files: []
73
-
74
- executables: []
75
-
76
- extensions: []
75
+ - bleak_house.gemspec
76
+ has_rdoc: true
77
+ homepage: http://blog.evanweaver.com/files/doc/fauna/bleak_house/
78
+ licenses: []
77
79
 
80
+ post_install_message:
81
+ rdoc_options:
82
+ - --line-numbers
83
+ - --inline-source
84
+ - --title
85
+ - Bleak_house
86
+ - --main
87
+ - README
88
+ require_paths:
89
+ - lib
90
+ - ext
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: "0"
96
+ version:
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: "1.2"
102
+ version:
78
103
  requirements: []
79
104
 
80
- dependencies:
81
- - !ruby/object:Gem::Dependency
82
- name: gruff
83
- version_requirement:
84
- version_requirements: !ruby/object:Gem::Version::Requirement
85
- requirements:
86
- - - "="
87
- - !ruby/object:Gem::Version
88
- version: 0.2.8
89
- version:
90
- - !ruby/object:Gem::Dependency
91
- name: rmagick
92
- version_requirement:
93
- version_requirements: !ruby/object:Gem::Version::Requirement
94
- requirements:
95
- - - ">"
96
- - !ruby/object:Gem::Version
97
- version: 0.0.0
98
- version:
99
- - !ruby/object:Gem::Dependency
100
- name: activesupport
101
- version_requirement:
102
- version_requirements: !ruby/object:Gem::Version::Requirement
103
- requirements:
104
- - - ">"
105
- - !ruby/object:Gem::Version
106
- version: 0.0.0
107
- version:
108
- - !ruby/object:Gem::Dependency
109
- name: RubyInline
110
- version_requirement:
111
- version_requirements: !ruby/object:Gem::Version::Requirement
112
- requirements:
113
- - - ">"
114
- - !ruby/object:Gem::Version
115
- version: 0.0.0
116
- version:
105
+ rubyforge_project: fauna
106
+ rubygems_version: 1.3.5
107
+ signing_key:
108
+ specification_version: 3
109
+ summary: A library for finding memory leaks.
110
+ test_files:
111
+ - test/test_helper.rb
112
+ - test/unit/test_bleak_house.rb
@@ -0,0 +1,2 @@
1
+ �UcNt@J�-�S�:�νN�wYi�\��.Z�������@��8�A��Lg���
2
+ 8k3&DL�R��7/�G��ڈ�c��x�ZF�(B<��I�U���@:﬊a]1�+(C�g����س2 ,�ˠ1�v���e�Y�XUӚ�V�"��Rb Ȇt1Mzn�+�ol<|���Z���0��Cst�:���+�����J롰�Fs�R��>m-�o�gb���9a��/�{�yo����Pm i��Tv�v[���� �(
data/init.rb DELETED
@@ -1,2 +0,0 @@
1
-
2
- require 'bleak_house'
data/install.rb DELETED
@@ -1,7 +0,0 @@
1
- puts "
2
-
3
- I was such a shy little thing that I seldom dared to open my lips,
4
- and never dared to open my heart, to anybody else.
5
- - Dickens, Bleak House
6
-
7
- "
@@ -1,17 +0,0 @@
1
-
2
- # Override ActionController::Base.process and process_with_exception to make sure the request tag for the snapshot gets set as a side-effect of request processing.
3
- class ActionController::Base
4
- class << self
5
- def process_with_bleak_house(request, *args)
6
- BleakHouse.set_request_name request
7
- process_without_bleak_house(request, *args)
8
- end
9
- alias_method_chain :process, :bleak_house
10
-
11
- def process_with_exception_with_bleak_house(request, *args)
12
- BleakHouse.set_request_name request, "/error"
13
- process_with_exception_without_bleak_house(request, *args)
14
- end
15
- alias_method_chain :process_with_exception, :bleak_house
16
- end
17
- end
@@ -1,196 +0,0 @@
1
-
2
- require 'rubygems'
3
- require 'fileutils'
4
- require 'yaml'
5
- require 'active_support'
6
-
7
- gem 'gruff', '= 0.2.8'
8
- require 'gruff'
9
-
10
- # require, but make rdoc not whine
11
- load "#{File.dirname(__FILE__)}/gruff_hacks.rb"
12
- load "#{File.dirname(__FILE__)}/support_methods.rb"
13
-
14
- Gruff::Base.send(:remove_const, "LEFT_MARGIN") # silence a warning
15
- Gruff::Base::LEFT_MARGIN = 200
16
- Gruff::Base::NEGATIVE_TOP_MARGIN = 30
17
- Gruff::Base::MAX_LEGENDS = 28
18
-
19
- class BleakHouse
20
- # Draws the BleakHouse graphs.
21
- class Analyze
22
-
23
- SMOOTHNESS = ENV['SMOOTHNESS'].to_i.zero? ? 1 : ENV['SMOOTHNESS'].to_i
24
- MEM_KEY = "memory usage"
25
- HEAP_KEY = "heap usage"
26
- CORE_KEY = "core rails"
27
-
28
- # Sets up a single graph.
29
- def initialize(data, increments, name)
30
- @data = data
31
- @increments = increments
32
- @name = name
33
- end
34
-
35
- def d #:nodoc:
36
- self.class.d
37
- end
38
-
39
- # Draw <tt>self</tt>. Use some special attributes added to Gruff. Requires the overrides in <tt>gruff_hacks.rb</tt>.
40
- def draw #:nodoc:
41
- g = Gruff::Line.new("1024x768")
42
- g.title = @name
43
- g.x_axis_label = "time"
44
- g.legend_font_size = g.legend_box_size = 14
45
- g.title_font_size = 24
46
- g.marker_font_size = 14
47
-
48
- # mangle some key names.
49
- # XXX unreadable
50
- @data.map do |key, values|
51
- ["#{(key.to_s.empty? ? '[Unknown]' : key).gsub(/.*::/, '')} (#{ if
52
- [MEM_KEY, HEAP_KEY].include?(key)
53
- 'relative'
54
- else
55
- values.to_i.max
56
- end })", values] # hax
57
- end.sort_by do |key, values|
58
- 0 - key[/.*?([\d]+)\)$/, 1].to_i
59
- end.each do |key, values|
60
- g.data(key, values.to_i)
61
- end
62
-
63
- labels = {}
64
- mod = (@increments.size / 4.0).ceil
65
- @increments.each_with_index do |increment, index|
66
- labels[index] = increment if (index % mod).zero?
67
- end
68
-
69
- g.labels = labels
70
-
71
- g.minimum_value = 0
72
- # g.maximum_value = @maximum
73
-
74
- g.write(@name.to_filename + ".png")
75
- end
76
-
77
- # Takes subkeys that match the <tt>selector</tt> regex and adds each subkey's count to the key named by the first group match in the <tt>namer</tt> regex for that subkey.
78
- def self.aggregate(data, selector = //, namer = //) #:nodoc:
79
- aggregate_data = {}
80
- increments = []
81
- data.each_with_index do |frameset, index|
82
- increments << frameset.time
83
- frameset.data.keys.select do |key|
84
- # aggregate common keys based on the selection regexs
85
- key =~ selector
86
- end.each do |key|
87
- aggregate_data[key.to_s[namer, 1]] ||= []
88
- aggregate_data[key.to_s[namer, 1]][index] += frameset.data[key].to_i
89
- end
90
- end
91
- aggregate_data.each do |key, value|
92
- # extend the length of every value set to the end of the run
93
- aggregate_data[key][increments.size - 1] ||= nil
94
- end
95
- [aggregate_data, increments]
96
- end
97
-
98
- # Generates a chart for each tag (by subtag) and subtag (by object type). Output is written to <tt>bleak_house/</tt> in the same folder as the passed <tt>logfile</tt> attribute.
99
- def self.build_all(logfile)
100
- unless File.exists? logfile
101
- puts "No data file found: #{logfile}"
102
- exit
103
- end
104
- puts "parsing data"
105
- data = YAML.load_file(logfile)
106
-
107
- rootdir = File.dirname(logfile) + "/bleak_house/"
108
- FileUtils.rm_r(rootdir) rescue nil
109
- Dir.mkdir(rootdir)
110
- Dir.chdir(rootdir) do
111
-
112
- labels = []
113
-
114
- # autodetect need for Rails snapshot conflation
115
- if data.first.last.keys.first =~ /^#{CORE_KEY}::::/
116
- # Rails snapshots double-count objects that start in the core and persist through the action (which is most core objects), so we need to the subtract core counts from action counts
117
- data = data[0..(-1 - data.size % 2)]
118
- data = data.in_groups_of(2).map do |frames|
119
- core, action = frames.first, frames.last
120
- action.data.each do |key, value|
121
- action.data[key] = value - core.data[key[/::::(.*)/,1]].to_i
122
- end
123
- [action.time, core.data.merge(action.data)]
124
- end
125
- puts " conflated core rails snapshots with their actions"
126
- labels = ["controller", "action"]
127
- else
128
- puts " assuming custom snapshotting"
129
- labels = ["tag", "subtag"]
130
- end
131
-
132
- # smooth frames (just an average)
133
- data = data[0..(-1 - data.size % SMOOTHNESS)]
134
- data = data.in_groups_of(SMOOTHNESS).map do |frames|
135
- timestamp = frames.map(&:time).sum / SMOOTHNESS
136
- values = frames.map(&:data).inject(Hash.new(0)) do |total, this_frame|
137
- this_frame.each do |key, value|
138
- total[key] += value / SMOOTHNESS.to_f
139
- end
140
- end
141
- [Time.at(timestamp).strftime("%H:%M:%S"), values]
142
- end
143
- puts " #{data.size} frames after smoothing"
144
-
145
- # scale memory/heap frames
146
- controller_data, increments = aggregate(data, //, /^(.*?)($|\/|::::)/)
147
- controller_data_without_specials = controller_data.dup
148
- controller_data_without_specials.delete(MEM_KEY)
149
- controller_data_without_specials.delete(HEAP_KEY)
150
- [HEAP_KEY, MEM_KEY].each do |key|
151
- scale_factor = controller_data_without_specials.values.flatten.to_i.max / controller_data[key].max.to_f * 0.8 rescue 1
152
- controller_data[key] = controller_data[key].map{|x| (x * scale_factor).to_i }
153
- end
154
-
155
- # generate initial controller graph
156
- puts(title = "objects by #{labels[0]}")
157
- Analyze.new(controller_data, increments, title).draw
158
-
159
- # in each controller, by action
160
- controller_data.keys.each do |controller|
161
- # next unless controller == HEAP_KEY
162
- @mem = [MEM_KEY, HEAP_KEY].include? controller
163
- @core = [CORE_KEY].include? controller
164
- Dir.descend(controller) do
165
- action_data, increments = aggregate(data, /^#{controller}($|\/|::::)/, /\/(.*?)($|\/|::::)/)
166
- unless @core
167
- puts(" " + (title = case controller
168
- when MEM_KEY then "#{controller} in kilobytes"
169
- when HEAP_KEY then "#{controller} in slots"
170
- else "objects by #{labels[1]} in /#{controller}/"
171
- end))
172
- Analyze.new(action_data, increments, title).draw
173
- end
174
-
175
- # in each action, by object class
176
- action_data.keys.each do |action|
177
- action = "unknown" if action.to_s == ""
178
- Dir.descend(@core ? "." : action) do
179
- puts((@core ? " " : " ") + (title = "objects by class in #{@core ? CORE_KEY : "/#{controller}/#{action}"}"))
180
- class_data, increments = aggregate(data, /^#{controller}#{"\/#{action}" unless action == "unknown"}($|\/|::::)/,
181
- /::::(.*)/)
182
- Analyze.new(class_data, increments, title).draw
183
- end
184
- end unless @mem
185
-
186
- end
187
- end
188
- end
189
- end
190
-
191
- def self.d #:nodoc:
192
- require 'ruby-debug'; Debugger.start; debugger
193
- end
194
-
195
- end
196
- end