newrelic_rpm 8.15.0 → 9.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -28
  3. data/.rubocop_todo.yml +41 -3
  4. data/CHANGELOG.md +191 -38
  5. data/CONTRIBUTING.md +1 -1
  6. data/README.md +3 -1
  7. data/bin/nrdebug +16 -16
  8. data/lib/new_relic/agent/agent_helpers/connect.rb +1 -1
  9. data/lib/new_relic/agent/agent_helpers/special_startup.rb +1 -2
  10. data/lib/new_relic/agent/attribute_filter.rb +0 -2
  11. data/lib/new_relic/agent/commands/thread_profiler_session.rb +3 -3
  12. data/lib/new_relic/agent/configuration/default_source.rb +139 -476
  13. data/lib/new_relic/agent/configuration/high_security_source.rb +0 -2
  14. data/lib/new_relic/agent/configuration/security_policy_source.rb +0 -16
  15. data/lib/new_relic/agent/database.rb +0 -14
  16. data/lib/new_relic/agent/distributed_tracing/cross_app_tracing.rb +1 -2
  17. data/lib/new_relic/agent/error_collector.rb +1 -1
  18. data/lib/new_relic/agent/error_filter.rb +3 -3
  19. data/lib/new_relic/agent/instrumentation/action_cable_subscriber.rb +6 -19
  20. data/lib/new_relic/agent/instrumentation/action_controller_other_subscriber.rb +39 -0
  21. data/lib/new_relic/agent/instrumentation/action_dispatch.rb +31 -0
  22. data/lib/new_relic/agent/instrumentation/action_dispatch_subscriber.rb +64 -0
  23. data/lib/new_relic/agent/instrumentation/action_mailbox.rb +30 -0
  24. data/lib/new_relic/agent/instrumentation/action_mailbox_subscriber.rb +33 -0
  25. data/lib/new_relic/agent/instrumentation/action_mailer.rb +30 -0
  26. data/lib/new_relic/agent/instrumentation/action_mailer_subscriber.rb +85 -0
  27. data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +7 -7
  28. data/lib/new_relic/agent/instrumentation/active_job.rb +15 -2
  29. data/lib/new_relic/agent/instrumentation/active_job_subscriber.rb +41 -0
  30. data/lib/new_relic/agent/instrumentation/active_storage.rb +4 -0
  31. data/lib/new_relic/agent/instrumentation/active_storage_subscriber.rb +2 -30
  32. data/lib/new_relic/agent/instrumentation/active_support.rb +21 -6
  33. data/lib/new_relic/agent/instrumentation/active_support_subscriber.rb +41 -0
  34. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +1 -1
  35. data/lib/new_relic/agent/instrumentation/custom_events.rb +12 -0
  36. data/lib/new_relic/agent/instrumentation/fiber/chain.rb +20 -0
  37. data/lib/new_relic/agent/instrumentation/fiber/instrumentation.rb +24 -0
  38. data/lib/new_relic/agent/instrumentation/fiber/prepend.rb +18 -0
  39. data/lib/new_relic/agent/instrumentation/fiber.rb +25 -0
  40. data/lib/new_relic/agent/instrumentation/grape.rb +1 -1
  41. data/lib/new_relic/agent/instrumentation/memcache.rb +2 -2
  42. data/lib/new_relic/agent/instrumentation/net_http.rb +1 -1
  43. data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +41 -0
  44. data/lib/new_relic/agent/instrumentation/rails_notifications/action_cable.rb +4 -4
  45. data/lib/new_relic/agent/instrumentation/rails_notifications/action_controller.rb +13 -1
  46. data/lib/new_relic/agent/instrumentation/rake/instrumentation.rb +1 -8
  47. data/lib/new_relic/agent/instrumentation/rake.rb +1 -1
  48. data/lib/new_relic/agent/instrumentation/redis.rb +1 -1
  49. data/lib/new_relic/agent/instrumentation/resque.rb +1 -1
  50. data/lib/new_relic/agent/instrumentation/sequel.rb +4 -5
  51. data/lib/new_relic/agent/instrumentation/thread/instrumentation.rb +3 -7
  52. data/lib/new_relic/agent/monitors/cross_app_monitor.rb +0 -1
  53. data/lib/new_relic/agent/new_relic_service/security_policy_settings.rb +0 -1
  54. data/lib/new_relic/agent/new_relic_service.rb +1 -1
  55. data/lib/new_relic/agent/rules_engine/segment_terms_rule.rb +0 -1
  56. data/lib/new_relic/agent/samplers/delayed_job_sampler.rb +1 -1
  57. data/lib/new_relic/agent/tracer.rb +10 -1
  58. data/lib/new_relic/agent/transaction/abstract_segment.rb +2 -2
  59. data/lib/new_relic/agent/transaction/tracing.rb +2 -2
  60. data/lib/new_relic/agent/transaction.rb +17 -16
  61. data/lib/new_relic/agent.rb +1 -19
  62. data/lib/new_relic/cli/commands/install.rb +9 -9
  63. data/lib/new_relic/control/instance_methods.rb +1 -1
  64. data/lib/new_relic/local_environment.rb +0 -10
  65. data/lib/new_relic/supportability_helper.rb +0 -1
  66. data/lib/new_relic/version.rb +2 -2
  67. data/lib/newrelic_rpm.rb +1 -1
  68. data/lib/sequel/extensions/{newrelic_instrumentation.rb → new_relic_instrumentation.rb} +3 -3
  69. data/lib/sequel/plugins/{newrelic_instrumentation.rb → new_relic_instrumentation.rb} +3 -3
  70. data/lib/tasks/helpers/format.rb +1 -1
  71. data/lib/tasks/instrumentation_generator/instrumentation.thor +7 -10
  72. data/lib/tasks/instrumentation_generator/templates/Envfile.tt +1 -1
  73. data/newrelic.yml +15 -9
  74. data/newrelic_rpm.gemspec +17 -13
  75. data/test/agent_helper.rb +1 -1
  76. metadata +37 -14
  77. data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +0 -83
  78. data/lib/new_relic/agent/instrumentation/authlogic.rb +0 -33
  79. data/lib/new_relic/agent/instrumentation/data_mapper.rb +0 -215
  80. data/lib/new_relic/agent/instrumentation/rainbows_instrumentation.rb +0 -36
  81. data/lib/new_relic/agent/instrumentation/sunspot.rb +0 -41
