method_meter 0.1.0 → 0.4.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: dfae0d180c684c345b21ad7c7c7a130ec2af9d5a
4
- data.tar.gz: 6844bd7f03f96d13c228fe28d11f5d7b783eeb16
2
+ SHA256:
3
+ metadata.gz: 3a5ff992ee06f786d08c62136e9c793d3c0810ce19b70feefadf298004d83d58
4
+ data.tar.gz: 36882deddbc956bcfc5baa29326f03a713c27de09cd00f833d88da6acf722ae4
5
5
  SHA512:
6
- metadata.gz: daaeb86102d7554627447f06d5fff8b076db1cc6be1a79026dc05d454f8c87d829d9d165c56eedf0f78b4ea988a9e9099ffff5bcd74be61674ccafced068c2e7
7
- data.tar.gz: f7cddc1da6977de3551e7fc4dd466b6bf5bf0466afcfdc188796b7448413b8bddee97a296eb4ba310f7b5a423b92d8f2888c9d07c967fd91ac384f78349b8133
6
+ metadata.gz: bb17a7e2982862a37acdadaf2adc7f981b06be55b57188a6e1ecb31cdcb1301ba9ad70f01fb21e06ca764931c4a3305bf7a01e88ba5897c9750b7dad2ffe2ccf
7
+ data.tar.gz: 41c3ed52140bbe3260f12152385261ac6360f8de87479674277277c146e81ea3589162b1cc35cddf1c442fd946fa05496ec670a09282f217f82076b0ab430686
@@ -0,0 +1,18 @@
1
+ version: v1.0
2
+ name: Initial Pipeline
3
+ agent:
4
+ machine:
5
+ type: e1-standard-2
6
+ os_image: ubuntu1804
7
+ blocks:
8
+ - name: Test
9
+ task:
10
+ jobs:
11
+ - name: rspec
12
+ commands:
13
+ - checkout
14
+ - sem-version ruby 2.6.5
15
+ - cache restore
16
+ - bundle install --path vendor/bundle
17
+ - cache store
18
+ - bundle exec rspec
data/1-basic-rb.gif ADDED
Binary file
data/Gemfile CHANGED
@@ -1,10 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
-
5
3
  # Specify your gem's dependencies in method_meter.gemspec
6
- gemspec
7
-
8
- gem 'activesupport'
9
- gem 'awesome_print'
10
- gem 'defined_methods'
4
+ gemspec
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # MethodMeter
1
+ # MethodMeter [![Build Status](https://wnuqui.semaphoreci.com/badges/method_meter/branches/master.svg?style=shields)](https://wnuqui.semaphoreci.com/projects/method_meter)
2
2
 
3
- `MethodMeter` is a library module that instruments methods defined in a given object. These methods are not from included or extended modules. These methods are not also from parent objects. By object, it means either a `class` or `module`.
3
+ `MethodMeter` is a library module that instruments **methods defined in a given object**. These methods are NOT from included or extended modules. These methods are also NOT from parent objects. By object, it means either a `class` or `module`.
4
4
 
5
5
  ## Installation
6
6
 
@@ -41,6 +41,10 @@ ap MethodMeter.measurement
41
41
 
42
42
  More examples found here: https://github.com/wnuqui/method_meter/tree/master/examples
43
43
 
44
+ ## In action
45
+
46
+ ![method_meter in action](1-basic-rb.gif)
47
+
44
48
  ## Development
45
49
 
46
50
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -49,7 +53,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
49
53
 
50
54
  ## Contributing
51
55
 
52
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/method_meter. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
56
+ Bug reports and pull requests are welcome on GitHub at https://github.com/wnuqui/method_meter. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
53
57
 
54
58
  ## License
55
59
 
data/bin/console CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'bundler/setup'
4
4
  require 'method_meter'
5
+ require 'awesome_print'
5
6
 
6
7
  # You can add fixtures and/or initialization code here to make experimenting
