diff --git a/lib/new_relic/control/instance_methods.rb b/lib/new_relic/control/instance_methods.rb index ee3dd91dfa..6d48b0d2a7 100644 --- a/lib/new_relic/control/instance_methods.rb +++ b/lib/new_relic/control/instance_methods.rb @@ -64,8 +64,12 @@ def init_plugin(options = {}) # An artifact of earlier implementation, we put both #add_method_tracer and #trace_execution # methods in the module methods. - Module.send(:include, NewRelic::Agent::MethodTracer::ClassMethods) - Module.send(:include, NewRelic::Agent::MethodTracer) + # Rails applications load the next two lines before any other initializers are run + unless defined?(Rails::VERSION) + Module.send(:include, NewRelic::Agent::MethodTracer::ClassMethods) + Module.send(:include, NewRelic::Agent::MethodTracer) + end + init_config(options) NewRelic::Agent.agent = NewRelic::Agent::Agent.instance init_instrumentation diff --git a/lib/newrelic_rpm.rb b/lib/newrelic_rpm.rb index 0b118b1d39..37e6e1854e 100644 --- a/lib/newrelic_rpm.rb +++ b/lib/newrelic_rpm.rb @@ -20,7 +20,12 @@ if defined?(Rails::VERSION) module NewRelic class Railtie < Rails::Railtie - initializer "newrelic_rpm.start_plugin", before: :load_config_initializers do |app| + initializer "newrelic_rpm.include_method_tracers", before: :load_config_initializers do |app| + Module.send(:include, NewRelic::Agent::MethodTracer::ClassMethods) + Module.send(:include, NewRelic::Agent::MethodTracer) + end + + initializer "newrelic_rpm.start_plugin", after: :load_config_initializers do |app| NewRelic::Control.instance.init_plugin(config: app.config) end end diff --git a/test/environments/rails40/config/initializers/test.rb b/test/environments/rails40/config/initializers/test.rb new file mode 100644 index 0000000000..1d88e77b0a --- /dev/null +++ b/test/environments/rails40/config/initializers/test.rb @@ -0,0 +1,20 @@ +# This file is distributed under New Relic's license terms. +# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details. +# frozen_string_literal: true + +require 'new_relic/agent/method_tracer' + +class Bloodhound < ActiveRecord::Base + include ::NewRelic::Agent::MethodTracer + + def sniff + puts "When a bloodhound sniffs a scent article (a piece of clothing or item touched only by the subject), " \ + "air rushes through its nasal cavity and chemical vapors — or odors — lodge in the mucus and bombard the dog's " \ + "scent receptors. " \ + "Source: https://www.pbs.org/wnet/nature/underdogs-the-bloodhounds-amazing-sense-of-smell/350/" + end + + add_method_tracer :sniff +end + +Rails.application.config.active_record.timestamped_migrations = false diff --git a/test/environments/rails41/config/initializers/test.rb b/test/environments/rails41/config/initializers/test.rb new file mode 100644 index 0000000000..06be89db54 --- /dev/null +++ b/test/environments/rails41/config/initializers/test.rb @@ -0,0 +1,19 @@ +# This file is distributed under New Relic's license terms. +# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details. +# frozen_string_literal: true + +require 'new_relic/agent/method_tracer' + +class Bloodhound < ActiveRecord::Base + include ::NewRelic::Agent::MethodTracer + + def sniff + puts "When a bloodhound sniffs a scent article (a piece of clothing or item touched only by the subject)," \ + "air rushes through its nasal cavity and chemical vapors — or odors — lodge in the mucus and bombard the dog's scent receptors. " \ + "Source: https://www.pbs.org/wnet/nature/underdogs-the-bloodhounds-amazing-sense-of-smell/350/" + end + + add_method_tracer :sniff +end + +Rails.application.config.active_record.timestamped_migrations = false diff --git a/test/environments/rails42/config/initializers/test.rb b/test/environments/rails42/config/initializers/test.rb new file mode 100644 index 0000000000..1d88e77b0a --- /dev/null +++ b/test/environments/rails42/config/initializers/test.rb @@ -0,0 +1,20 @@ +# This file is distributed under New Relic's license terms. +# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details. +# frozen_string_literal: true + +require 'new_relic/agent/method_tracer' + +class Bloodhound < ActiveRecord::Base + include ::NewRelic::Agent::MethodTracer + + def sniff + puts "When a bloodhound sniffs a scent article (a piece of clothing or item touched only by the subject), " \ + "air rushes through its nasal cavity and chemical vapors — or odors — lodge in the mucus and bombard the dog's " \ + "scent receptors. " \ + "Source: https://www.pbs.org/wnet/nature/underdogs-the-bloodhounds-amazing-sense-of-smell/350/" + end + + add_method_tracer :sniff +end + +Rails.application.config.active_record.timestamped_migrations = false diff --git a/test/environments/rails50/config/initializers/test.rb b/test/environments/rails50/config/initializers/test.rb new file mode 100644 index 0000000000..1d88e77b0a --- /dev/null +++ b/test/environments/rails50/config/initializers/test.rb @@ -0,0 +1,20 @@ +# This file is distributed under New Relic's license terms. +# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details. +# frozen_string_literal: true + +require 'new_relic/agent/method_tracer' + +class Bloodhound < ActiveRecord::Base + include ::NewRelic::Agent::MethodTracer + + def sniff + puts "When a bloodhound sniffs a scent article (a piece of clothing or item touched only by the subject), " \ + "air rushes through its nasal cavity and chemical vapors — or odors — lodge in the mucus and bombard the dog's " \ + "scent receptors. " \ + "Source: https://www.pbs.org/wnet/nature/underdogs-the-bloodhounds-amazing-sense-of-smell/350/" + end + + add_method_tracer :sniff +end + +Rails.application.config.active_record.timestamped_migrations = false diff --git a/test/environments/rails51/config/initializers/test.rb b/test/environments/rails51/config/initializers/test.rb new file mode 100644 index 0000000000..1d88e77b0a --- /dev/null +++ b/test/environments/rails51/config/initializers/test.rb @@ -0,0 +1,20 @@ +# This file is distributed under New Relic's license terms. +# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details. +# frozen_string_literal: true + +require 'new_relic/agent/method_tracer' + +class Bloodhound < ActiveRecord::Base + include ::NewRelic::Agent::MethodTracer + + def sniff + puts "When a bloodhound sniffs a scent article (a piece of clothing or item touched only by the subject), " \ + "air rushes through its nasal cavity and chemical vapors — or odors — lodge in the mucus and bombard the dog's " \ + "scent receptors. " \ + "Source: https://www.pbs.org/wnet/nature/underdogs-the-bloodhounds-amazing-sense-of-smell/350/" + end + + add_method_tracer :sniff +end + +Rails.application.config.active_record.timestamped_migrations = false diff --git a/test/environments/rails52/config/initializers/test.rb b/test/environments/rails52/config/initializers/test.rb new file mode 100644 index 0000000000..1d88e77b0a --- /dev/null +++ b/test/environments/rails52/config/initializers/test.rb @@ -0,0 +1,20 @@ +# This file is distributed under New Relic's license terms. +# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details. +# frozen_string_literal: true + +require 'new_relic/agent/method_tracer' + +class Bloodhound < ActiveRecord::Base + include ::NewRelic::Agent::MethodTracer + + def sniff + puts "When a bloodhound sniffs a scent article (a piece of clothing or item touched only by the subject), " \ + "air rushes through its nasal cavity and chemical vapors — or odors — lodge in the mucus and bombard the dog's " \ + "scent receptors. " \ + "Source: https://www.pbs.org/wnet/nature/underdogs-the-bloodhounds-amazing-sense-of-smell/350/" + end + + add_method_tracer :sniff +end + +Rails.application.config.active_record.timestamped_migrations = false diff --git a/test/environments/rails60/config/initializers/test.rb b/test/environments/rails60/config/initializers/test.rb new file mode 100644 index 0000000000..1d88e77b0a --- /dev/null +++ b/test/environments/rails60/config/initializers/test.rb @@ -0,0 +1,20 @@ +# This file is distributed under New Relic's license terms. +# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details. +# frozen_string_literal: true + +require 'new_relic/agent/method_tracer' + +class Bloodhound < ActiveRecord::Base + include ::NewRelic::Agent::MethodTracer + + def sniff + puts "When a bloodhound sniffs a scent article (a piece of clothing or item touched only by the subject), " \ + "air rushes through its nasal cavity and chemical vapors — or odors — lodge in the mucus and bombard the dog's " \ + "scent receptors. " \ + "Source: https://www.pbs.org/wnet/nature/underdogs-the-bloodhounds-amazing-sense-of-smell/350/" + end + + add_method_tracer :sniff +end + +Rails.application.config.active_record.timestamped_migrations = false diff --git a/test/environments/rails61/config/initializers/test.rb b/test/environments/rails61/config/initializers/test.rb new file mode 100644 index 0000000000..1d88e77b0a --- /dev/null +++ b/test/environments/rails61/config/initializers/test.rb @@ -0,0 +1,20 @@ +# This file is distributed under New Relic's license terms. +# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details. +# frozen_string_literal: true + +require 'new_relic/agent/method_tracer' + +class Bloodhound < ActiveRecord::Base + include ::NewRelic::Agent::MethodTracer + + def sniff + puts "When a bloodhound sniffs a scent article (a piece of clothing or item touched only by the subject), " \ + "air rushes through its nasal cavity and chemical vapors — or odors — lodge in the mucus and bombard the dog's " \ + "scent receptors. " \ + "Source: https://www.pbs.org/wnet/nature/underdogs-the-bloodhounds-amazing-sense-of-smell/350/" + end + + add_method_tracer :sniff +end + +Rails.application.config.active_record.timestamped_migrations = false diff --git a/test/environments/rails70/config/initializers/test.rb b/test/environments/rails70/config/initializers/test.rb new file mode 100644 index 0000000000..1d88e77b0a --- /dev/null +++ b/test/environments/rails70/config/initializers/test.rb @@ -0,0 +1,20 @@ +# This file is distributed under New Relic's license terms. +# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details. +# frozen_string_literal: true + +require 'new_relic/agent/method_tracer' + +class Bloodhound < ActiveRecord::Base + include ::NewRelic::Agent::MethodTracer + + def sniff + puts "When a bloodhound sniffs a scent article (a piece of clothing or item touched only by the subject), " \ + "air rushes through its nasal cavity and chemical vapors — or odors — lodge in the mucus and bombard the dog's " \ + "scent receptors. " \ + "Source: https://www.pbs.org/wnet/nature/underdogs-the-bloodhounds-amazing-sense-of-smell/350/" + end + + add_method_tracer :sniff +end + +Rails.application.config.active_record.timestamped_migrations = false diff --git a/test/environments/railsedge/config/initializers/test.rb b/test/environments/railsedge/config/initializers/test.rb new file mode 100644 index 0000000000..1d88e77b0a --- /dev/null +++ b/test/environments/railsedge/config/initializers/test.rb @@ -0,0 +1,20 @@ +# This file is distributed under New Relic's license terms. +# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details. +# frozen_string_literal: true + +require 'new_relic/agent/method_tracer' + +class Bloodhound < ActiveRecord::Base + include ::NewRelic::Agent::MethodTracer + + def sniff + puts "When a bloodhound sniffs a scent article (a piece of clothing or item touched only by the subject), " \ + "air rushes through its nasal cavity and chemical vapors — or odors — lodge in the mucus and bombard the dog's " \ + "scent receptors. " \ + "Source: https://www.pbs.org/wnet/nature/underdogs-the-bloodhounds-amazing-sense-of-smell/350/" + end + + add_method_tracer :sniff +end + +Rails.application.config.active_record.timestamped_migrations = false diff --git a/test/new_relic/newrelic_rpm_test.rb b/test/new_relic/newrelic_rpm_test.rb new file mode 100644 index 0000000000..3698b9bad8 --- /dev/null +++ b/test/new_relic/newrelic_rpm_test.rb @@ -0,0 +1,47 @@ +# This file is distributed under New Relic's license terms. +# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details. +# frozen_string_literal: true + +require_relative '../test_helper' + +class NewRelicRpmTest < Minitest::Test + # This test examines the behavior of an initializer when the agent is started in a Rails context + # The initializer used for these tests is defined in test/environments/*/config/inititalizers/test.rb + + # We have documentation recommending customers call add_method_tracer + # in their initializers, let's make sure this works + def test_add_method_tracer_in_initializer_gets_traced + skip unless defined?(Rails::VERSION) + skip 'MySQL error for Rails 3.2' if Rails::VERSION::MAJOR == 3 + + assert Bloodhound.newrelic_method_exists?('sniff'), + 'Bloodhound#sniff not found by' \ + 'NewRelic::Agent::MethodTracer::ClassMethods::AddMethodTracer.newrelic_method_exists?' + assert Bloodhound.method_traced?('sniff'), + 'Bloodhound#sniff not found by' \ + 'NewRelic::Agent::MethodTracer::ClassMethods::AddMethodTracer.method_traced?' + end + + # All supported Rails versions have the default value for + # timestamped_migrations as true. Our initializer sets it to false. + # Test to resolve: https://github.com/newrelic/newrelic-ruby-agent/issues/662 + def test_active_record_initializer_config_change_saved + skip unless defined?(Rails::VERSION) + # TODO: This test passes in a Rails console in a playground app and in the customer's environment + # but fails in this unit test context + skip if Gem::Version.new(NewRelic::VERSION::STRING) >= Gem::Version.new('8.13.0') + skip 'MySQL error for Rails 3.2' if Rails::VERSION::MAJOR == 3 + + # Verify the configuration value was set to the initializer value + refute Rails.application.config.active_record.timestamped_migrations, + "Rails.application.config.active_record.timestamped_migrations equals true, expected false" + + # Verify the configuration value was applied to the ActiveRecord class variable + if Gem::Version.new(Rails::VERSION::STRING) >= Gem::Version.new('7.1') + refute ActiveRecord.timestamped_migrations, "ActiveRecord.timestamped_migrations equals true, expected false" + else + refute ActiveRecord::Base.timestamped_migrations, + "ActiveRecord::Base.timestamped_migrations equals true, expected false" + end + end +end