Module: MethodMeter

Defined in:
lib/method_meter.rb,
lib/method_meter/version.rb

Constant Summary collapse

VERSION =
'0.4.3'

Class Method Summary collapse

Class Method Details

.define_metering_method(object, method, is_private, is_protected, is_singleton) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/method_meter.rb', line 76

def define_metering_method(object, method, is_private, is_protected, is_singleton)
  object.module_eval do
    method_with_profiling, method_without_profiling = MethodMeter.profiling_method_names(method)
    object_name = is_singleton ? object.to_s.split(':').last.gsub('>', '') : object.to_s
    method_name = DefinedMethods.fqmn(object_name, method, is_singleton)

    return unless MethodMeter.meter_method?(method_name)

    MethodMeter.metered_methods << method_name

    define_method(method_with_profiling) do |*args, &block|
      ActiveSupport::Notifications.instrument(method_name, args) do
        send(method_without_profiling, *args, &block)
      end
    end

    alias_method method_without_profiling, method
    alias_method method, method_with_profiling

    private method_with_profiling if is_private
    protected method_with_profiling if is_protected
  end
end

.measure!(key) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/method_meter.rb', line 22

def measure!(key)
  data[key] = {}

  metered_methods.each do |metered_method|
    subscribers << ActiveSupport::Notifications.subscribe(metered_method) do |_, started_at, finished_at, _, _|
      data[key][metered_method] = [] unless data[key].has_key?(metered_method)
      data[key][metered_method] << (finished_at - started_at)
    end
  end

  yield

  subscribers.each do |subscriber|
    ActiveSupport::Notifications.unsubscribe(subscriber)
  end
end

.measurementObject



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/method_meter.rb', line 39

def measurement
  measurement = {}

  data.each do |key, measurement_records|
    _measurement = measurement_records.collect do |method_name, records|
      total_calls   = records.size
      total_runtime = records.reduce(:+) * 1000
      average       = total_runtime / total_calls

      {
        method: method_name,
        min: records.min * 1000,
        max: records.max * 1000,
        average: average,
        total_runtime: total_runtime,
        total_calls: total_calls,
      }
    end

    measurement[key] = _measurement
  end

  measurement
end

.meter_method?(method_name) ⇒ Boolean

Returns:

  • (Boolean)


70
71
72
73
74
# File 'lib/method_meter.rb', line 70

def meter_method?(method_name)
  object_name, method = method_name.split('#')
  object_name, method = method_name.split('.') if method.nil?
  !exceptions.include?(method.to_sym) && !metered_methods.include?(method_name) && (method_name =~ /_profiling/).nil?
end

.observe(object, excepted_methods = []) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
# File 'lib/method_meter.rb', line 10

def observe(object, excepted_methods=[])
  init excepted_methods

  DefinedMethods.in(object).each do |group|
    group[:object].module_eval do
      group[:methods].each do |method|
        MethodMeter.define_metering_method(group[:object], method, group[:private], group[:protected], group[:singleton])
      end
    end
  end
end

.profiling_method_names(method) ⇒ Object



64
65
66
67
68
# File 'lib/method_meter.rb', line 64

def profiling_method_names(method)
  method_with_profiling     = method.to_s + '_with_profiling'
  method_without_profiling  = method.to_s + '_without_profiling'
  [method_with_profiling, method_without_profiling]
end