birth_control 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +9 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +13 -0
- data/README.md +62 -0
- data/Rakefile +1 -0
- data/birth_control.gemspec +28 -0
- data/lib/birth_control.rb +21 -0
- data/lib/birth_control/counter.rb +22 -0
- data/lib/birth_control/extensions/active_record.rb +15 -0
- data/lib/birth_control/extensions/controller.rb +20 -0
- data/lib/birth_control/railtie.rb +10 -0
- data/lib/birth_control/report.rb +59 -0
- data/lib/birth_control/version.rb +3 -0
- data/spec/lib/birth_control/counter_spec.rb +40 -0
- data/spec/lib/birth_control/report_spec.rb +23 -0
- data/spec/lib/birth_control_spec.rb +12 -0
- data/spec/spec_helper.rb +13 -0
- metadata +152 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3904cd8ccfa1d3999f2ff5611bce9e262a09f6b2
|
4
|
+
data.tar.gz: a1c6f5c1995106164acee1dd712aed0747ac1f66
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0d97df7b6818906dc7c538f703190ab7bfd82b12f026d4bd09f15895b1e13f2a386e365ad6b1f12cf7ee691570164e8564b2d12b0312dfc6f359239c46039d76
|
7
|
+
data.tar.gz: 19803e430038e1ab9fc303ad3669bc820de8bb948d1170bb3dcfee498b19b143f64f4ee8c28089de068a3a28086206bed6bc6cfa7954691b2aca898fe832517f
|
data/.gitignore
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
birth_control
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.0.0
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
2
|
+
Version 2, December 2004
|
3
|
+
|
4
|
+
Copyright (c) 2013 Johannes Opper
|
5
|
+
|
6
|
+
Everyone is permitted to copy and distribute verbatim or modified
|
7
|
+
copies of this license document, and changing it is allowed as long
|
8
|
+
as the name is changed.
|
9
|
+
|
10
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
11
|
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
12
|
+
|
13
|
+
0. You just DO WHAT THE FUCK YOU WANT TO.
|
data/README.md
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# BirthControl
|
2
|
+
|
3
|
+
Count active record instantiations and report them to the log.
|
4
|
+
|
5
|
+
[](http://travis-ci.org/xijo/birth_control)
|
6
|
+
|
7
|
+
[](http://coderwall.com/xijo)
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
gem 'birth_control', groups: [:development]
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
After bundling you'll need to enable the logging by putting this line into your development environment:
|
20
|
+
|
21
|
+
BirthControl.enable = true
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
Two new reports will be logged into your rails log:
|
26
|
+
|
27
|
+
1. The class instantiation report - count all active record objects by class and in total
|
28
|
+
2. Duplication report - reveals where active record objects were loaded more than once
|
29
|
+
|
30
|
+
### Example reports:
|
31
|
+
|
32
|
+
This example show the result of a project detail page. You can see, that there were 5 project instantiations but always the same project. The first two may be necassary, but the later 3 could have been avoided.
|
33
|
+
|
34
|
+
*** [BirthControl] Class instantiation overview ***
|
35
|
+
5 Projects
|
36
|
+
20 ProjectPictures
|
37
|
+
2 Users
|
38
|
+
1 Countries
|
39
|
+
3 BlogPosts
|
40
|
+
30 Total
|
41
|
+
|
42
|
+
*** [BirthControl] Duplicate instantiation detected ***
|
43
|
+
|
44
|
+
Project(42) - 5 times
|
45
|
+
1. app/controllers/projects_controller.rb:27:in `load_project_for_caching'
|
46
|
+
2. app/controllers/projects_controller.rb:13:in `show'
|
47
|
+
3. app/views/projects/_blog_post.html.slim:3:in `...'
|
48
|
+
4. app/views/projects/_blog_post.html.slim:3:in `...'
|
49
|
+
5. app/views/projects/_blog_post.html.slim:3:in `...'
|
50
|
+
|
51
|
+
## Contributing
|
52
|
+
|
53
|
+
1. Fork it
|
54
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
55
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
56
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
57
|
+
5. Create new Pull Request
|
58
|
+
|
59
|
+
## Changelog
|
60
|
+
|
61
|
+
**0.0.1** (*2013-11-16*)
|
62
|
+
* Initial import, basic reports
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'birth_control/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "birth_control"
|
8
|
+
spec.version = BirthControl::VERSION
|
9
|
+
spec.authors = ["Johannes Opper"]
|
10
|
+
spec.email = ["xijo@gmx.de"]
|
11
|
+
spec.description = %q{Count active record instantiations and report them to the log}
|
12
|
+
spec.summary = %q{Count active record instantiations and report them to the log}
|
13
|
+
spec.homepage = "http://github.com/xijo/birth_control"
|
14
|
+
spec.license = "WTFPL"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency 'terminal-table'
|
22
|
+
spec.add_dependency 'actionpack'
|
23
|
+
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
25
|
+
spec.add_development_dependency 'rake'
|
26
|
+
spec.add_development_dependency 'rspec'
|
27
|
+
spec.add_development_dependency 'simplecov'
|
28
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'terminal-table'
|
3
|
+
require 'singleton'
|
4
|
+
|
5
|
+
module BirthControl
|
6
|
+
def self.enable=(enable)
|
7
|
+
@enabled = enable
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.enabled?
|
11
|
+
!!@enabled
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
require 'birth_control/extensions/active_record'
|
16
|
+
require 'birth_control/extensions/controller'
|
17
|
+
require 'birth_control/counter'
|
18
|
+
require 'birth_control/railtie' if defined?(Rails)
|
19
|
+
require 'birth_control/report'
|
20
|
+
require 'birth_control/version'
|
21
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module BirthControl
|
2
|
+
class Counter
|
3
|
+
include Singleton
|
4
|
+
|
5
|
+
attr_accessor :results
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
reset
|
9
|
+
end
|
10
|
+
|
11
|
+
def count(klass, id, caller = [])
|
12
|
+
@results[klass] ||= {}
|
13
|
+
@results[klass][id] ||= []
|
14
|
+
@results[klass][id] << caller
|
15
|
+
@results
|
16
|
+
end
|
17
|
+
|
18
|
+
def reset
|
19
|
+
@results = {}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module BirthControl
|
2
|
+
module Extensions
|
3
|
+
module ActiveRecord
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
after_initialize :count_class_instantiation
|
8
|
+
end
|
9
|
+
|
10
|
+
def count_class_instantiation
|
11
|
+
BirthControl::Counter.instance.count(self.class.name, id, caller)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module BirthControl
|
2
|
+
module Extensions
|
3
|
+
module Controller
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
before_filter :reset_birth_control
|
8
|
+
after_filter :birth_control_report
|
9
|
+
end
|
10
|
+
|
11
|
+
def reset_birth_control
|
12
|
+
BirthControl::Counter.instance.reset
|
13
|
+
end
|
14
|
+
|
15
|
+
def birth_control_report
|
16
|
+
Rails.logger.warn BirthControl::Report.new(BirthControl::Counter.instance.results)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module BirthControl
|
2
|
+
class Railtie < Rails::Railtie
|
3
|
+
initializer 'birth_control.initialize_extensions' do
|
4
|
+
if BirthControl.enabled?
|
5
|
+
ActiveRecord::Base.send :include, BirthControl::Extensions::ActiveRecord
|
6
|
+
ActionController::Base.send :include, BirthControl::Extensions::Controller
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module BirthControl
|
2
|
+
class Report
|
3
|
+
def initialize(results)
|
4
|
+
@results = results
|
5
|
+
end
|
6
|
+
|
7
|
+
def count_class_and_id(klass, id)
|
8
|
+
@results[klass][id].size
|
9
|
+
end
|
10
|
+
|
11
|
+
def count_class(klass)
|
12
|
+
@results[klass].inject(0) { |c, (id, _)| c + count_class_and_id(klass, id) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def count
|
16
|
+
@results.inject(0) { |c, (klass, _)| c + count_class(klass) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def duplication_report
|
20
|
+
lines = []
|
21
|
+
|
22
|
+
@results.each do |klass, entries|
|
23
|
+
entries.each do |id, callers|
|
24
|
+
if callers.size > 1
|
25
|
+
lines << "\n#{klass}(#{id}) - #{callers.size} times"
|
26
|
+
callers.each_with_index do |caller, index|
|
27
|
+
occurence = caller.detect { |call| call.match(/app\//) }
|
28
|
+
occurence.sub!(/(.*)\/app\//, 'app/')
|
29
|
+
lines << " #{index+1}. #{occurence}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
if lines.size > 0
|
35
|
+
lines.unshift "*** [BirthControl] Duplicate instantiation detected ***"
|
36
|
+
lines.join("\n") + "\n"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def class_instantiation_report
|
41
|
+
lines = ["*** [BirthControl] Class instantiation overview ***"]
|
42
|
+
@results.each do |klass, _|
|
43
|
+
count = "%5s" % count_class(klass)
|
44
|
+
lines << "#{count} #{klass.pluralize}"
|
45
|
+
end
|
46
|
+
lines << "#{"%5s" % count} Total"
|
47
|
+
lines.join("\n") + "\n"
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_s
|
51
|
+
lines = [
|
52
|
+
'[BirthControl]',
|
53
|
+
class_instantiation_report,
|
54
|
+
duplication_report
|
55
|
+
]
|
56
|
+
lines.join "\n"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BirthControl::Counter do
|
4
|
+
|
5
|
+
let(:counter) { BirthControl::Counter.instance }
|
6
|
+
after { counter.reset }
|
7
|
+
|
8
|
+
it 'behaves as singleton' do
|
9
|
+
counter.should eq BirthControl::Counter.instance
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#reset' do
|
13
|
+
it 'removes all existing results' do
|
14
|
+
counter.results = :something
|
15
|
+
counter.reset
|
16
|
+
counter.results.should eq({})
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#count' do
|
21
|
+
it 'groups results by class' do
|
22
|
+
counter.count('Foo', 1)
|
23
|
+
counter.count('Bar', 1)
|
24
|
+
counter.results.should have(2).keys
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'counts different ids per class' do
|
28
|
+
counter.count 'Foo', 1
|
29
|
+
counter.count 'Foo', 2
|
30
|
+
counter.results['Foo'].should have(2).keys
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'groups multiple occurencies of the same id' do
|
34
|
+
counter.count('Foo', 1)
|
35
|
+
counter.count('Foo', 1)
|
36
|
+
counter.results['Foo'][1].should have(2).entries
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BirthControl::Report do
|
4
|
+
let(:results) do
|
5
|
+
{
|
6
|
+
'Project' => {
|
7
|
+
1 => [['somewhere/app/models/project.rb:123'], ['somewhere/lib/project_counter.rb:1']],
|
8
|
+
2 => [['somewhere/app/models/project.rb:123']]
|
9
|
+
},
|
10
|
+
'User' => {
|
11
|
+
1 => [['somewhere/app/controllers/sessions_controller.rb:1']],
|
12
|
+
}
|
13
|
+
}
|
14
|
+
end
|
15
|
+
let(:report) { BirthControl::Report.new(results) }
|
16
|
+
|
17
|
+
it '#count returns total of all counted objects' do
|
18
|
+
report.count_class_and_id('Project', 1).should eq 2
|
19
|
+
report.count_class('Project').should eq 3
|
20
|
+
report.count.should eq 4
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: birth_control
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Johannes Opper
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-11-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: terminal-table
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: actionpack
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: Count active record instantiations and report them to the log
|
98
|
+
email:
|
99
|
+
- xijo@gmx.de
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- .gitignore
|
105
|
+
- .ruby-gemset
|
106
|
+
- .ruby-version
|
107
|
+
- .travis.yml
|
108
|
+
- Gemfile
|
109
|
+
- LICENSE.txt
|
110
|
+
- README.md
|
111
|
+
- Rakefile
|
112
|
+
- birth_control.gemspec
|
113
|
+
- lib/birth_control.rb
|
114
|
+
- lib/birth_control/counter.rb
|
115
|
+
- lib/birth_control/extensions/active_record.rb
|
116
|
+
- lib/birth_control/extensions/controller.rb
|
117
|
+
- lib/birth_control/railtie.rb
|
118
|
+
- lib/birth_control/report.rb
|
119
|
+
- lib/birth_control/version.rb
|
120
|
+
- spec/lib/birth_control/counter_spec.rb
|
121
|
+
- spec/lib/birth_control/report_spec.rb
|
122
|
+
- spec/lib/birth_control_spec.rb
|
123
|
+
- spec/spec_helper.rb
|
124
|
+
homepage: http://github.com/xijo/birth_control
|
125
|
+
licenses:
|
126
|
+
- WTFPL
|
127
|
+
metadata: {}
|
128
|
+
post_install_message:
|
129
|
+
rdoc_options: []
|
130
|
+
require_paths:
|
131
|
+
- lib
|
132
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - '>='
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
requirements: []
|
143
|
+
rubyforge_project:
|
144
|
+
rubygems_version: 2.0.3
|
145
|
+
signing_key:
|
146
|
+
specification_version: 4
|
147
|
+
summary: Count active record instantiations and report them to the log
|
148
|
+
test_files:
|
149
|
+
- spec/lib/birth_control/counter_spec.rb
|
150
|
+
- spec/lib/birth_control/report_spec.rb
|
151
|
+
- spec/lib/birth_control_spec.rb
|
152
|
+
- spec/spec_helper.rb
|