module NewRelic::Agent::Instrumentation::RakeInstrumentation

Public Class Methods

before_invoke_transaction(task) click to toggle source
# File lib/new_relic/agent/instrumentation/rake.rb, line 111
def self.before_invoke_transaction(task)
  ensure_at_exit

  # We can't represent overlapping operations yet, so if multitask just
  # make one node and annotate with prereq task names
  if task.application.options.always_multitask
    instrument_invoke_prerequisites_concurrently(task)
  else
    instrument_execute_on_prereqs(task)
  end
rescue => e
  NewRelic::Agent.logger.error("Error during Rake task invoke", e)
end
ensure_at_exit() click to toggle source
# File lib/new_relic/agent/instrumentation/rake.rb, line 155
def self.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.
    NewRelic::Agent.shutdown
  end

  @installed_at_exit = true
end
instrument_execute(task) click to toggle source
# File lib/new_relic/agent/instrumentation/rake.rb, line 84
def self.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) click to toggle source
# File lib/new_relic/agent/instrumentation/rake.rb, line 78
def self.instrument_execute_on_prereqs(task)
  task.prerequisite_tasks.each do |child_task|
    instrument_execute(child_task)
  end
end
instrument_invoke_prerequisites_concurrently(task) click to toggle source
# File lib/new_relic/agent/instrumentation/rake.rb, line 99
def self.instrument_invoke_prerequisites_concurrently(task)
  task.instance_eval do
    def invoke_prerequisites_concurrently(*_)
      NewRelic::Agent::MethodTracer.trace_execution_scoped("Rake/execute/multitask") do
        prereqs = self.prerequisite_tasks.map(&:name).join(", ")
        NewRelic::Agent::Datastores.notice_statement("Couldn't trace concurrent prereq tasks: #{prereqs}", 0)
        super
      end
    end
  end
end
is_supported_version?() click to toggle source
# File lib/new_relic/agent/instrumentation/rake.rb, line 59
def self.is_supported_version?
  ::NewRelic::VersionNumber.new(::Rake::VERSION) >= ::NewRelic::VersionNumber.new("10.0.0")
end
name_the_args(args, names) click to toggle source

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

# File lib/new_relic/agent/instrumentation/rake.rb, line 142
def self.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) click to toggle source
# File lib/new_relic/agent/instrumentation/rake.rb, line 125
def self.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?() click to toggle source
# File lib/new_relic/agent/instrumentation/rake.rb, line 63
def self.safe_from_third_party_gem?
  if 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
  else
    true
  end
end
should_install?() click to toggle source
# File lib/new_relic/agent/instrumentation/rake.rb, line 55
def self.should_install?
  is_supported_version? && safe_from_third_party_gem?
end
should_trace?(name) click to toggle source
# File lib/new_relic/agent/instrumentation/rake.rb, line 72
def self.should_trace?(name)
  NewRelic::Agent.config[:'rake.tasks'].any? do |regex|
    regex.match(name)
  end
end

Public Instance Methods

execute(*args, &block) click to toggle source
Calls superclass method
# File lib/new_relic/agent/instrumentation/rake.rb, line 89
def execute(*args, &block)
  NewRelic::Agent::MethodTracer.trace_execution_scoped("Rake/execute/#{self.name}") do
    super
  end
end
invoke_prerequisites_concurrently(*_) click to toggle source
Calls superclass method
# File lib/new_relic/agent/instrumentation/rake.rb, line 101
def invoke_prerequisites_concurrently(*_)
  NewRelic::Agent::MethodTracer.trace_execution_scoped("Rake/execute/multitask") do
    prereqs = self.prerequisite_tasks.map(&:name).join(", ")
    NewRelic::Agent::Datastores.notice_statement("Couldn't trace concurrent prereq tasks: #{prereqs}", 0)
    super
  end
end