7
8
  # with your gem easier. You can also use a different console, if you like.
@@ -0,0 +1,21 @@
1
+ require_relative 'helper'
2
+
3
+ # values set will not be profiled/instrumented
4
+ MethodMeter.exceptions = [:perform_addition]
5
+
6
+ MethodMeter.observe Arithmeter
7
+
8
+ MethodMeter.measure!('key-1') do
9
+ arithmeter = Arithmeter.new
10
+ arithmeter.add 1, 3
11
+
12
+ Arithmeter.sum 1, 3
13
+
14
+ arithmeter = Arithmeter.new
15
+ arithmeter.add 4, 3
16
+
17
+ Arithmeter.sum 4, 3
18
+ end
19
+
20
+ ap MethodMeter.data
21
+ ap MethodMeter.measurement
data/lib/method_meter.rb CHANGED
@@ -1,85 +1,110 @@
1
1
  require 'method_meter/version'
2
2
 
3
- require 'byebug'
4
3
  require 'active_support'
5
- require 'active_support/core_ext/string'
6
4
  require 'defined_methods'
7
5
 
8
6
  module MethodMeter
9
- mattr_accessor :events, :subscribers, :data
7
+ mattr_accessor :metered_methods, :subscribers, :data, :exceptions
10
8
 
11
9
  class << self
12
- def observe(object=Arithmeter)
13
- self.events = [] if self.events.blank?
10
+ def observe(object, excepted_methods=[])
11
+ init excepted_methods
14
12
 
15
13
  DefinedMethods.in(object).each do |group|
16
14
  group[:object].module_eval do
17
15
  group[:methods].each do |method|
18
- method_with_profiling = method.to_s + '_with_profiling'
19
- method_without_profiling = method.to_s + '_without_profiling'
20
- event_name = DefinedMethods.fqmn(group, method)
21
-
22
- next if event_name =~ /_profiling/
23
- next if MethodMeter.events.include?(event_name)
24
-
25
- MethodMeter.events << event_name
26
-
27
- define_method(method_with_profiling) do |*args, &block|
28
- ActiveSupport::Notifications.instrument(event_name, args) do
29
- send(method_without_profiling, *args, &block)
30
- end
31
- end
32
-
33
- alias_method method_without_profiling, method
34
- alias_method method, method_with_profiling
35
-
36
- private method_with_profiling if group[:private]
37
- protected method_with_profiling if group[:protected]
16
+ MethodMeter.define_metering_method(group[:object], method, group[:private], group[:protected], group[:singleton])
38
17
  end
39
18
  end
40
19
  end
41
20
  end
42
21
 
43
22
  def measure!(key)
44
- self.subscribers = []
45
- self.data = {} if self.data.blank?
46
- self.data[key] = {}
47
-
48
- self.events.each do |event|
49
- self.subscribers << ActiveSupport::Notifications.subscribe(event) do |_, started_at, finished_at, _, _|
50
- self.data[key][event] = [] unless self.data[key].has_key?(event)
51
- self.data[key][event] << (finished_at - started_at)
23
+ data[key] = {}
24
+
25
+ metered_methods.each do |metered_method|
26
+ subscribers << ActiveSupport::Notifications.subscribe(metered_method) do |_, started_at, finished_at, _, _|
27
+ data[key][metered_method] = [] unless data[key].has_key?(metered_method)
28
+ data[key][metered_method] << (finished_at - started_at)
52
29
  end
53
30
  end
54
31
 
55
32
  yield
56
33
 
57
- self.subscribers.each do |subscriber|
34
+ subscribers.each do |subscriber|
58
35
  ActiveSupport::Notifications.unsubscribe(subscriber)
59
36
  end
60
37
  end
61
38
 
62
39
  def measurement
