bloat_check 0.0.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/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/README.rdoc +74 -0
- data/Rakefile +7 -0
- data/bloat_check.gemspec +24 -0
- data/lib/bloat_check.rb +42 -0
- data/lib/bloat_check/stats.rb +34 -0
- data/lib/bloat_check/version.rb +3 -0
- data/lib/bloat_check/wrap_requests.rb +18 -0
- data/spec/keyword_args_spec.rb +6 -0
- data/spec/spec_helper.rb +16 -0
- metadata +115 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Ronen Barzel
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
= bloat_check
|
2
|
+
|
3
|
+
BloatCheck is yet another tool for debugging bloat and memory leaks in ruby
|
4
|
+
projects. This one has the feature that you can wrap any bit of code with
|
5
|
+
a "BloatCheck" and it will log elapsed time, and memory & object growth.
|
6
|
+
|
7
|
+
Plus you can include it in any rails controller to log that same info per
|
8
|
+
request.
|
9
|
+
|
10
|
+
== Installation
|
11
|
+
|
12
|
+
Gemfile:
|
13
|
+
gem 'bloat_check'
|
14
|
+
|
15
|
+
== Usage: Ruby Code
|
16
|
+
|
17
|
+
Put this line anywhere:
|
18
|
+
|
19
|
+
BloatCheck.log("some label")
|
20
|
+
|
21
|
+
and it will write to the log the current time, process memory size, and 5 ruby
|
22
|
+
objects classes with most instances, prefixed with "BLOAT[pid]" and your label.
|
23
|
+
|
24
|
+
Wrap it around any existing code, such as
|
25
|
+
|
26
|
+
BloatCheck.log("here's looking at you") do
|
27
|
+
some_suspec_computation()
|
28
|
+
and_more()
|
29
|
+
end
|
30
|
+
|
31
|
+
And it will write to the log the deltas: elapsed time, change in memory
|
32
|
+
size, and 5 ruby object classes that had the largest increase in number of
|
33
|
+
instances.
|
34
|
+
|
35
|
+
== Usage: Rails Controllers
|
36
|
+
|
37
|
+
In a rails controller, you can do
|
38
|
+
|
39
|
+
class MyController < ApplicationController
|
40
|
+
include BloatCheck::WrapRequests
|
41
|
+
|
42
|
+
# etc.
|
43
|
+
end
|
44
|
+
|
45
|
+
and every request will log the deltas incurred during that request.
|
46
|
+
|
47
|
+
== Disabling (e.g., when running tests)
|
48
|
+
|
49
|
+
BloatCheck is slow (calls system 'ps', and runs through
|
50
|
+
ObjectSpace#each_object), so you might want to disable it in your unit
|
51
|
+
tests or integration tests. Do that via:
|
52
|
+
|
53
|
+
BloatCheck.disable = true
|
54
|
+
|
55
|
+
Put this, e.g. in your spec/spec_helper.rb file
|
56
|
+
|
57
|
+
== Choosing the logger
|
58
|
+
|
59
|
+
By default, BloatCheck logs to the Rails logger if Rails is defined, or to
|
60
|
+
STDOUT otherwise. But you can specify your own logger using
|
61
|
+
|
62
|
+
BloatCheck.logger = Logger.new(...)
|
63
|
+
|
64
|
+
|
65
|
+
== Versions
|
66
|
+
|
67
|
+
Has been tested on MRI 1.9.3
|
68
|
+
|
69
|
+
== History
|
70
|
+
|
71
|
+
== Copyright
|
72
|
+
|
73
|
+
Released under the MIT License. See LICENSE for details.
|
74
|
+
|
data/Rakefile
ADDED
data/bloat_check.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/bloat_check/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["ronen barzel"]
|
6
|
+
gem.email = ["ronen@barzel.org"]
|
7
|
+
gem.description = %q{Another ruby/rails bloat and memory leak debugging tool.}
|
8
|
+
gem.summary = %q{Another ruby/rails bloat and memory leak debugging tool.}
|
9
|
+
gem.homepage = "http://github.com/ronen/blo"
|
10
|
+
|
11
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
12
|
+
gem.files = `git ls-files`.split("\n")
|
13
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
|
+
gem.name = "bloat_check"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = BloatCheck::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency 'key_struct'
|
19
|
+
|
20
|
+
gem.add_development_dependency 'rake'
|
21
|
+
gem.add_development_dependency 'rspec'
|
22
|
+
gem.add_development_dependency 'simplecov'
|
23
|
+
gem.add_development_dependency 'simplecov-gem-adapter'
|
24
|
+
end
|
data/lib/bloat_check.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'bloat_check/version'
|
2
|
+
require 'bloat_check/stats'
|
3
|
+
require 'bloat_check/wrap_requests'
|
4
|
+
|
5
|
+
module BloatCheck
|
6
|
+
|
7
|
+
def self.disabled?
|
8
|
+
return true if @disabled
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.disable=(val)
|
12
|
+
@disabled = val
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.logger=(logger)
|
16
|
+
@logger = logger
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.logger
|
20
|
+
return @logger if @logger
|
21
|
+
return Rails.logger if defined? Rails
|
22
|
+
@logger ||= Logger.new(STDERR).tap { |logger|
|
23
|
+
logger.formatter = proc do |severity, datetime, progname, msg|
|
24
|
+
"#{msg}\n"
|
25
|
+
end
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.log(message)
|
30
|
+
start = Stats.get
|
31
|
+
if block_given?
|
32
|
+
begin
|
33
|
+
ret = yield
|
34
|
+
ensure
|
35
|
+
(Stats.get - start).log(message)
|
36
|
+
end
|
37
|
+
ret
|
38
|
+
else
|
39
|
+
start.log(message)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'key_struct'
|
2
|
+
|
3
|
+
module BloatCheck
|
4
|
+
class Stats < KeyStruct.reader(:memory, :counts, :time)
|
5
|
+
|
6
|
+
def to_s
|
7
|
+
"TIME=#{time.is_a?(Numeric) ? "#{time.round(1)} sec" : time} MEM=#{memory} OBJ: #{counts.sort_by(&:last).reverse[0...5].map(&it.join('>')).join(' ')}"
|
8
|
+
end
|
9
|
+
|
10
|
+
def log(prefix="")
|
11
|
+
BloatCheck.logger.warn("BLOAT[#{$$}] (#{Time.now}) #{prefix} #{self.to_s}") unless BloatCheck.disabled?
|
12
|
+
end
|
13
|
+
|
14
|
+
def -(other)
|
15
|
+
delta = {}
|
16
|
+
counts.each do |klass, count|
|
17
|
+
delta[klass] = count - other.counts[klass]
|
18
|
+
end
|
19
|
+
Stats.new(:memory => self.memory - other.memory, :counts => delta, :time => self.time - other.time)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.get
|
23
|
+
return new(:memory => 0, :counts => {}, :time => 0) if BloatCheck.disabled?
|
24
|
+
|
25
|
+
memory = `ps -o rss= -p #{$$}`.to_i
|
26
|
+
counts = Hash.new(0)
|
27
|
+
ObjectSpace.each_object do |obj|
|
28
|
+
klass = (class << obj ; superclass ; end) # can't use obj.class method since it may be overwritten
|
29
|
+
counts[klass] += 1
|
30
|
+
end
|
31
|
+
self.new(:memory => memory, :counts => counts, :time => Time.now)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module BloatCheck
|
2
|
+
module WrapRequests
|
3
|
+
def self.included(klass)
|
4
|
+
klass.class_eval do
|
5
|
+
before_filter :init_bloat_stats
|
6
|
+
after_filter :dump_bloat_stats
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def init_bloat_stats
|
11
|
+
@bloat_start = BloatCheck.stats
|
12
|
+
end
|
13
|
+
|
14
|
+
def dump_bloat_stats
|
15
|
+
(BloatCheck.stats - @bloat_start).log("REQ=#{request.method.inspect} URL=#{request.url.inspect}")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
if RUBY_VERSION > "1.9"
|
2
|
+
require 'simplecov'
|
3
|
+
require 'simplecov-gem-adapter'
|
4
|
+
SimpleCov.start 'gem'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rspec'
|
8
|
+
require 'bloat_check'
|
9
|
+
|
10
|
+
# Requires supporting files with custom matchers and macros, etc,
|
11
|
+
# in ./support/ and its subdirectories.
|
12
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
13
|
+
|
14
|
+
RSpec.configure do |config|
|
15
|
+
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bloat_check
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- ronen barzel
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-22 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: key_struct
|
16
|
+
requirement: &70128802826680 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70128802826680
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rake
|
27
|
+
requirement: &70128802826220 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70128802826220
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &70128802825780 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70128802825780
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: simplecov
|
49
|
+
requirement: &70128802825200 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70128802825200
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: simplecov-gem-adapter
|
60
|
+
requirement: &70128802824700 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70128802824700
|
69
|
+
description: Another ruby/rails bloat and memory leak debugging tool.
|
70
|
+
email:
|
71
|
+
- ronen@barzel.org
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- .gitignore
|
77
|
+
- Gemfile
|
78
|
+
- LICENSE
|
79
|
+
- README.rdoc
|
80
|
+
- Rakefile
|
81
|
+
- bloat_check.gemspec
|
82
|
+
- lib/bloat_check.rb
|
83
|
+
- lib/bloat_check/stats.rb
|
84
|
+
- lib/bloat_check/version.rb
|
85
|
+
- lib/bloat_check/wrap_requests.rb
|
86
|
+
- spec/keyword_args_spec.rb
|
87
|
+
- spec/spec_helper.rb
|
88
|
+
homepage: http://github.com/ronen/blo
|
89
|
+
licenses: []
|
90
|
+
post_install_message:
|
91
|
+
rdoc_options: []
|
92
|
+
require_paths:
|
93
|
+
- lib
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ! '>='
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
none: false
|
102
|
+
requirements:
|
103
|
+
- - ! '>='
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
requirements: []
|
107
|
+
rubyforge_project:
|
108
|
+
rubygems_version: 1.8.12
|
109
|
+
signing_key:
|
110
|
+
specification_version: 3
|
111
|
+
summary: Another ruby/rails bloat and memory leak debugging tool.
|
112
|
+
test_files:
|
113
|
+
- spec/keyword_args_spec.rb
|
114
|
+
- spec/spec_helper.rb
|
115
|
+
has_rdoc:
|