Skip to content

Commit

Permalink
Split agent startup for Rails into two initializers
Browse files Browse the repository at this point in the history
The central argument around loading the agent before other
initializers is to allow initializers to reference the add_method_tracer
API. Including the modules before other initializers are run
allows this to happen.

If the second initializer doesn't specify when it should be run, it
will run immediately after our first initializer. By specifying after:
:load_config_initializers, the agent will not execute init_plugin until
after initializers defined in config/initializers are run. This stops
the agent from forcing ActiveRecord to load before customer-defined
initializers.
kaylareopelle committed Dec 7, 2022

Verified

This commit was signed with the committer’s verified signature.
kaylareopelle Kayla Reopelle
1 parent b5a3aed commit 29e749d
Showing 13 changed files with 258 additions and 3 deletions.
8 changes: 6 additions & 2 deletions lib/new_relic/control/instance_methods.rb
Original file line number Diff line number Diff line change
@@ -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
7 changes: 6 additions & 1 deletion lib/newrelic_rpm.rb
Original file line number Diff line number Diff line change
@@ -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
20 changes: 20 additions & 0 deletions test/environments/rails40/config/initializers/test.rb
Original file line number Diff line number Diff line change
@@ -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
19 changes: 19 additions & 0 deletions test/environments/rails41/config/initializers/test.rb
Original file line number Diff line number Diff line change
@@ -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
20 changes: 20 additions & 0 deletions test/environments/rails42/config/initializers/test.rb
Original file line number Diff line number Diff line change
@@ -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
20 changes: 20 additions & 0 deletions test/environments/rails50/config/initializers/test.rb
Original file line number Diff line number Diff line change
@@ -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
20 changes: 20 additions & 0 deletions test/environments/rails51/config/initializers/test.rb
Original file line number Diff line number Diff line change
@@ -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
20 changes: 20 additions & 0 deletions test/environments/rails52/config/initializers/test.rb
Original file line number Diff line number Diff line change
@@ -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
20 changes: 20 additions & 0 deletions test/environments/rails60/config/initializers/test.rb
Original file line number Diff line number Diff line change
@@ -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
20 changes: 20 additions & 0 deletions test/environments/rails61/config/initializers/test.rb
Original file line number Diff line number Diff line change
@@ -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
20 changes: 20 additions & 0 deletions test/environments/rails70/config/initializers/test.rb
Original file line number Diff line number Diff line change
@@ -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
20 changes: 20 additions & 0 deletions test/environments/railsedge/config/initializers/test.rb
Original file line number Diff line number Diff line change
@@ -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
47 changes: 47 additions & 0 deletions test/new_relic/newrelic_rpm_test.rb
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 29e749d

Please sign in to comment.