Module: NewRelic::Agent::Instrumentation::ActiveJobHelper

Includes:
MethodTracer
Defined in:
lib/new_relic/agent/instrumentation/active_job.rb

Constant Summary collapse

ADAPTER_REGEX =
/ActiveJob::QueueAdapters::(.*)Adapter/

Constants included from MethodTracer::ClassMethods::AddMethodTracer

MethodTracer::ClassMethods::AddMethodTracer::ALLOWED_KEYS, MethodTracer::ClassMethods::AddMethodTracer::DEFAULT_SETTINGS

Class Method Summary collapse

Methods included from MethodTracer

extended, included, trace_execution_scoped, trace_execution_unscoped

Methods included from MethodTracer::ClassMethods

add_method_tracer, #remove_method_tracer

Methods included from MethodTracer::ClassMethods::AddMethodTracer

#_nr_clear_traced_methods!, #_nr_default_metric_name, #_nr_derived_class_name, #_nr_traced_method_module, #_nr_validate_method_tracer_options, #method_traced?, #newrelic_method_exists?

Class Method Details

.adapterObject



116
117
118
119
120
121
122
123
124
# File 'lib/new_relic/agent/instrumentation/active_job.rb', line 116

def self.adapter
  adapter_class = if ::ActiveJob::Base.queue_adapter.class == Class
    ::ActiveJob::Base.queue_adapter
  else
    ::ActiveJob::Base.queue_adapter.class
  end

  clean_adapter_name(adapter_class.name)
end

.clean_adapter_name(name) ⇒ Object



128
129
130
131
# File 'lib/new_relic/agent/instrumentation/active_job.rb', line 128

def self.clean_adapter_name(name)
  name = "ActiveJob::#{$1}" if ADAPTER_REGEX =~ name
  name
end

.code_information_for_job(job) ⇒ Object



100
101
102
# File 'lib/new_relic/agent/instrumentation/active_job.rb', line 100

def self.code_information_for_job(job)
  NewRelic::Agent::MethodTracerHelpers.code_information(job.class, :perform)
end

.enqueue(job, block) ⇒ Object



50
51
52
# File 'lib/new_relic/agent/instrumentation/active_job.rb', line 50

def self.enqueue(job, block)
  run_in_trace(job, block, :Produce)
end

.perform(job, block) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/new_relic/agent/instrumentation/active_job.rb', line 54

def self.perform(job, block)
  state = ::NewRelic::Agent::Tracer.state
  txn = state.current_transaction

  # Don't nest transactions if we're already in a web transaction.
  # Probably inline processing the job if that happens, so just trace.
  if txn&.recording_web_transaction?
    run_in_trace(job, block, :Consume)
  elsif txn && !txn.recording_web_transaction?
    ::NewRelic::Agent::Transaction.set_default_transaction_name(
      transaction_name_suffix_for_job(job),
      transaction_category
    )
    block.call
  else
    run_in_transaction(job, block)
  end
end

.run_in_trace(job, block, event) ⇒ Object



73
74
75
76
77
78
79
# File 'lib/new_relic/agent/instrumentation/active_job.rb', line 73

def self.run_in_trace(job, block, event)
  trace_execution_scoped("ActiveJob/#{adapter.sub(/^ActiveJob::/, '')}/Queue/#{event}/Named/#{job.queue_name}/#{job.class}",
    code_information: code_information_for_job(job)) do
    ::NewRelic::Agent::Tracer.current_segment&.span_kind = span_kind_for_event(event)
    block.call
  end
end

.run_in_transaction(job, block) ⇒ Object



89
90
91
92
93
94
95
96
97
98
# File 'lib/new_relic/agent/instrumentation/active_job.rb', line 89

def self.run_in_transaction(job, block)
  options = code_information_for_job(job)
  options = {} if options.frozen? # the hash will be added to later
  ::NewRelic::Agent::Tracer.in_transaction(name: transaction_name_for_job(job),
    category: :other, options: options) do
    # this method is only called on perform actions, so the kind will always be consumer
    ::NewRelic::Agent::Tracer.current_segment&.span_kind = ::NewRelic::Agent::SpanEventPrimitive::CONSUMER
    block.call
  end
end

.span_kind_for_event(event) ⇒ Object



81
82
83
84
85
86
87
# File 'lib/new_relic/agent/instrumentation/active_job.rb', line 81

def self.span_kind_for_event(event)
  if event == :Produce
    ::NewRelic::Agent::SpanEventPrimitive::PRODUCER
  else
    ::NewRelic::Agent::SpanEventPrimitive::CONSUMER
  end
end

.transaction_categoryObject



104
105
106
# File 'lib/new_relic/agent/instrumentation/active_job.rb', line 104

def self.transaction_category
  "OtherTransaction/#{adapter}"
end

.transaction_name_for_job(job) ⇒ Object



112
113
114
# File 'lib/new_relic/agent/instrumentation/active_job.rb', line 112

def self.transaction_name_for_job(job)
  "#{transaction_category}/#{transaction_name_suffix_for_job(job)}"
end

.transaction_name_suffix_for_job(job) ⇒ Object



108
109
110
# File 'lib/new_relic/agent/instrumentation/active_job.rb', line 108

def self.transaction_name_suffix_for_job(job)
  "#{job.class}/execute"
end