Skip to content

Commit

Permalink
Merge pull request #2239 from newrelic/ignore_non_server_rails_commands
Browse files Browse the repository at this point in the history
Disable autostart for non 'server' Rails commands
  • Loading branch information
fallwith authored Sep 29, 2023
2 parents 10846a6 + 356ab6a commit 806b0a9
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 11 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

Version <dev> brings support for gleaning a Docker container id from cgroups v2 based containers and records additional synthetics attributes.

- **Feature: Prevent the agent from starting in rails commands in Rails 7**

Previously, the agent ignored many Rails commands by default, such as `rails routes`, using Rake-specific logic. This was accomplished by setting these commands as default values for the config option `autostart.denylisted_rake_tasks`. However, Rails 7 no longer uses Rake for these commands, causing the agent to start running and attempting to record data when running these commands. The commands have now been added to the default value for the config option `autostart.denylisted_constants`, which will allow the agent to recognize these commands correctly in Rails 7 and prevent the agent from starting during ignored tasks. Note that the agent will continue to start up when the `rails server` and `rails runner` commands are invoked. [PR#2239](https://github.com/newrelic/newrelic-ruby-agent/pull/2239)

- **Feature: Enhance Docker container id reporting**

Previously, the agent was only capable of determining a host Docker container's ID if the container was based on cgroups v1. Now, containers based on cgroups v2 will also have their container IDs reported to New Relic. [PR#2229](https://github.com/newrelic/newrelic-ruby-agent/issues/2229).
Expand Down
15 changes: 14 additions & 1 deletion lib/new_relic/agent/configuration/default_source.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1014,7 +1014,20 @@ def self.enforce_fallback(allowed_values: nil, fallback: nil)
},
# Autostart
:'autostart.denylisted_constants' => {
:default => 'Rails::Console',
:default => %w[Rails::Command::ConsoleCommand
Rails::Command::CredentialsCommand
Rails::Command::Db::System::ChangeCommand
Rails::Command::DbConsoleCommand
Rails::Command::DestroyCommand
Rails::Command::DevCommand
Rails::Command::EncryptedCommand
Rails::Command::GenerateCommand
Rails::Command::InitializersCommand
Rails::Command::NotesCommand
Rails::Command::RoutesCommand
Rails::Command::SecretsCommand
Rails::Console
Rails::DBConsole].join(','),
:public => true,
:type => String,
:allowed_from_server => false,
Expand Down
48 changes: 38 additions & 10 deletions test/new_relic/agent/autostart_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,45 @@ def test_typically_the_agent_should_autostart
assert_predicate ::NewRelic::Agent::Autostart, :agent_should_start?
end

if defined?(::Rails)
def test_agent_wont_autostart_if_RAILS_CONSOLE_constant_is_defined
refute defined?(::Rails::Console), "precondition: Rails::Console shouldn't be defined"
Rails.const_set(:Console, Class.new)

refute_predicate ::NewRelic::Agent::Autostart, :agent_should_start?, "Agent shouldn't autostart in Rails Console session"
ensure
Rails.send(:remove_const, :Console)
def test_agent_will_not_autostart_in_certain_contexts_recognized_by_constants_being_defined
rails_is_present = defined?(::Rails)
NewRelic::Agent.config[:'autostart.denylisted_constants'].split(/\s*,\s*/).each do |constant|
assert_predicate ::NewRelic::Agent::Autostart, :agent_should_start?, 'Agent should autostart by default'

# For Rails::Command::ConsoleCommand as an example, eval these:
# 'module ::Rails; end',
# 'module ::Rails::Command; end', and
# 'module ::Rails::Command::ConsoleCommand; end'
#
# If this test is running within a context that already has Rails defined,
# the result of `::NewRelic::LanguageSupport.constantize('::Rails')` will
# be non-nil and the first `eval` will be skipped.
elements = constant.split('::')
elements.inject(+'') do |namespace, element|
namespace += "::#{element}"
eval("module #{namespace}; end") unless ::NewRelic::LanguageSupport.constantize(namespace)
namespace
end

refute_predicate ::NewRelic::Agent::Autostart,
:agent_should_start?,
"Agent shouldn't autostart when the '#{constant}' constant is defined"

# For Rails::Command::ConsoleCommand as an example, eval these:
# "::Rails::Command.send(:remove_const, 'ConsoleCommand'.to_sym)" and
# "::Rails.send(:remove_const, 'Command'.to_sym)".
#
# and then invoke `Object.send(:remove_const, 'Rails'.to_sym)` to
# undefine Rails itself. If Rails was already defined before this test
# ran, don't invoke the `Object.send` command and leave Rails alone.
dupe = constant.dup
while dupe =~ /^.+(::.+)$/
element = Regexp.last_match(1)
dupe.sub!(/#{element}$/, '')
eval("::#{dupe}.send(:remove_const, '#{element.sub('::', '')}'.to_sym)")
end
Object.send(:remove_const, dupe.to_sym) unless dupe == 'Rails' && rails_is_present
end
else
puts "Skipping `test_agent_wont_autostart_if_RAILS_CONSOLE_constant_is_defined` in #{File.basename(__FILE__)} because Rails is unavailable" if ENV['VERBOSE_TEST_OUTPUT']
end

def test_agent_will_autostart_if_global_CONSOLE_constant_is_defined
Expand Down

0 comments on commit 806b0a9

Please sign in to comment.