@@ -2,11 +2,26 @@
2
2
  # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
3
  # frozen_string_literal: true
4
4
 
5
- # This is a helper file that will allow apps using ActiveSupport without Rails
6
- # to still leverage all ActiveSupport based instrumentation functionality
7
- # offered by the agent that would otherwise be gated by the detection of Rails.
5
+ require 'new_relic/agent/instrumentation/active_support_subscriber'
8
6
 
9
- # ActiveSupport notifications custom events
10
- if !defined?(Rails) && defined?(ActiveSupport::Notifications) && defined?(ActiveSupport::IsolatedExecutionState)
11
- require_relative 'rails_notifications/custom_events'
7
+ DependencyDetection.defer do
8
+ named :active_support
9
+
10
+ depends_on do
11
+ !NewRelic::Agent.config[:disable_active_support]
12
+ end
13
+
14
+ depends_on do
15
+ defined?(ActiveSupport) &&
16
+ !NewRelic::Agent::Instrumentation::ActiveSupportSubscriber.subscribed?
17
+ end
18
+
19
+ executes do
20
+ NewRelic::Agent.logger.info('Installing ActiveSupport instrumentation')
21
+ end
22
+
23
+ executes do
24
+ ActiveSupport::Notifications.subscribe(/\.active_support$/,
25
+ NewRelic::Agent::Instrumentation::ActiveSupportSubscriber.new)
26
+ end
12
27
  end