63
- @measurement ||= begin
64
- self.data.collect do |key, measurement_records|
65
- _measurement = measurement_records.collect do |method_name, records|
66
- total_calls = records.size
67
- total_runtime = records.reduce(:+) * 1000
68
- average = total_runtime / total_calls
69
-
70
- {
71
- method: method_name,
72
- min: records.min * 1000,
73
- max: records.max * 1000,
74
- average: average,
75
- total_runtime: total_runtime,
76
- total_calls: total_calls,
77
- }
78
- end
40
+ measurement = {}
41
+
42
+ data.each do |key, measurement_records|
43
+ _measurement = measurement_records.collect do |method_name, records|
44
+ total_calls = records.size
45
+ total_runtime = records.reduce(:+) * 1000
46
+ average = total_runtime / total_calls
47
+
48
+ {
49
+ method: method_name,
50
+ min: records.min * 1000,
51
+ max: records.max * 1000,
52
+ average: average,
53
+ total_runtime: total_runtime,
54
+ total_calls: total_calls,
55
+ }
56
+ end
57
+
58
+ measurement[key] = _measurement
59
+ end
79
60
 
80
- { key => _measurement }
61
+ measurement
62
+ end
63
+
64
+ def profiling_method_names(method)
65
+ method_with_profiling = method.to_s + '_with_profiling'
66
+ method_without_profiling = method.to_s + '_without_profiling'
67
+ [method_with_profiling, method_without_profiling]
68
+ end
69
+
70
+ def meter_method?(method_name)
71
+ object_name, method = method_name.split('#')
72
+ object_name, method = method_name.split('.') if method.nil?
73
+ !exceptions.include?(method.to_sym) && !metered_methods.include?(method_name) && (method_name =~ /_profiling/).nil?
74
+ end
75
+
76
+ def define_metering_method(object, method, is_private, is_protected, is_singleton)
77
+ object.module_eval do
78
+ method_with_profiling, method_without_profiling = MethodMeter.profiling_method_names(method)
79
+ object_name = is_singleton ? object.to_s.split(':').last.gsub('>', '') : object.to_s
80
+ method_name = DefinedMethods.fqmn(object_name, method, is_singleton)
81
+
82
+ return unless MethodMeter.meter_method?(method_name)
83
+
84
+ MethodMeter.metered_methods << method_name
85
+
86
+ define_method(method_with_profiling) do |*args, &block|
87
+ ActiveSupport::Notifications.instrument(method_name, args) do
88
+ send(method_without_profiling, *args, &block)
89
+ end
81
90
  end
91
+
92
+ alias_method method_without_profiling, method
93
+ alias_method method, method_with_profiling
94
+
95
+ private method_with_profiling if is_private
96
+ protected method_with_profiling if is_protected
82
97
  end
83
98
  end
99
+
100
+ private
101
+
102
+ def init(excepted_methods)
103
+ self.metered_methods = [] if metered_methods.nil?
104
+ self.exceptions = [] if exceptions.nil?
105
+ self.exceptions |= excepted_methods
106
+ self.subscribers = []
107
+ self.data = {} if data.blank?
108
+ end
84
109
  end
85
110
  end
@@ -1,3 +1,3 @@
1
1
  module MethodMeter
2
- VERSION = '0.1.0'
2
+ VERSION = '0.4.3'
3
3
  end
data/method_meter.gemspec CHANGED
@@ -19,9 +19,12 @@ Gem::Specification.new do |spec|
19
19
 
20
20
  spec.require_paths = ['lib']
21
21
 
22
- spec.add_development_dependency 'bundler', '~> 1.16'
23
- spec.add_development_dependency 'rake', '~> 10.0'
24
- spec.add_development_dependency 'rspec', '~> 3.0'
22
+ spec.add_runtime_dependency 'activesupport'
23
+ spec.add_runtime_dependency 'awesome_print'
24
+ spec.add_runtime_dependency 'defined_methods'
25
25
 
