model_observer 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ec8feeb3833a59b988c7d230d4495e688bb23daa
4
+ data.tar.gz: 7a5ea18696fc7397111ab8047a00a0c6931d80a3
5
+ SHA512:
6
+ metadata.gz: c52ca71ef43463cedee183431c8c1e9cfb577c25869934cf4c66bca74628be653ba05bdb9e8a98e85ecec7a89f538fc0329b2a48f377979f9f20321f06f36555
7
+ data.tar.gz: e33777e428926ea72981bac2dfe9f97b81fe27a66f8953af896422c60fa19c9ceb17c63bc213f45ba63d9d0c87a87b76fc26b86ad1c22ad49fbde74c9e8491f0
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2013 Weihu Chen
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.md ADDED
@@ -0,0 +1,33 @@
1
+ # ModelObserver
2
+
3
+ A rails plugin to count the model object creations between each request, and help to find out the duplication.
4
+
5
+ [![Build Status](https://travis-ci.org/cctiger36/model_observer.png?branch=master)](https://travis-ci.org/cctiger36/model_observer) [![Code Climate](https://codeclimate.com/github/cctiger36/model_observer.png)](https://codeclimate.com/github/cctiger36/model_observer)
6
+
7
+ ## Installation
8
+
9
+ Add to your Gemfile
10
+
11
+ group :development do
12
+ gem 'model_observer'
13
+ end
14
+
15
+ and bundle
16
+
17
+ bundle
18
+
19
+ ## Log
20
+
21
+ The ModelObserver log will look like:
22
+
23
+ ===== Model Observer Start =====
24
+ Author: 1 sum(10ms) avg(10ms)
25
+ Book: 36 sum(13ms) avg(0ms)
26
+ id(20): 2
27
+ id(50): 9
28
+ id(61): 4
29
+ id(68): 2
30
+ id(111): 2
31
+ id(123): 3
32
+ id(124): 3
33
+ ===== Model Observer End =====
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ desc 'Default: run specs'
5
+ task :default => :spec
6
+
7
+ require 'rspec/core/rake_task'
8
+ RSpec::Core::RakeTask.new do |t|
9
+ t.pattern = "spec/**/*_spec.rb"
10
+ end
11
+
12
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,17 @@
1
+ module ModelObserver
2
+ module ActiveRecord
3
+ def self.enable
4
+ require 'active_record'
5
+ ::ActiveRecord::Inheritance::ClassMethods.class_eval do
6
+ alias_method :origin_instantiate, :instantiate
7
+
8
+ def instantiate(record)
9
+ started_at = Time.now
10
+ instance = origin_instantiate(record)
11
+ ModelObserver::Collector.add_metric(ModelObserver::Metric.new(instance, started_at, Time.now))
12
+ instance
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,33 @@
1
+ module ModelObserver
2
+ class Analyser
3
+ class << self
4
+ def result
5
+ text = ""
6
+ Collector.metrics_hash.each do |key, value|
7
+ sum_duration = value.map(&:duration).sum
8
+ average_duration = sum_duration / value.count
9
+ text << "#{key}: #{value.count} sum(#{sum_duration}ms) avg(#{average_duration}ms)\n"
10
+ text << analyse_single_class(value)
11
+ end
12
+ text.sub!(/\n$/, '')
13
+ text
14
+ end
15
+
16
+ def analyse_single_class(metrics)
17
+ return if metrics.empty?
18
+ primary_key = metrics.first.model_class.primary_key
19
+ hash = {}
20
+ metrics.each do |m|
21
+ hash[m.model_id] ||= 0
22
+ hash[m.model_id] += 1
23
+ end
24
+ hash
25
+ text = ""
26
+ hash.sort_by{|key, value| key}.each do |key, value|
27
+ text << " #{primary_key}(#{key}): #{value}\n" if value > 1
28
+ end
29
+ text
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,26 @@
1
+ module ModelObserver
2
+ class Collector
3
+ class << self
4
+ def metrics
5
+ @@metrics ||= []
6
+ end
7
+
8
+ def add_metric(metric)
9
+ metrics << metric
10
+ end
11
+
12
+ def clear
13
+ @@metrics = nil
14
+ end
15
+
16
+ def metrics_hash
17
+ hash = {}
18
+ metrics.each do |m|
19
+ hash[m.model_class.name] ||= []
20
+ hash[m.model_class.name] << m
21
+ end
22
+ hash
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,12 @@
1
+ module ModelObserver
2
+ module Dependency
3
+ def active_record?
4
+ @active_record ||= begin
5
+ require 'active_record'
6
+ true
7
+ rescue LoadError
8
+ false
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ module ModelObserver
2
+ class Metric
3
+ attr_accessor :model_class, :model_id, :started_at, :ended_at
4
+
5
+ def initialize(model, started_at, ended_at)
6
+ @model_class = model.class
7
+ @model_id = model.__send__(model.class.primary_key)
8
+ @started_at = started_at
9
+ @ended_at = ended_at
10
+ end
11
+
12
+ def duration
13
+ ((ended_at.to_f - started_at.to_f) * 1000).to_i
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ module ModelObserver
2
+ class Rack
3
+ def initialize(app)
4
+ @app = app
5
+ end
6
+
7
+ def call(env)
8
+ ModelObserver.start_request
9
+ response = @app.call(env)
10
+ ModelObserver.write_to_rails_log
11
+ ModelObserver.end_request
12
+ response
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ module ModelObserver
2
+ class Railtie < Rails::Railtie
3
+ initializer "model_observer.configure_rails_initialization" do |app|
4
+ app.middleware.use ModelObserver::Rack
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module ModelObserver
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,31 @@
1
+ require 'model_observer/dependency'
2
+ require 'model_observer/railtie'
3
+
4
+ module ModelObserver
5
+ extend Dependency
6
+
7
+ autoload :Metric, 'model_observer/metric'
8
+ autoload :Collector, 'model_observer/collector'
9
+ autoload :Analyser, 'model_observer/analyser'
10
+ autoload :Rack, 'model_observer/rack'
11
+
12
+ if active_record?
13
+ autoload :ActiveRecord, 'model_observer/active_record'
14
+ ModelObserver::ActiveRecord.enable
15
+ end
16
+
17
+ class << self
18
+ def start_request
19
+ end
20
+
21
+ def end_request
22
+ Collector.clear
23
+ end
24
+
25
+ def write_to_rails_log
26
+ Rails.logger.warn "===== Model Observer Start ====="
27
+ Rails.logger.warn Analyser.result
28
+ Rails.logger.warn "===== Model Observer End ====="
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :model_observer do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: model_observer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Weihu Chen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-09-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 3.1.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 3.1.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: sqlite3
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
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: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: A rails plugin to count the model object creations between each request,
56
+ and help to find out the duplication.
57
+ email:
58
+ - cctiger36@gmail.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - lib/model_observer/active_record.rb
64
+ - lib/model_observer/analyser.rb
65
+ - lib/model_observer/collector.rb
66
+ - lib/model_observer/dependency.rb
67
+ - lib/model_observer/metric.rb
68
+ - lib/model_observer/rack.rb
69
+ - lib/model_observer/railtie.rb
70
+ - lib/model_observer/version.rb
71
+ - lib/model_observer.rb
72
+ - lib/tasks/model_observer_tasks.rake
73
+ - MIT-LICENSE
74
+ - Rakefile
75
+ - README.md
76
+ homepage: https://github.com/cctiger36/model_observer
77
+ licenses:
78
+ - MIT
79
+ metadata: {}
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubyforge_project:
96
+ rubygems_version: 2.0.6
97
+ signing_key:
98
+ specification_version: 4
99
+ summary: Help to find out duplicated model object creations.
100
+ test_files: []