Module: NewRelic::Agent::MethodTracerHelpers

Extended by:
MethodTracerHelpers
Included in:
MethodTracerHelpers
Defined in:
lib/new_relic/agent/method_tracer_helpers.rb

Constant Summary collapse

SOURCE_CODE_INFORMATION_PARAMETERS =

These are code level metrics (CLM) attributes. For Ruby, they map like so:

filepath: full path to an .rb file on disk
lineno: the line number a Ruby method is defined on within a given .rb file
function: the name of the Ruby method
namespace: the Ruby class' namespace as a string, ex: 'MyModule::MyClass'
%i[filepath lineno function namespace].freeze
SOURCE_CODE_INFORMATION_FAILURE_METRIC =
'Supportability/CodeLevelMetrics/Ruby/Failure'.freeze
MAX_ALLOWED_METRIC_DURATION =

roughly 31 years

1_000_000_000

Instance Method Summary collapse

Instance Method Details

#code_information(object, method_name) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/new_relic/agent/method_tracer_helpers.rb', line 42

def code_information(object, method_name)
  return ::NewRelic::EMPTY_HASH unless clm_enabled? && object && method_name

  @code_information ||= {}
  cache_key = "#{object.object_id}#{method_name}".freeze
  return @code_information[cache_key] if @code_information.key?(cache_key)

  info = namespace_and_location(object, method_name.to_sym)
  return ::NewRelic::EMPTY_HASH if info.empty?

  namespace, location, is_class_method = info
  @code_information[cache_key] = {filepath: location.first,
                                  lineno: location.last,
                                  function: "#{'self.' if is_class_method}#{method_name}",
                                  namespace: namespace}.freeze
rescue StandardError => e
  ::NewRelic::Agent.logger.warn("Unable to determine source code info for '#{object}', " \
                                  "method '#{method_name}' - #{e.class}: #{e.message}")
  ::NewRelic::Agent.increment_metric(SOURCE_CODE_INFORMATION_FAILURE_METRIC, 1)
  ::NewRelic::EMPTY_HASH
end

#trace_execution_scoped(metric_names, options = NewRelic::EMPTY_HASH) ⇒ Object

THREAD_LOCAL_ACCESS



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/new_relic/agent/method_tracer_helpers.rb', line 19

def trace_execution_scoped(metric_names, options = NewRelic::EMPTY_HASH) # THREAD_LOCAL_ACCESS
  return yield unless NewRelic::Agent::Tracer.state.is_execution_traced?

  metric_names = Array(metric_names)
  first_name = metric_names.shift
  return yield unless first_name

  segment = NewRelic::Agent::Tracer.start_segment(
    name: first_name,
    unscoped_metrics: metric_names
  )

  segment.record_metrics = false if options[:metric] == false

  unless !options.key?(:code_information) || options[:code_information].nil? || options[:code_information].empty?
    segment.code_information = options[:code_information]
  end

  Tracer.capture_segment_error(segment) { yield }
ensure
  ::NewRelic::Agent::Transaction::Segment.finish(segment)
end