Module: NewRelic::Agent::Instrumentation::Rake

Defined in:
lib/new_relic/agent/instrumentation/rake/chain.rb,
lib/new_relic/agent/instrumentation/rake/prepend.rb,
lib/new_relic/agent/instrumentation/rake/instrumentation.rb
more...

Defined Under Namespace

Modules: Chain, Prepend, Tracer

Class Method Summary collapse

Class Method Details

.before_invoke_transaction(task) ⇒ Object

[View source]

86
87
88
89
90
91
92
93
94
95
# File 'lib/new_relic/agent/instrumentation/rake/instrumentation.rb', line 86

def before_invoke_transaction(task)
  ensure_at_exit

  instrument_execute_on_prereqs(task)
  if task.application.options.always_multitask
    instrument_invoke_prerequisites_concurrently(task)
  end
rescue => e
  NewRelic::Agent.logger.error('Error during Rake task invoke', e)
end

.ensure_at_exitObject

[View source]

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/new_relic/agent/instrumentation/rake/instrumentation.rb', line 127

def ensure_at_exit
  return if @installed_at_exit

  at_exit do
    # The agent's default at_exit might not default to installing, but
    # if we are running an instrumented rake task, we always want it.
    # No code coverage, as the strategy for mocking Kernel.exit prevents
    # the at_exit block from being executed, and not mocking results in
    # an early unwanted exit of MiniTest.
    # :nocov:
    NewRelic::Agent.shutdown
    # :nocov:
  end

  @installed_at_exit = true
end

.instrument_execute(task) ⇒ Object

[View source]

61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/new_relic/agent/instrumentation/rake/instrumentation.rb', line 61

def instrument_execute(task)
  return if task.instance_variable_get(:@__newrelic_instrumented_execute)

  task.instance_variable_set(:@__newrelic_instrumented_execute, true)
  task.instance_eval do
    def execute(*args, &block)
      NewRelic::Agent::MethodTracer.trace_execution_scoped("Rake/execute/#{self.name}") do
        super
      end
    end
  end

  instrument_execute_on_prereqs(task)
end

.instrument_execute_on_prereqs(task) ⇒ Object

[View source]

55
56
57
58
59
# File 'lib/new_relic/agent/instrumentation/rake/instrumentation.rb', line 55

def instrument_execute_on_prereqs(task)
  task.prerequisite_tasks.each do |child_task|
    instrument_execute(child_task)
  end
end

.instrument_invoke_prerequisites_concurrently(task) ⇒ Object

[View source]

76
77
78
79
80
81
82
83
84
# File 'lib/new_relic/agent/instrumentation/rake/instrumentation.rb', line 76

def instrument_invoke_prerequisites_concurrently(task)
  task.instance_eval do
    def invoke_prerequisites_concurrently(*_)
      NewRelic::Agent::MethodTracer.trace_execution_scoped('Rake/execute/multitask') do
        super
      end
    end
  end
end

.name_the_args(args, names) ⇒ Object

Expects literal args passed to the task and array of task names If names are present without matching args, still sets them with nils

[View source]

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

def name_the_args(args, names)
  unfulfilled_names_length = names.length - args.length
  if unfulfilled_names_length > 0
    args.concat(Array.new(unfulfilled_names_length))
  end

  result = {}
  args.zip(names).each_with_index do |(value, key), index|
    result[key || index.to_s] = value
  end
  result
end

.record_attributes(args, task) ⇒ Object

[View source]

97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/new_relic/agent/instrumentation/rake/instrumentation.rb', line 97

def record_attributes(args, task)
  command_line = task.application.top_level_tasks.join(' ')
  NewRelic::Agent::Transaction.merge_untrusted_agent_attributes({:command => command_line},
    :'job.rake',
    NewRelic::Agent::AttributeFilter::DST_NONE)
  named_args = name_the_args(args, task.arg_names)
  unless named_args.empty?
    NewRelic::Agent::Transaction.merge_untrusted_agent_attributes(named_args,
      :'job.rake.args',
      NewRelic::Agent::AttributeFilter::DST_NONE)
  end
rescue => e
  NewRelic::Agent.logger.error('Error during Rake task attribute recording.', e)
end

.safe_from_third_party_gem?Boolean

Returns:

  • (Boolean)
[View source]

42
43
44
45
46
47
# File 'lib/new_relic/agent/instrumentation/rake/instrumentation.rb', line 42

def safe_from_third_party_gem?
  return true unless NewRelic::LanguageSupport.bundled_gem?('newrelic-rake')

  ::NewRelic::Agent.logger.info('Not installing New Relic supported Rake instrumentation because the third party newrelic-rake gem is present')
  false
end

.should_install?Boolean

Returns:

  • (Boolean)
[View source]

38
39
40
# File 'lib/new_relic/agent/instrumentation/rake/instrumentation.rb', line 38

def should_install?
  safe_from_third_party_gem?
end

.should_trace?(name) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

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

def should_trace?(name)
  NewRelic::Agent.config[:'rake.tasks'].any? do |regex|
    regex.match(name)
  end
end