Class: NewRelic::Agent::Instrumentation::ActionViewSubscriber

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

Constant Summary collapse

RENDER_TEMPLATE_EVENT_NAME =
'render_template.action_view'.freeze
RENDER_PARTIAL_EVENT_NAME =
'render_partial.action_view'.freeze
RENDER_COLLECTION_EVENT_NAME =
'render_collection.action_view'.freeze
RENDER_LAYOUT_EVENT_NAME =
'render_layout.action_view'.freeze

Instance Method Summary collapse

Methods inherited from NotificationsSubscriber

#add_segment_params, #define_exception_method, find_all_subscribers, #finish, #initialize, #log_notification_error, #metric_name, #pop_segment, #push_segment, #segment_stack, #start, #state, subscribe, subscribed?

Constructor Details

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

Instance Method Details

#finish_segment(id, payload) ⇒ Object



25
26
27
28
29
30
31
32
# File 'lib/new_relic/agent/instrumentation/action_view_subscriber.rb', line 25

def finish_segment(id, payload)
  if segment = pop_segment(id)
    if exception = exception_object(payload)
      segment.notice_error(exception)
    end
    segment.finish
  end
end

#format_metric_name(event_name, payload, parent) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/new_relic/agent/instrumentation/action_view_subscriber.rb', line 34

def format_metric_name(event_name, payload, parent)
  return parent.name if parent \
     && (payload[:virtual_path] \
      || (parent.identifier =~ /template$/))

  if payload.key?(:virtual_path)
    identifier = payload[:virtual_path]
  else
    identifier = payload[:identifier]
  end

  "View/#{metric_path(event_name, identifier)}/#{metric_action(event_name)}"
end

#metric_action(name) ⇒ Object



63
64
65
66
67
68
69
70
71
# File 'lib/new_relic/agent/instrumentation/action_view_subscriber.rb', line 63

def metric_action(name)
  case name
  when /#{RENDER_TEMPLATE_EVENT_NAME}$/o then 'Rendering'
  when RENDER_PARTIAL_EVENT_NAME then 'Partial'
  when RENDER_COLLECTION_EVENT_NAME then 'Partial'
  when RENDER_LAYOUT_EVENT_NAME then 'Layout'
  else NewRelic::UNKNOWN
  end
end

#metric_path(name, identifier) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/new_relic/agent/instrumentation/action_view_subscriber.rb', line 73

def metric_path(name, identifier)
  # Rails 5 sets identifier to nil for empty collections,
  # so do not mistake rendering a collection for rendering a file.
  if identifier.nil? && name != RENDER_COLLECTION_EVENT_NAME
    'file'
  elsif /template$/.match?(identifier)
    identifier
  elsif identifier && (parts = identifier.split('/')).size > 1
    parts[-2..-1].join('/')
  else
    ::NewRelic::Agent::UNKNOWN_METRIC
  end
end

#recordable?(event_name, metric_name) ⇒ Boolean

Nearly every “render_blah.action_view” event has a child in the form of “!render_blah.action_view”. The children are the ones we want to record. There are a couple special cases of events without children.

Returns:

  • (Boolean)


52
53
54
55
56
# File 'lib/new_relic/agent/instrumentation/action_view_subscriber.rb', line 52

def recordable?(event_name, metric_name)
  event_name[0] == '!' \
      || metric_name == 'View/text template/Rendering' \
      || metric_name == "View/#{::NewRelic::Agent::UNKNOWN_METRIC}/Partial"
end

#start_segment(name, id, payload) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
# File 'lib/new_relic/agent/instrumentation/action_view_subscriber.rb', line 13

def start_segment(name, id, payload)
  parent = segment_stack[id].last
  metric_name = format_metric_name(name, payload, parent)

  event = ActionViewEvent.new(metric_name, payload[:identifier])

  if recordable?(name, metric_name)
    event.finishable = Tracer.start_segment(name: metric_name)
  end
  push_segment(id, event)
end