class ScoutApm::Instruments::ActiveRecord

Attributes

context[R]

Public Class Methods

new(context) click to toggle source
# File lib/scout_apm/instruments/active_record.rb, line 40
def initialize(context)
  @context = context
  @installed = false
end

Public Instance Methods

add_instruments() click to toggle source
# File lib/scout_apm/instruments/active_record.rb, line 73
def add_instruments
  # Setup Tracer on AR::Base
  if Utils::KlassHelper.defined?("ActiveRecord::Base")
    @installed = true

    ::ActiveRecord::Base.class_eval do
      include ::ScoutApm::Tracer
    end
  end

  # Install #log tracing
  if Utils::KlassHelper.defined?("ActiveRecord::ConnectionAdapters::AbstractAdapter")
    ::ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend(ActiveRecordInstruments)
    ::ActiveRecord::ConnectionAdapters::AbstractAdapter.include(Tracer)
  end

  if Utils::KlassHelper.defined?("ActiveRecord::Base")
    ::ActiveRecord::Base.class_eval do
      include ::ScoutApm::Instruments::ActiveRecordUpdateInstruments
    end
  end

  # Disabled until we can determine how to use Module#prepend in the
  # agent. Otherwise, this will cause infinite loops if NewRelic is
  # installed. We can't just use normal Module#include, since the
  # original methods don't call super the way Base#save does
  #
  #if Utils::KlassHelper.defined?("ActiveRecord::Relation")
  #  ::ActiveRecord::Relation.class_eval do
  #    include ::ScoutApm::Instruments::ActiveRecordRelationInstruments
  #  end
  #end

  if Utils::KlassHelper.defined?("ActiveRecord::Querying")
    ::ActiveRecord::Querying.module_eval do
      include ::ScoutApm::Tracer
      include ::ScoutApm::Instruments::ActiveRecordQueryingInstruments
    end
  end

  rails_3_2_or_above = defined?(::ActiveRecord::VERSION::MAJOR) &&
    defined?(::ActiveRecord::VERSION::MINOR) &&
    (::ActiveRecord::VERSION::MAJOR.to_i > 3 ||
     (::ActiveRecord::VERSION::MAJOR.to_i == 3 && ::ActiveRecord::VERSION::MINOR.to_i >= 2))
  if rails_3_2_or_above
    if Utils::KlassHelper.defined?("ActiveRecord::Relation")
      if @context.environment.supports_module_prepend?
        ::ActiveRecord::Relation.module_eval do
          prepend ::ScoutApm::Instruments::ActiveRecordRelationQueryInstruments
        end
      else
        ::ActiveRecord::Relation.module_eval do
          include ::ScoutApm::Instruments::ActiveRecordRelationQueryInstruments
        end
      end
    end
  else
    if Utils::KlassHelper.defined?("ActiveRecord::FinderMethods")
      ::ActiveRecord::FinderMethods.module_eval do
        include ::ScoutApm::Tracer
        include ::ScoutApm::Instruments::ActiveRecordFinderMethodsInstruments
      end
    end
  end

  if Utils::KlassHelper.defined?("ActiveSupport::Notifications")
    ActiveSupport::Notifications.subscribe("instantiation.active_record") do |event_name, start, stop, uuid, payload|
      req = ScoutApm::RequestManager.lookup
      layer = req.current_layer
      if layer && layer.type == "ActiveRecord"
        layer.annotate_layer({
          :class_name => payload[:class_name],
          :record_count => payload[:record_count]
        })
      elsif layer
        logger.debug("Expected layer type: ActiveRecord, got #{layer && layer.type}")
      else
        # noop, no layer at all. We're probably ignoring this req.
      end
    end
  end
rescue
  logger.warn "ActiveRecord instrumentation exception: #{$!.message}"
end
install() click to toggle source
# File lib/scout_apm/instruments/active_record.rb, line 53
def install
  if install_via_after_initialize?
    Rails.configuration.after_initialize do
      add_instruments
    end
  else
    add_instruments
  end
end
install_via_after_initialize?() click to toggle source

If we have the right version of rails, we should use the hooks provided to install these instruments

# File lib/scout_apm/instruments/active_record.rb, line 65
def install_via_after_initialize?
  defined?(::Rails) &&
    defined?(::Rails::VERSION) &&
    defined?(::Rails::VERSION::MAJOR) &&
    ::Rails::VERSION::MAJOR.to_i == 3 &&
    ::Rails.respond_to?(:configuration)
end
installed?() click to toggle source
# File lib/scout_apm/instruments/active_record.rb, line 49
def installed?
  @installed
end
logger() click to toggle source
# File lib/scout_apm/instruments/active_record.rb, line 45
def logger
  context.logger
end