Class: ScoutApm::Instruments::ActionControllerRails3Rails4

Inherits:
Object
  • Object
show all
Defined in:
lib/scout_apm/instruments/action_controller_rails_3_rails4.rb

Overview

instrumentation for Rails 3 and Rails 4 is the same.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(context) ⇒ ActionControllerRails3Rails4

Returns a new instance of ActionControllerRails3Rails4.



7
8
9
10
# File 'lib/scout_apm/instruments/action_controller_rails_3_rails4.rb', line 7

def initialize(context)
  @context = context
  @installed = false
end

Instance Attribute Details

#contextObject (readonly)

Returns the value of attribute context.



5
6
7
# File 'lib/scout_apm/instruments/action_controller_rails_3_rails4.rb', line 5

def context
  @context
end

Class Method Details

.build_instrument_moduleObject



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/scout_apm/instruments/action_controller_rails_3_rails4.rb', line 58

def self.build_instrument_module
  Module.new do
    def process_action(*args)
      req = ScoutApm::RequestManager.lookup
      current_layer = req.current_layer
      agent_context = ScoutApm::Agent.instance.context

      # Check if this this request is to be reported instantly
      if instant_key = request.cookies['scoutapminstant']
        agent_context.logger.info "Instant trace request with key=#{instant_key} for path=#{path}"
        req.instant_key = instant_key
      end

      if current_layer && current_layer.type == "Controller"
        # Don't start a new layer if ActionController::API or ActionController::Base handled it already.
        super
      else
        req.annotate_request(:uri => ScoutApm::Instruments::ActionControllerRails3Rails4.scout_transaction_uri(request))

        # IP Spoofing Protection can throw an exception, just move on w/o remote ip
        if agent_context.config.value('collect_remote_ip')
          req.context.add_user(:ip => request.remote_ip) rescue nil
        end
        req.set_headers(request.headers)

        resolved_name = scout_action_name(*args)
        req.start_layer( ScoutApm::Layer.new("Controller", "#{controller_path}/#{resolved_name}") )
        begin
          super
        rescue
          req.error!
          raise
        ensure
          req.stop_layer
        end
      end
    end
  end
end

.scout_transaction_uri(request, config = ScoutApm::Agent.instance.context.config) ⇒ Object

Given an ActionDispatch::Request, formats the uri based on config settings. XXX: Don’t lookup context like this - find a way to pass it through



100
101
102
103
104
105
106
107
# File 'lib/scout_apm/instruments/action_controller_rails_3_rails4.rb', line 100

def self.scout_transaction_uri(request, config=ScoutApm::Agent.instance.context.config)
  case config.value("uri_reporting")
  when 'path'
    request.path # strips off the query string for more security
  else # default handles filtered params
    request.filtered_path
  end
end

Instance Method Details

#installObject



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/scout_apm/instruments/action_controller_rails_3_rails4.rb', line 20

def install
  # We previously instrumented ActionController::Metal, which missed
  # before and after filter timing. Instrumenting Base includes those
  # filters, at the expense of missing out on controllers that don't use
  # the full Rails stack.
  if defined?(::ActionController)
    @installed = true

    if defined?(::ActionController::Base)
      logger.info "Instrumenting ActionController::Base"
      ::ActionController::Base.class_eval do
        # include ScoutApm::Tracer
        include ScoutApm::Instruments::ActionControllerBaseInstruments
      end
    end

    if defined?(::ActionController::Metal)
      logger.info "Instrumenting ActionController::Metal"
      ::ActionController::Metal.class_eval do
        include ScoutApm::Instruments::ActionControllerMetalInstruments
      end
    end

    if defined?(::ActionController::API)
      logger.info "Instrumenting ActionController::Api"
      ::ActionController::API.class_eval do
        include ScoutApm::Instruments::ActionControllerAPIInstruments
      end
    end
  end

  # Returns a new anonymous module each time it is called. So
  # we can insert this multiple times into the ancestors
  # stack. Otherwise it only exists the first time you include it
  # (under Metal, instead of under API) and we miss instrumenting
  # before_action callbacks
end

#installed?Boolean

Returns:

  • (Boolean)


16
17
18
# File 'lib/scout_apm/instruments/action_controller_rails_3_rails4.rb', line 16

def installed?
  @installed
end

#loggerObject



12
13
14
# File 'lib/scout_apm/instruments/action_controller_rails_3_rails4.rb', line 12

def logger
  context.logger
end