Module: Nunes::Instrumentable

Defined in:
lib/nunes/instrumentable.rb

Constant Summary collapse

MethodTimeEventName =

Private

"instrument_method_time.nunes".freeze

Instance Method Summary collapse

Instance Method Details

#instrument_method_time(method_name, options_or_string = nil) ⇒ Object

Public: Instrument a method’s timing by name.

method_name - The String or Symbol name of the method. options_or_string - The Hash of options or the String metic name.

:payload - Any items you would like to include with the
           instrumentation payload.
:name - The String name of the event and namespace.


15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/nunes/instrumentable.rb', line 15

def instrument_method_time(method_name, options_or_string = nil)
  options = options_or_string || {}
  options = {name: options} if options.is_a?(String)

  action = :time
  payload = options.fetch(:payload) { {} }
  instrumenter = options.fetch(:instrumenter) { ActiveSupport::Notifications }

  payload[:metric] = options.fetch(:name) {
    if name.nil?
      raise ArgumentError, "For class methods you must provide the full name of the metric."
    else
      "#{::Nunes.class_to_metric(name)}.#{method_name}"
    end
  }

  nunes_wrap_method(method_name, action) do |old_method_name, new_method_name|
    define_method(new_method_name) do |*args, &block|
      instrumenter.instrument(MethodTimeEventName, payload) {
        send(old_method_name, *args, &block)
      }
    end
  end
end

#nunes_wrap_method(method_name, action) {|method_without_instrumentation, method_with_instrumentation| ... } ⇒ Object

Private: And so horrendously ugly…

Yields:

  • (method_without_instrumentation, method_with_instrumentation)


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/nunes/instrumentable.rb', line 41

def nunes_wrap_method(method_name, action, &block)
  method_without_instrumentation = :"#{method_name}_without_#{action}"
  method_with_instrumentation = :"#{method_name}_with_#{action}"

  if method_defined?(method_without_instrumentation)
    raise ArgumentError, "already instrumented #{method_name} for #{self.name}"
  end

  if !method_defined?(method_name) && !private_method_defined?(method_name)
    raise ArgumentError, "could not find method #{method_name} for #{self.name}"
  end

  alias_method method_without_instrumentation, method_name
  yield method_without_instrumentation, method_with_instrumentation
  alias_method method_name, method_with_instrumentation
end