@@ -0,0 +1,41 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ require 'new_relic/agent/instrumentation/notifications_subscriber'
6
+
7
+ module NewRelic
8
+ module Agent
9
+ module Instrumentation
10
+ class ActiveSupportSubscriber < NotificationsSubscriber
11
+ def add_segment_params(segment, payload)
12
+ segment.params[:key] = payload[:key]
13
+ segment.params[:store] = payload[:store]
14
+ segment.params[:hit] = payload[:hit] if payload.key?(:hit)
15
+ segment.params[:super_operation] = payload[:super_operation] if payload.key?(:super_operation)
16
+ segment
17
+ end
18
+
19
+ def metric_name(name, payload)
20
+ store = payload[:store]
21
+ method = method_from_name(name)
22
+ "Ruby/ActiveSupport#{"/#{store}" if store}/#{method}"
23
+ end
24
+
25
+ PATTERN = /\Acache_([^\.]*)\.active_support\z/
26
+
27
+ METHOD_NAME_MAPPING = Hash.new do |h, k|
28
+ if PATTERN =~ k
29
+ h[k] = $1
30
+ else
31
+ h[k] = NewRelic::UNKNOWN
32
+ end
33
+ end
34
+
35
+ def method_from_name(name)
36
+ METHOD_NAME_MAPPING[name]
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -180,7 +180,7 @@ module NewRelic
180
180
  code_info = NewRelic::Agent::MethodTracerHelpers.code_information(self, method)
181
181
  argument_list = generate_argument_list(options.merge(code_info))
182
182
 
183
- class_eval(<<-EOC)
183
+ class_eval(<<~EOC)
184
184
  def #{with_method_name}(*args, &block)
