vendor/plugins/newrelic_rpm/lib/newrelic/agent/method_tracer.rb
# Add a method tracer to the specified method.  
# metric_name_code is ruby code that determines the name of the
# metric to be collected during tracing.  As such, the code
# should be provided in 'single quote' strings rather than
# "double quote" strings, so that #{} evaluation happens
# at traced method execution time.
# Example: tracing a method :foo, where the metric name is
# the first argument converted to a string
#     add_method_tracer :foo, '#{args.first.to_s}'
# statically defined metric names can be specified as regular strings
# push_scope specifies whether this method tracer should push
# the metric name onto the scope stack.
Add a method tracer to the specified method.
metric_name_code is ruby code that determines the name of the
metric to be collected during tracing.  As such, the code
should be provided in 'single quote' strings rather than
"double quote" strings, so that #{} evaluation happens
at traced method execution time.
Example: tracing a method :foo, where the metric name is
the first argument converted to a string
add_method_tracer :foo, '#{args.first.to_s}'
statically defined metric names can be specified as regular strings
push_scope specifies whether this method tracer should push
the metric name onto the scope stack.
Add a method tracer to the specified method . metric_name_code is ruby code that determines the name of the metric to be collected during tracing . As such the code should be provided in ' single quote ' strings rather than " double quote " strings so that # {} evaluation happens at traced method execution time . Example : tracing a method : foo where the metric name is the first argument converted to a string add_method_tracer : foo ' # { args . first . to_s } ' statically defined metric names can be specified as regular strings push_scope specifies whether this method tracer should push the metric name onto the scope stack .
def add_method_tracer (method_name, metric_name_code, options = {})
    return unless ::RPM_TRACERS_ENABLED
    if !options.is_a?(Hash)
      options = {:push_scope => options} 
    end
    options[:push_scope] = true if options[:push_scope].nil?
    options[:metric] = true if options[:metric].nil?
    options[:deduct_call_time_from_parent] = false if options[:deduct_call_time_from_parent].nil? && !options[:metric]
    options[:deduct_call_time_from_parent] = true if options[:deduct_call_time_from_parent].nil?
    options[:code_header] ||= ""
    options[:code_footer] ||= ""
    klass = (self === Module) ? "self" : "self.class"
    unless method_defined?(method_name) || private_method_defined?(method_name)
      method_tracer_log.warn("Did not trace #{self}##{method_name} because that method does not exist")
      return
    end
    traced_method_name = _traced_method_name(method_name, metric_name_code)
    if method_defined? traced_method_name
      method_tracer_log.warn("Attempt to trace a method twice with the same metric: Method = #{method_name}, Metric Name = #{metric_name_code}")
      return
    end
    code = <<-CODE
    def #{_traced_method_name(method_name, metric_name_code)}(*args, &block)
      #{options[:code_header]}
      metric_name = "#{metric_name_code}"
      traced_method_result = #{klass}.trace_method_execution("\#{metric_name}", #{options[:push_scope]}, #{options[:metric]}, #{options[:deduct_call_time_from_parent]}) do
        #{_untraced_method_name(method_name, metric_name_code)}(*args, &block)
      end
      #{options[:code_footer]}
      traced_method_result
    end
    CODE
    class_eval code, __FILE__, __LINE__
    alias_method _untraced_method_name(method_name, metric_name_code), method_name
    alias_method method_name, "#{_traced_method_name(method_name, metric_name_code)}"
    method_tracer_log.debug("Traced method: class = #{self}, method = #{method_name}, "+
        "metric = '#{metric_name_code}', options: #{options}, ")
  end
def add_method_tracer ( method_name , metric_name_code , options = { } ) return unless :: RPM_TRACERS_ENABLED if ! options . is_a? ( Hash ) options = { :push_scope => options } end options [ :push_scope ] = true if options [ :push_scope ] . nil? options [ :metric ] = true if options [ :metric ] . nil? options [ :deduct_call_time_from_parent ] = false if options [ :deduct_call_time_from_parent ] . nil? && ! options [ :metric ] options [ :deduct_call_time_from_parent ] = true if options [ :deduct_call_time_from_parent ] . nil? options [ :code_header ] ||= "" options [ :code_footer ] ||= "" klass = ( self === Module ) ? "self" : "self.class" unless method_defined? ( method_name ) || private_method_defined? ( method_name ) method_tracer_log . warn ( "Did not trace #{self}##{method_name} because that method does not exist" ) return end traced_method_name = _traced_method_name ( method_name , metric_name_code ) if method_defined? traced_method_name method_tracer_log . warn ( "Attempt to trace a method twice with the same metric: Method = #{method_name}, Metric Name = #{metric_name_code}" ) return end code = <<-CODE 
    def  #{ _traced_method_name ( method_name , metric_name_code ) } (*args, &block)
       #{ options [ :code_header ] } 
      metric_name = " #{ metric_name_code } "
      traced_method_result =  #{ klass } .trace_method_execution(" \# {metric_name}",  #{ options [ :push_scope ] } ,  #{ options [ :metric ] } ,  #{ options [ :deduct_call_time_from_parent ] } ) do
         #{ _untraced_method_name ( method_name , metric_name_code ) } (*args, &block)
      end
       #{ options [ :code_footer ] } 
      traced_method_result
    end
     CODE class_eval code , __FILE__ , __LINE__ alias_method _untraced_method_name ( method_name , metric_name_code ) , method_name alias_method method_name , "#{_traced_method_name(method_name, metric_name_code)}" method_tracer_log . debug ( "Traced method: class = #{self}, method = #{method_name}, " + "metric = '#{metric_name_code}', options: #{options}, " ) end
Add a method tracer to the specified method.
Add a method tracer to the specified method .
method_name
<not_specific>
metric_name_code
<not_specific>
options
<not_specific>