diff --git a/.changesets/ignore-rails-healthcheck-by-default.md b/.changesets/ignore-rails-healthcheck-by-default.md new file mode 100644 index 000000000..5be9a005c --- /dev/null +++ b/.changesets/ignore-rails-healthcheck-by-default.md @@ -0,0 +1,31 @@ +--- +bump: patch +type: change +--- + +Ignore the Rails healthcheck endpoint (Rails::HealthController#show) by default for Rails apps. + +If the `ignore_actions` option is set in the `config/appsignal.yml` file, the default is overwritten. +If the `APPSIGNAL_IGNORE_ACTIONS` environment variable is set, the default is overwritten. +When using the `Appsignal.configure` helper, add more actions to the default like so: + +```ruby +# config/appsignal.rb +Appsignal.configure do |config| + # Add more actions to ignore + config.ignore_actions << "My action" +end +``` + +To overwrite the default using the `Appsignal.configure` helper, do either of the following: + +```ruby +# config/appsignal.rb +Appsignal.configure do |config| + # Overwrite the default value, ignoring all actions ignored by default + config.ignore_actions = ["My action"] + + # To only remove the healtcheck endpoint + config.ignore_actions.delete("Rails::HealthController#show") +end +``` diff --git a/lib/appsignal/config.rb b/lib/appsignal/config.rb index 189748407..c0b2895d1 100644 --- a/lib/appsignal/config.rb +++ b/lib/appsignal/config.rb @@ -243,15 +243,26 @@ def load_config @system_config = detect_from_system merge(system_config) - # Set defaults from loaders in reverse order so the first register + # Set defaults from loaders in reverse order so the first registered # loader's defaults overwrite all others self.class.loader_defaults.reverse.each do |loader_defaults| + options = config_hash + new_loader_defaults = {} defaults = loader_defaults[:options] - @loaders_config.merge!(defaults.merge( + defaults.each do |option, value| + new_loader_defaults[option] = + if ARRAY_OPTIONS.key?(option) + # Merge arrays: new value first + value + options[option] + else + value + end + end + @loaders_config.merge!(new_loader_defaults.merge( :root_path => loader_defaults[:root_path], :env => loader_defaults[:env] )) - merge(defaults) + merge(new_loader_defaults) end # Track origin of env diff --git a/lib/appsignal/integrations/railtie.rb b/lib/appsignal/integrations/railtie.rb index 3ea6804a4..fb5706232 100644 --- a/lib/appsignal/integrations/railtie.rb +++ b/lib/appsignal/integrations/railtie.rb @@ -45,7 +45,8 @@ def self.load_default_config :root_path => Rails.root, :env => Rails.env, :name => Appsignal::Utils::RailsHelper.detected_rails_app_name, - :log_path => Rails.root.join("log") + :log_path => Rails.root.join("log"), + :ignore_actions => ["Rails::HealthController#show"] ) end diff --git a/spec/lib/appsignal/cli/diagnose_spec.rb b/spec/lib/appsignal/cli/diagnose_spec.rb index 94e232b97..d2236c873 100644 --- a/spec/lib/appsignal/cli/diagnose_spec.rb +++ b/spec/lib/appsignal/cli/diagnose_spec.rb @@ -926,7 +926,9 @@ def dont_accept_prompt_to_send_diagnostics_report # Workaround to not being able to require the railtie file # multiple times and triggering the Rails initialization process. # This will be used whtn the MyApp app has already been loaded. - Appsignal::Integrations::Railtie.load_default_config if defined?(MyApp) + if defined?(MyApp) && MyApp::Application.initialized? + Appsignal::Integrations::Railtie.load_default_config + end run_within_dir(root_path) end @@ -942,6 +944,7 @@ def dont_accept_prompt_to_send_diagnostics_report " ignore_actions: [\"Action from DSL\"]\n" \ " Sources:\n" \ " default: []\n" \ + " loaders: [\"Rails::HealthController#show\"]\n" \ " dsl: [\"Action from DSL\"]\n" ) @@ -951,7 +954,8 @@ def dont_accept_prompt_to_send_diagnostics_report "root_path" => root_path, "env" => "test", "log_path" => File.join(rails_project_fixture_path, "log"), - "name" => "MyApp" + "name" => "MyApp", + "ignore_actions" => ["Rails::HealthController#show"] } ) # Includes values from the DSL diff --git a/spec/lib/appsignal/config_spec.rb b/spec/lib/appsignal/config_spec.rb index 4eb96d9a9..5b9fbbd6a 100644 --- a/spec/lib/appsignal/config_spec.rb +++ b/spec/lib/appsignal/config_spec.rb @@ -313,7 +313,7 @@ def on_load register_config_defaults( :env => "loader_env", :root_path => "loader-path", - :ignore_actions => ["loader-action"], + :ignore_actions => ["loader 1 action"], :my_option => "my_value", :nil_option => nil ) @@ -323,7 +323,7 @@ def on_load end it "overrides the default config option values" do - expect(config[:ignore_actions]).to eq(["loader-action"]) + expect(config[:ignore_actions]).to eq(["loader 1 action"]) end it "does not set any nil values" do @@ -346,7 +346,8 @@ def on_load def on_load register_config_defaults( :my_option => "second_value", - :second_option => "second_value" + :second_option => "second_value", + :ignore_actions => ["loader 2 action"] ) end end @@ -358,6 +359,26 @@ def on_load :my_option => "my_value", :second_option => "second_value" ) + expect(config.loaders_config).to include( + :my_option => "my_value", + :second_option => "second_value" + ) + end + + it "merges options with array values" do + expect(config.config_hash).to include( + :ignore_actions => ["loader 1 action", "loader 2 action"] + ) + expect(config.loaders_config).to include( + :ignore_actions => ["loader 1 action", "loader 2 action"] + ) + + # Doesn't modify defaults + defaults = Appsignal::Config.loader_defaults + expect(defaults.find { |d| d[:name] == :options_loader }[:options][:ignore_actions]) + .to eq(["loader 1 action"]) + expect(defaults.find { |d| d[:name] == :options_loader2 }[:options][:ignore_actions]) + .to eq(["loader 2 action"]) end end end diff --git a/spec/lib/appsignal/integrations/railtie_spec.rb b/spec/lib/appsignal/integrations/railtie_spec.rb index db0c14a4c..cb05eccf9 100644 --- a/spec/lib/appsignal/integrations/railtie_spec.rb +++ b/spec/lib/appsignal/integrations/railtie_spec.rb @@ -82,6 +82,8 @@ def initialize_railtie(event) expect(rails_defaults[:options][:name]).to eq("MyApp") expect(rails_defaults[:options][:log_path]) .to eq(Pathname.new(File.join(rails_project_fixture_path, "log"))) + expect(rails_defaults[:options][:ignore_actions]) + .to eq(["Rails::HealthController#show"]) end it "loads the app name from the project's appsignal.yml file" do