module ScoutApm::Tracer::ClassMethods
Public Instance Methods
Source
# File lib/scout_apm/tracer.rb, line 43 def instrument(type, name, options={}, &block) ScoutApm::Tracer.instrument(type, name, options, &block) end
Source
# File lib/scout_apm/tracer.rb, line 52 def instrument_method(method_name, options = {}) ScoutApm::Agent.instance.context.logger.info "Instrumenting #{method_name}" type = options[:type] || "Custom" name = options[:name] || "#{self.name}/#{method_name.to_s}" instrumented_name, uninstrumented_name = _determine_instrumented_name(method_name, type) ScoutApm::Agent.instance.context.logger.info "Instrumenting #{instrumented_name}, #{uninstrumented_name}" return if !_instrumentable?(method_name) or _instrumented?(instrumented_name, method_name) class_eval( _instrumented_method_string(instrumented_name, uninstrumented_name, type, name, {:scope => options[:scope] }), __FILE__, __LINE__ ) alias_method uninstrumented_name, method_name alias_method method_name, instrumented_name end
Wraps a method in a call to instrument
via aggressive monkey patching.
Options: type - “View” or “ActiveRecord” and similar name - “users/show”, “App#find”
Private Instance Methods
Source
# File lib/scout_apm/tracer.rb, line 74 def _determine_instrumented_name(method_name, type) inst = _find_unused_method_name { _instrumented_method_name(method_name, type) } uninst = _find_unused_method_name { _uninstrumented_method_name(method_name, type) } return inst, uninst end
Source
# File lib/scout_apm/tracer.rb, line 81 def _find_unused_method_name raw_name = name = yield i = 0 while method_defined?(name) && i < 100 i += 1 name = "#{raw_name}_#{i}" end name end
Source
# File lib/scout_apm/tracer.rb, line 115 def _instrumentable?(method_name) exists = method_defined?(method_name) || private_method_defined?(method_name) ScoutApm::Agent.instance.context.logger.warn "The method [#{self.name}##{method_name}] does not exist and will not be instrumented" unless exists exists end
The method must exist to be instrumented.
Source
# File lib/scout_apm/tracer.rb, line 122 def _instrumented?(instrumented_name, method_name) instrumented = method_defined?(instrumented_name) ScoutApm::Agent.instance.context.logger.warn("The method [#{self.name}##{method_name}] has already been instrumented") if instrumented instrumented end
True
if the method is already instrumented.
Source
# File lib/scout_apm/tracer.rb, line 136 def _instrumented_method_name(method_name, type) "#{_sanitize_name(method_name)}_with_scout_instrument" end
given a method and a metric, this method returns the traced alias of the method name
Source
# File lib/scout_apm/tracer.rb, line 92 def _instrumented_method_string(instrumented_name, uninstrumented_name, type, name, options={}) method_str = <<-EOF def #{instrumented_name}(*args#{", **kwargs" if ScoutApm::Agent.instance.context.environment.supports_kwarg_delegation?}, &block) name = begin "#{name}" rescue => e ScoutApm::Agent.instance.context.logger.error("Error raised while interpreting instrumented name: %s, %s" % ['#{name}', e.message]) "Unknown" end ::ScoutApm::Tracer.instrument( "#{type}", name, {:scope => #{options[:scope] || false}} ) do #{uninstrumented_name}(*args#{", **kwargs" if ScoutApm::Agent.instance.context.environment.supports_kwarg_delegation?}, &block) end end EOF method_str end
Source
# File lib/scout_apm/tracer.rb, line 142 def _sanitize_name(name) name.to_s.tr_s('^a-zA-Z0-9', '_') end
Method names like any?
or replace!
contain a trailing character that would break when eval’d as ? and ! aren’t allowed inside method names.
Source
# File lib/scout_apm/tracer.rb, line 130 def _uninstrumented_method_name(method_name, type) "#{_sanitize_name(method_name)}_without_scout_instrument" end
given a method and a metric, this method returns the untraced alias of the method name