26
- spec.add_development_dependency 'byebug', '~> 9.1.0' # can be put in Gemfile
26
+ spec.add_development_dependency 'bundler'
27
+ spec.add_development_dependency 'rake', '>= 12.3.3'
28
+ spec.add_development_dependency 'rspec', '~> 3.0'
29
+ spec.add_development_dependency 'pry'
27
30
  end
metadata CHANGED
@@ -1,43 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: method_meter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wilfrido T. Nuqui Jr.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-18 00:00:00.000000000 Z
11
+ date: 2021-02-14 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
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: awesome_print
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: defined_methods
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
13
55
  - !ruby/object:Gem::Dependency
14
56
  name: bundler
15
57
  requirement: !ruby/object:Gem::Requirement
16
58
  requirements:
17
- - - "~>"
59
+ - - ">="
18
60
  - !ruby/object:Gem::Version
19
- version: '1.16'
61
+ version: '0'
20
62
  type: :development
21
63
  prerelease: false
22
64
  version_requirements: !ruby/object:Gem::Requirement
23
65
  requirements:
24
- - - "~>"
66
+ - - ">="
25
67
  - !ruby/object:Gem::Version
26
- version: '1.16'
68
+ version: '0'
27
69
  - !ruby/object:Gem::Dependency
28
70
  name: rake
29
71
  requirement: !ruby/object:Gem::Requirement
30
72
  requirements:
31
- - - "~>"
73
+ - - ">="
32
74
  - !ruby/object:Gem::Version
33
- version: '10.0'
75
+ version: 12.3.3
34
76
  type: :development
35
77
  prerelease: false
36
78
  version_requirements: !ruby/object:Gem::Requirement
37
79
  requirements:
38
- - - "~>"
80
+ - - ">="
39
81
  - !ruby/object:Gem::Version
40
- version: '10.0'
82
+ version: 12.3.3
41
83
  - !ruby/object:Gem::Dependency
42
84
  name: rspec
43
85
  requirement: !ruby/object:Gem::Requirement
@@ -53,19 +95,19 @@ dependencies:
53
95
  - !ruby/object:Gem::Version
54
96
  version: '3.0'
55
97
  - !ruby/object:Gem::Dependency
56
- name: byebug
98
+ name: pry
57
99
  requirement: !ruby/object:Gem::Requirement
58
100
  requirements:
59
- - - "~>"
101
+ - - ">="
60
102
  - !ruby/object:Gem::Version
61
- version: 9.1.0
103
+ version: '0'
62
104
  type: :development
63
105
  prerelease: false
64
106
  version_requirements: !ruby/object:Gem::Requirement
65
107
  requirements:
66
- - - "~>"
108
+ - - ">="
67
109
  - !ruby/object:Gem::Version
68
- version: 9.1.0
110
+ version: '0'
69
111
  description: MethodMeter is a library module that instruments methods defined in a
70
112
  given object.
71
113
  email:
@@ -76,6 +118,8 @@ extra_rdoc_files: []
76
118
  files:
77
119
  - ".gitignore"
78
120
  - ".rspec"
121
+ - ".semaphore/semaphore.yml"
122
+ - 1-basic-rb.gif
79
123
  - CODE_OF_CONDUCT.md
80
124
  - Gemfile
81
125
  - LICENSE.txt
@@ -87,6 +131,7 @@ files:
87
131
  - examples/2-serial-measurement-using-keys.rb
88
132
  - examples/3-observe-multiple-times.rb
89
133
  - examples/4-more-measurement.rb
134
+ - examples/5-excepted-methods.rb
90
135
  - examples/helper.rb
91
136
  - examples/src/arithmeter.rb
92
137
  - examples/src/raiser.rb
@@ -112,8 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
157
  - !ruby/object:Gem::Version
113
158
  version: '0'
114
159
  requirements: []
115
- rubyforge_project:
116
- rubygems_version: 2.6.13
160
+ rubygems_version: 3.0.3
117
161
  signing_key:
118
162
  specification_version: 4
119
163
  summary: MethodMeter is a library module that instruments methods defined in a given