Module: MethodMeter

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

Constant Summary collapse

VERSION =
'0.4.0'

Class Method Summary collapse

Class Method Details

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



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

def define_instrumented_method(object, method, is_private, is_protected, is_singleton)
  object.module_eval do
    method_with_profiling, method_without_profiling = MethodMeter.profiling_method_names(method)
    event_name = DefinedMethods.fqmn(object.to_s, method, is_singleton)

    return unless MethodMeter.instrument_method?(method, event_name)

    MethodMeter.events << event_name

    define_method(method_with_profiling) do |*args, &block|
      ActiveSupport::Notifications.instrument(event_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

.instrument_method?(method, event_name) ⇒ Boolean

Returns:

  • (Boolean)


69
70
71
# File 'lib/method_meter.rb', line 69

def instrument_method?(method, event_name)
  !exceptions.include?(method) && !events.include?(event_name) && (event_name =~ /_profiling/).nil?
end

.measure!(key) ⇒ Object



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

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

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

  yield

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

.measurementObject



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

def measurement
  @measurement ||= begin
    data.collect 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

      { key => _measurement }
    end
  end
end

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



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

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_instrumented_method(group[:object], method, group[:private], group[:protected], group[:singleton])
      end
    end
  end
end

.profiling_method_names(method) ⇒ Object



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

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