Class: NewRelic::Agent::Instrumentation::ActionControllerSubscriber

Inherits:
NotificationsSubscriber show all
Defined in:
lib/new_relic/agent/instrumentation/action_controller_subscriber.rb

Instance Method Summary collapse

Methods inherited from NotificationsSubscriber

#add_segment_params, #define_exception_method, find_all_subscribers, #finish_segment, #initialize, #log_notification_error, #metric_name, #pop_segment, #push_segment, #segment_stack, #start_segment, #state, subscribe, subscribed?

Constructor Details

This class inherits a constructor from NewRelic::Agent::Instrumentation::NotificationsSubscriber

Instance Method Details

#controller_class(payload) ⇒ Object



80
81
82
# File 'lib/new_relic/agent/instrumentation/action_controller_subscriber.rb', line 80

def controller_class(payload)
  ::NewRelic::LanguageSupport.constantize(payload[:controller])
end

#filtered_params(params) ⇒ Object



67
68
69
# File 'lib/new_relic/agent/instrumentation/action_controller_subscriber.rb', line 67

def filtered_params(params)
  NewRelic::Agent::ParameterFiltering.filter_using_rails(params, Rails.application.config.filter_parameters)
end

#finish(name, id, payload) ⇒ Object

THREAD_LOCAL_ACCESS



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/new_relic/agent/instrumentation/action_controller_subscriber.rb', line 29

def finish(name, id, payload) # THREAD_LOCAL_ACCESS
  finishable = pop_segment(id)

  if state.is_execution_traced? \
      && !should_ignore(payload, controller_class(payload))

    if exception = exception_object(payload)
      finishable.notice_error(exception)
    end

    finishable.finish
  else
    Agent.instance.pop_trace_execution_flag
  end
rescue => e
  log_notification_error(e, name, 'finish')
end

#format_metric_name(metric_action, controller) ⇒ Object



75
76
77
78
# File 'lib/new_relic/agent/instrumentation/action_controller_subscriber.rb', line 75

def format_metric_name(metric_action, controller)
  controller_class = controller.is_a?(Class) ? controller : Object.const_get(controller)
  "Controller/#{controller_class.controller_path}/#{metric_action}"
end

#ignore?(action, key, controller_class) ⇒ Boolean

Returns:

  • (Boolean)


71
72
73
# File 'lib/new_relic/agent/instrumentation/action_controller_subscriber.rb', line 71

def ignore?(action, key, controller_class)
  NewRelic::Agent::Instrumentation::IgnoreActions.is_filtered?(key, controller_class, action)
end

#queue_start(request) ⇒ Object



92
93
94
95
96
97
# File 'lib/new_relic/agent/instrumentation/action_controller_subscriber.rb', line 92

def queue_start(request)
  # the following line needs else branch coverage
  if request && request.respond_to?(:env) # rubocop:disable Style/SafeNavigation
    QueueTime.parse_frontend_timestamp(request.env, Process.clock_gettime(Process::CLOCK_REALTIME))
  end
end

#request_for_payload(payload) ⇒ Object



99
100
101
102
103
104
# File 'lib/new_relic/agent/instrumentation/action_controller_subscriber.rb', line 99

def request_for_payload(payload)
  # @req is a historically stable but not guaranteed Rails header property
  return unless payload[:headers].instance_variables.include?(:@req)

  payload[:headers].instance_variable_get(:@req)
end

#should_ignore(payload, controller_class) ⇒ Object



84
85
86
87
88
89
90
# File 'lib/new_relic/agent/instrumentation/action_controller_subscriber.rb', line 84

def should_ignore(payload, controller_class)
  NewRelic::Agent::Instrumentation::IgnoreActions.is_filtered?(
    ControllerInstrumentation::NR_DO_NOT_TRACE_KEY,
    controller_class,
    payload[:action]
  )
end

#start(name, id, payload) ⇒ Object

THREAD_LOCAL_ACCESS



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/new_relic/agent/instrumentation/action_controller_subscriber.rb', line 13

def start(name, id, payload) # THREAD_LOCAL_ACCESS
  controller_class = controller_class(payload)

  if state.is_execution_traced? && !should_ignore(payload, controller_class)
    finishable = start_transaction_or_segment(payload, request_for_payload(payload), controller_class)
    push_segment(id, finishable)
  else
    # if this transaction is ignored, make sure child
    # transaction are also ignored
    state.current_transaction&.ignore!
    NewRelic::Agent.instance.push_trace_execution_flag(false)
  end
rescue => e
  log_notification_error(e, name, 'start')
end

#start_transaction_or_segment(payload, request, controller_class) ⇒ Object



47
48
49
50
51
52
53
# File 'lib/new_relic/agent/instrumentation/action_controller_subscriber.rb', line 47

def start_transaction_or_segment(payload, request, controller_class)
  Tracer.start_transaction_or_segment(
    name: format_metric_name(payload[:action], controller_class),
    category: :controller,
    options: tracer_options(payload, request, controller_class)
  )
end

#tracer_options(payload, request, controller_class) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
# File 'lib/new_relic/agent/instrumentation/action_controller_subscriber.rb', line 55

def tracer_options(payload, request, controller_class)
  {
    request: request,
    filtered_params: filtered_params(payload[:params]),
    apdex_start_time: queue_start(request),
    ignore_apdex: ignore?(payload[:action], ControllerInstrumentation::NR_IGNORE_APDEX_KEY, controller_class),
    ignore_enduser: ignore?(payload[:action],
      ControllerInstrumentation::NR_IGNORE_ENDUSER_KEY,
      controller_class)
  }.merge(NewRelic::Agent::MethodTracerHelpers.code_information(controller_class, payload[:action]))
end