module NewRelic::Agent::DataMapperTracing

Constants

AMPERSAND
DATA_MAPPER
PASSWORD_PARAM
PASSWORD_REGEX

Public Class Methods

add_tracer(clazz, method_name, operation_only = false) click to toggle source
# File lib/new_relic/agent/instrumentation/data_mapper.rb, line 98
def self.add_tracer(clazz, method_name, operation_only = false)
  clazz.class_eval do
    if method_defined?(method_name) || private_method_defined?(method_name)
      define_method("#{method_name}_with_newrelic",
                    NewRelic::Agent::DataMapperTracing.method_body(clazz, method_name, operation_only))

      alias_method "#{method_name}_without_newrelic", method_name
      alias_method method_name, "#{method_name}_with_newrelic"
    end
  end
end
method_body(clazz, method_name, operation_only) click to toggle source
# File lib/new_relic/agent/instrumentation/data_mapper.rb, line 115
def self.method_body(clazz, method_name, operation_only)
  use_model_name   = NewRelic::Helper.instance_methods_include?(clazz, :model)
  metric_operation = method_name.to_s.gsub(/[!?]/, "")

  Proc.new do |*args, &blk|
    begin
      if operation_only
        # Used by direct SQL, like ::DataMapper::Adapters::DataObjectsAdapter#select
        name = nil
      elsif use_model_name
        # Used by ::DataMapper::Collection to get contained model name
        name = self.model.name
      elsif self.is_a?(Class)
        # Used by class-style access, like Model.first()
        name = self.name
      else
        # Used by instance-style access, like model.update(attr: "new")
        name = self.class.name
      end

      metrics = NewRelic::Agent::Datastores::MetricHelper.metrics_for(
        DATA_MAPPER,
        metric_operation,
        name)

      NewRelic::Agent::MethodTracer.trace_execution_scoped(metrics) do
        begin
          self.send("#{method_name}_without_newrelic", *args, &blk)
        rescue ::DataObjects::SQLError => e
          e.uri.gsub!(PASSWORD_REGEX, AMPERSAND) if e.uri.include?(PASSWORD_PARAM)

          strategy = NewRelic::Agent::Database.record_sql_method(:slow_sql)
          case strategy
          when :obfuscated
            statement = NewRelic::Agent::Database::Statement.new(e.query, :adapter => self.options[:adapter])
            obfuscated_sql = NewRelic::Agent::Database.obfuscate_sql(statement)
            e.instance_variable_set(:@query, obfuscated_sql)
          when :off
            e.instance_variable_set(:@query, nil)
          end

          raise
        end
      end
    end
  end
end