185
185
  perform_action_with_newrelic_trace(#{argument_list.join(',')}) do
186
186
  #{without_method_name}(*args, &block)
@@ -0,0 +1,12 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ # This is a helper file that will allow apps using ActiveSupport without Rails
6
+ # to still leverage all ActiveSupport based instrumentation functionality
7
+ # offered by the agent that would otherwise be gated by the detection of Rails.
8
+
9
+ # ActiveSupport notifications custom events
10
+ if !defined?(Rails) && defined?(ActiveSupport::Notifications) && defined?(ActiveSupport::IsolatedExecutionState)
11
+ require_relative 'rails_notifications/custom_events'
12
+ end
@@ -0,0 +1,20 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module MonitoredFiber
7
+ def self.instrument!
8
+ ::Fiber.class_eval do
9
+ include NewRelic::Agent::Instrumentation::MonitoredFiber
10
+
11
+ alias_method(:initialize_without_new_relic, :initialize)
12
+
13
+ def initialize(*args, &block)
14
+ traced_block = add_thread_tracing(*args, &block)
15
+ initialize_with_newrelic_tracing { initialize_without_new_relic(*args, &traced_block) }
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,24 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module MonitoredFiber
7
+ attr_reader :nr_parent_key
8
+
9
+ def initialize_with_newrelic_tracing
10
+ @nr_parent_key = NewRelic::Agent::Tracer.current_segment_key
11
+ yield
12
+ end
13
+
14
+ def add_thread_tracing(*args, &block)
15
+ return block if !NewRelic::Agent::Tracer.thread_tracing_enabled?
16
+
17
+ NewRelic::Agent::Tracer.thread_block_with_current_transaction(
18
+ *args,
19
+ segment_name: 'Ruby/Fiber',
20
+ &block
21
+ )
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ require_relative 'instrumentation'
6
+
7
+ module NewRelic::Agent::Instrumentation
8
+ module MonitoredFiber
9
+ module Prepend
10
+ include NewRelic::Agent::Instrumentation::MonitoredFiber
11
+
12
+ def initialize(*args, &block)
13
+ traced_block = add_thread_tracing(*args, &block)
14
+ initialize_with_newrelic_tracing { super(*args, &traced_block) }
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,25 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ require_relative 'fiber/instrumentation'
6
+ require_relative 'fiber/chain'
7
+ require_relative 'fiber/prepend'
8
+
9
+ DependencyDetection.defer do
10
+ named :fiber
11
+
12
+ depends_on do
13
+ defined?(Fiber)
14
+ end
15
+
16
+ executes do
17
+ NewRelic::Agent.logger.info('Installing Fiber instrumentation')
18
+
19
+ if use_prepend?
20
+ prepend_instrument Fiber, NewRelic::Agent::Instrumentation::MonitoredFiber::Prepend
21
+ else
22
+ chain_instrument NewRelic::Agent::Instrumentation::MonitoredFiber
23
+ end
24
+ end
25
+ end
@@ -9,7 +9,7 @@ require_relative 'grape/prepend'
9
9
  DependencyDetection.defer do
10
10
  # Why not just :grape? newrelic-grape used that name already, and while we're
11
11
  # not shipping yet, overloading the name interferes with the plugin.
12
- named :grape_instrumentation
12
+ @name = :grape_instrumentation
13
13
  configure_with :grape
14
14
 
15
15
  depends_on do
@@ -46,7 +46,7 @@ DependencyDetection.defer do
46
46
  end
47
47
 
48
48
  DependencyDetection.defer do
49
- named :dalli
49
+ @name = :dalli
50
50
  configure_with :memcache
51
51
 
52
52
  depends_on { defined? Dalli::Client }
@@ -67,7 +67,7 @@ end
67
67
  # dalli/cas/client. Use a separate dependency block so it can potentially
68
68
  # re-evaluate after they've done that require.
69
69
  DependencyDetection.defer do
70
- named :dalli_cas_client
70
+ @name = :dalli_cas_client
71
71
  configure_with :memcache
72
72
 
73
73
  depends_on { defined? Dalli::Client }
@@ -27,7 +27,7 @@ DependencyDetection.defer do
27
27
  end
28
28
 
29
29
  conflicts_with_prepend do
30
- defined?(Rack::MiniProfiler)
30
+ defined?(Rack::MiniProfiler) && !defined?(Rack::MINI_PROFILER_PREPEND_NET_HTTP_PATCH)
31
31
  end
32
32
 
33
33
  conflicts_with_prepend do
@@ -47,6 +47,47 @@ module NewRelic
47
47
  end
48
48
  end
49
49
 
50
+ def start(name, id, payload)
51
+ return unless state.is_execution_traced?
52
+
53
+ start_segment(name, id, payload)
54
+ rescue => e
55
+ log_notification_error(e, name, 'start')
56
+ end
57
+
58
+ def finish(name, id, payload)
59
+ return unless state.is_execution_traced?
60
+
61
+ finish_segment(id, payload)
62
+ rescue => e
63
+ log_notification_error(e, name, 'finish')
64
+ end
65
+
66
+ def start_segment(name, id, payload)
67
+ segment = Tracer.start_segment(name: metric_name(name, payload))
68
+ add_segment_params(segment, payload)
69
+ push_segment(id, segment)
70
+ end
71
+
72
+ def finish_segment(id, payload)
73
+ if segment = pop_segment(id)
74
+ if exception = exception_object(payload)
75
+ segment.notice_error(exception)
76
+ end
77
+ segment.finish
78
+ end
79
+ end
80
+
81
+ # for subclasses
82
+ def add_segment_params(segment, payload)
83
+ # no op
84
+ end
85
+
86
+ # for subclasses
87
+ def metric_name(name, payload)
88
+ "Ruby/#{name}"
89
+ end
90
+
50
91
  def log_notification_error(error, name, event_type)
51
92
  # These are important enough failures that we want the backtraces
52
93
  # logged at error level, hence the explicit log_exception call.
@@ -9,9 +9,9 @@ DependencyDetection.defer do
9
9
  @name = :action_cable_notifications
10
10
 
11
11
  depends_on do
12
- defined?(Rails::VERSION::MAJOR) &&
13
- Rails::VERSION::MAJOR.to_i >= 5 &&
14
- defined?(ActionCable)
12
+ defined?(ActionCable::VERSION::MAJOR) &&
13
+ ActionCable::VERSION::MAJOR.to_i >= 5 &&
14
+ defined?(ActiveSupport)
15
15
  end
16
16
 
17
17
  depends_on do
@@ -25,7 +25,7 @@ DependencyDetection.defer do
25
25
 
26
26
  executes do
27
27
  # enumerate the specific events we want so that we do not get unexpected additions in the future
28
- ActiveSupport::Notifications.subscribe(/(perform_action|transmit)\.action_cable/,
28
+ ActiveSupport::Notifications.subscribe(/\A(?:perform_action|transmit|broadcast)\.action_cable\z/,
29
29
  NewRelic::Agent::Instrumentation::ActionCableSubscriber.new)
30
30
 
31
31
  ActiveSupport.on_load(:action_cable) do
@@ -3,6 +3,7 @@
3
3
  # frozen_string_literal: true
4
4
 
5
5
  require 'new_relic/agent/instrumentation/action_controller_subscriber'
6
+ require 'new_relic/agent/instrumentation/action_controller_other_subscriber'
6
7
  require 'new_relic/agent/prepend_supportability'
7
8
 
8
9
  DependencyDetection.defer do
@@ -13,7 +14,8 @@ DependencyDetection.defer do
13
14
  end
14
15
 
15
16
  depends_on do
16
- defined?(ActionController) && (defined?(ActionController::Base) || defined?(ActionController::API))
17
+ !NewRelic::Agent.config[:disable_action_controller] &&
18
+ defined?(ActionController) && (defined?(ActionController::Base) || defined?(ActionController::API))
17
19
  end
18
20
 
19
21
  executes do
@@ -29,5 +31,15 @@ DependencyDetection.defer do
29
31
 
30
32
  NewRelic::Agent::Instrumentation::ActionControllerSubscriber \
31
33
  .subscribe(/^process_action.action_controller$/)
34
+
35
+ subs = %w[send_file
36
+ send_data
37
+ redirect_to
38
+ halted_callback
39
+ unpermitted_parameters]
40
+
41
+ # have to double escape period because its going from string -> regex
42
+ NewRelic::Agent::Instrumentation::ActionControllerOtherSubscriber \
43
+ .subscribe(Regexp.new("^(#{subs.join('|')})\\.action_controller$"))
32
44
  end
33
45
  end
@@ -73,10 +73,6 @@ module NewRelic
73
73
  task.instance_eval do
74
74
  def invoke_prerequisites_concurrently(*_)
75
75
  NewRelic::Agent::MethodTracer.trace_execution_scoped("Rake/execute/multitask") do
76
- prereqs = self.prerequisite_tasks.map(&:name).join(", ")
77
- if txn = ::NewRelic::Agent::Tracer.current_transaction
78
- txn.current_segment.params[:statement] = NewRelic::Agent::Database.truncate_query("Couldn't trace concurrent prereq tasks: #{prereqs}")
79
- end
80
76
  super
81
77
  end
82
78
  end
@@ -86,12 +82,9 @@ module NewRelic
86
82
  def before_invoke_transaction(task)
87
83
  ensure_at_exit
88
84
 
89
- # We can't represent overlapping operations yet, so if multitask just
90
- # make one node and annotate with prereq task names
85
+ instrument_execute_on_prereqs(task)
91
86
  if task.application.options.always_multitask
92
87
  instrument_invoke_prerequisites_concurrently(task)
93
- else
94
- instrument_execute_on_prereqs(task)
95
88
  end
96
89
  rescue => e
97
90
  NewRelic::Agent.logger.error("Error during Rake task invoke", e)
@@ -8,7 +8,7 @@ require_relative 'rake/prepend'
8
8
 
9
9
  DependencyDetection.defer do
10
10
  # Why not :rake? newrelic-rake used that name, so avoid conflicting
11
- named :rake_instrumentation
11
+ @name = :rake_instrumentation
12
12
  configure_with :rake
13
13
 
14
14
  depends_on { defined?(Rake) && defined?(Rake::VERSION) }
@@ -13,7 +13,7 @@ require_relative 'redis/middleware'
13
13
 
14
14
  DependencyDetection.defer do
15
15
  # Why not :redis? newrelic-redis used that name, so avoid conflicting
16
- named :redis_instrumentation
16
+ @name = :redis_instrumentation
17
17
  configure_with :redis
18
18
 
19
19
  depends_on do
@@ -10,7 +10,7 @@ DependencyDetection.defer do
10
10
  @name = :resque
11
11
 
12
12
  depends_on do
13
- defined?(Resque::Job) && !NewRelic::Agent.config[:disable_resque]
13
+ defined?(Resque::Job)
14
14
  end
15
15
 
16
16
  # Airbrake uses method chaining on Resque::Job on versions < 11.0.3
@@ -11,8 +11,7 @@ DependencyDetection.defer do
11
11
  end
12
12
 
13
13
  depends_on do
14
- !NewRelic::Agent.config[:disable_sequel_instrumentation] &&
15
- !NewRelic::Agent.config[:disable_database_instrumentation]
14
+ !NewRelic::Agent.config[:disable_sequel_instrumentation]
16
15
  end
17
16
 
18
17
  def supported_sequel_version?
@@ -27,7 +26,7 @@ DependencyDetection.defer do
27
26
  NewRelic::Agent.logger.info('Installing Sequel instrumentation')
28
27
 
29
28
  if Sequel::Database.respond_to?(:extension)
30
- Sequel::Database.extension(:newrelic_instrumentation)
29
+ Sequel::Database.extension(:new_relic_instrumentation)
31
30
  else
32
31
  NewRelic::Agent.logger.info("Detected Sequel version %s." % [Sequel::VERSION])
33
32
  NewRelic::Agent.logger.info("Please see additional documentation: " +
@@ -35,10 +34,10 @@ DependencyDetection.defer do
35
34
  end
36
35
 
37
36
  Sequel.synchronize { Sequel::DATABASES.dup }.each do |db|
38
- db.extension(:newrelic_instrumentation)
37
+ db.extension(:new_relic_instrumentation)
39
38
  end
40
39
 
41
- Sequel::Model.plugin(:newrelic_instrumentation) if defined?(Sequel::Model)
40
+ Sequel::Model.plugin(:new_relic_instrumentation) if defined?(Sequel::Model)
42
41
  else
43
42
 
44
43
  NewRelic::Agent.logger.info("Sequel instrumentation requires at least version 3.37.0.")
@@ -6,15 +6,15 @@ module NewRelic
6
6
  module Agent
7
7
  module Instrumentation
8
8
  module MonitoredThread
9
- attr_reader :nr_parent_thread_id
9
+ attr_reader :nr_parent_key
10
10
 
11
11
  def initialize_with_newrelic_tracing
12
- @nr_parent_thread_id = ::Thread.current.object_id
12
+ @nr_parent_key = NewRelic::Agent::Tracer.current_segment_key
13
13
  yield
14
14
  end
15
15
 
16
16
  def add_thread_tracing(*args, &block)
17
- return block if skip_tracing?
17
+ return block if !NewRelic::Agent::Tracer.thread_tracing_enabled?
18
18
 
19
19
  NewRelic::Agent::Tracer.thread_block_with_current_transaction(
20
20
  *args,
@@ -22,10 +22,6 @@ module NewRelic
22
22
  &block
23
23
  )
24
24
  end
25
-
26
- def skip_tracing?
27
- !NewRelic::Agent.config[:'instrumentation.thread.tracing']
28
- end
29
25
  end
30
26
  end
31
27
  end
@@ -12,7 +12,6 @@ module NewRelic
12
12
  module Agent
13
13
  module DistributedTracing
14
14
  class CrossAppMonitor < InboundRequestMonitor
15
- NEWRELIC_ID_HEADER = 'X-NewRelic-ID'.freeze
16
15
  NEWRELIC_TXN_HEADER = 'X-NewRelic-Transaction'.freeze
17
16
  NEWRELIC_APPDATA_HEADER = 'X-NewRelic-App-Data'.freeze
18
17
 
@@ -14,7 +14,6 @@ module NewRelic
14
14
  custom_parameters
15
15
  custom_instrumentation_editor
16
16
  message_parameters
17
- job_arguments
18
17
  ].map(&:freeze)
19
18
 
20
19
  def self.preliminary_settings(security_policies)
@@ -595,7 +595,7 @@ module NewRelic
595
595
  return if post_string.size < Agent.config[:max_payload_size_in_bytes]
596
596
 
597
597
  ::NewRelic::Agent.logger.debug("Tried to send too much data: #{post_string.size} bytes")
598
- NewRelic::Agent.increment_metric("Supportability/Agent/Collector/#{endpoint}/MaxPayloadSizeLimit")
598
+ NewRelic::Agent.increment_metric("Supportability/Ruby/Collector/#{endpoint}/MaxPayloadSizeLimit")
599
599
  raise UnrecoverableServerException.new('413 Request Entity Too Large')
600
600
  end
601
601
 
@@ -11,7 +11,6 @@ module NewRelic
11
11
  SEGMENT_PLACEHOLDER = '*'.freeze
12
12
  ADJACENT_PLACEHOLDERS_REGEX = %r{((?:^|/)\*)(?:/\*)*}.freeze
13
13
  ADJACENT_PLACEHOLDERS_REPLACEMENT = '\1'.freeze
14
- VALID_PREFIX_SEGMENT_COUNT = 2
15
14
 
16
15
  attr_reader :prefix, :terms
17
16
 
@@ -25,7 +25,7 @@ module NewRelic
25
25
  end
26
26
 
27
27
  def initialize
28
- raise Unsupported, "DJ queue sampler disabled" if Agent.config[:disable_dj]
28
+ raise Unsupported, "DJ queue sampler disabled" if Agent.config[:'instrumentation.delayed_job'] == 'disabled'
29
29
  raise Unsupported, "DJ queue sampling unsupported with backend '#{::Delayed::Worker.backend}'" unless self.class.supported_backend?
30
30
  raise Unsupported, "No DJ worker present. Skipping DJ queue sampler" unless NewRelic::DelayedJobInjection.worker_name
31
31
  end
@@ -410,8 +410,17 @@ module NewRelic
410
410
 
411
411
  alias_method :tl_clear, :clear_state
412
412
 
413
+ def current_segment_key
414
+ ::Fiber.current.object_id
415
+ end
416
+
417
+ def thread_tracing_enabled?
418
+ NewRelic::Agent.config[:'instrumentation.thread.tracing']
419
+ end
420
+
413
421
  def thread_block_with_current_transaction(*args, segment_name:, parent: nil, &block)
414
- current_txn = ::Thread.current[:newrelic_tracer_state].current_transaction if ::Thread.current[:newrelic_tracer_state] && ::Thread.current[:newrelic_tracer_state].is_execution_traced?
422
+ parent ||= current_segment
423
+ current_txn = ::Thread.current[:newrelic_tracer_state]&.current_transaction if ::Thread.current[:newrelic_tracer_state]&.is_execution_traced?
415
424
  proc do
416
425
  begin
417
426
  if current_txn
@@ -20,14 +20,14 @@ module NewRelic
20
20
  # after its parent. We will use the optimized exclusive duration
21
21
  # calculation in all other cases.
22
22
  #
23
- attr_reader :start_time, :end_time, :duration, :exclusive_duration, :guid, :starting_thread_id
23
+ attr_reader :start_time, :end_time, :duration, :exclusive_duration, :guid, :starting_segment_key
24
24
  attr_accessor :name, :parent, :children_time, :transaction, :transaction_name
25
25
  attr_writer :record_metrics, :record_scoped_metric, :record_on_finish
26
26
  attr_reader :noticed_error
27
27
 
28
28
  def initialize(name = nil, start_time = nil)
29
29
  @name = name
30
- @starting_thread_id = ::Thread.current.object_id
30
+ @starting_segment_key = NewRelic::Agent::Tracer.current_segment_key
31
31
  @transaction_name = nil
32
32
  @transaction = nil
33
33
  @guid = NewRelic::Agent::GuidGenerator.generate_guid
@@ -35,8 +35,8 @@ module NewRelic
35
35
 
36
36
  def segment_complete(segment)
37
37
  # if parent was in another thread, remove the current_segment entry for this thread
38
- if segment.parent && segment.parent.starting_thread_id != ::Thread.current.object_id
39
- remove_current_segment_by_thread_id(::Thread.current.object_id)
38
+ if segment.parent && segment.parent.starting_segment_key != NewRelic::Agent::Tracer.current_segment_key
39
+ remove_current_segment_by_thread_id(NewRelic::Agent::Tracer.current_segment_key)
40
40
  else
41
41
  set_current_segment(segment.parent)
42
42
  end
@@ -53,9 +53,6 @@ module NewRelic
53
53
 
54
54
  JRUBY_CPU_TIME_ERROR = "Error calculating JRuby CPU Time"
55
55
 
56
- # reference to the transaction state managing this transaction
57
- attr_accessor :state
58
-
59
56
  # A Time instance for the start time, never nil
60
57
  attr_accessor :start_time
61
58
 
@@ -121,7 +118,6 @@ module NewRelic
121
118
  def self.start_new_transaction(state, category, options)
122
119
  txn = Transaction.new(category, options)
123
120
  state.reset(txn)
124
- txn.state = state
125
121
  txn.start(options)
126
122
  txn
127
123
  end
@@ -248,6 +244,7 @@ module NewRelic
248
244
  @priority = nil
249
245
 
250
246
  @starting_thread_id = Thread.current.object_id
247
+ @starting_segment_key = current_segment_key
251
248
 
252
249
  @attributes = Attributes.new(NewRelic::Agent.instance.attribute_filter)
253
250
 
@@ -260,20 +257,26 @@ module NewRelic
260
257
  end
261
258
  end
262
259
 
263
- def parent_thread_id
264
- ::Thread.current.nr_parent_thread_id if ::Thread.current.respond_to?(:nr_parent_thread_id)
260
+ def state
261
+ NewRelic::Agent::Tracer.state
265
262
  end
266
263
 
267
- def current_segment
268
- current_thread_id = ::Thread.current.object_id
269
- return current_segment_by_thread[current_thread_id] if current_segment_by_thread[current_thread_id]
270
- return current_segment_by_thread[parent_thread_id] if current_segment_by_thread[parent_thread_id]
264
+ def current_segment_key
265
+ Tracer.current_segment_key
266
+ end
271
267
 
272
- current_segment_by_thread[@starting_thread_id]
268
+ def parent_segment_key
269
+ (::Fiber.current.nr_parent_key if ::Fiber.current.respond_to?(:nr_parent_key)) || (::Thread.current.nr_parent_key if ::Thread.current.respond_to?(:nr_parent_key))
270
+ end
271
+
272
+ def current_segment
273
+ current_segment_by_thread[current_segment_key] ||
274
+ current_segment_by_thread[parent_segment_key] ||
275
+ current_segment_by_thread[@starting_segment_key]
273
276
  end
274
277
 
275
278
  def set_current_segment(new_segment)
276
- @current_segment_lock.synchronize { current_segment_by_thread[::Thread.current.object_id] = new_segment }
279
+ @current_segment_lock.synchronize { current_segment_by_thread[current_segment_key] = new_segment }
277
280
  end
278
281
 
279
282
  def remove_current_segment_by_thread_id(id)
@@ -359,10 +362,8 @@ module NewRelic
359
362
  def set_overriding_transaction_name(name, category)
360
363
  return log_frozen_name(name) if name_frozen?
361
364
 
362
- if influences_transaction_name?(category)
363
- self.overridden_name = name
364
- @category = category if category
365
- end
365
+ self.overridden_name = name
366
+ @category = category if category
366
367
  end
367
368
 
368
369
  def log_frozen_name(name)