newrelic_rpm 9.2.0 → 9.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/.build_ignore +26 -0
  3. data/CHANGELOG.md +197 -2
  4. data/README.md +8 -4
  5. data/lib/new_relic/agent/attribute_pre_filtering.rb +109 -0
  6. data/lib/new_relic/agent/configuration/default_source.rb +218 -63
  7. data/lib/new_relic/agent/configuration/environment_source.rb +1 -1
  8. data/lib/new_relic/agent/configuration/manager.rb +14 -0
  9. data/lib/new_relic/agent/configuration/yaml_source.rb +13 -0
  10. data/lib/new_relic/agent/distributed_tracing.rb +1 -1
  11. data/lib/new_relic/agent/error_collector.rb +1 -1
  12. data/lib/new_relic/agent/instrumentation/action_controller_other_subscriber.rb +1 -1
  13. data/lib/new_relic/agent/instrumentation/active_record.rb +1 -1
  14. data/lib/new_relic/agent/instrumentation/active_record_notifications.rb +2 -1
  15. data/lib/new_relic/agent/instrumentation/active_support_logger/instrumentation.rb +4 -0
  16. data/lib/new_relic/agent/instrumentation/bunny/instrumentation.rb +9 -0
  17. data/lib/new_relic/agent/instrumentation/concurrent_ruby/chain.rb +1 -1
  18. data/lib/new_relic/agent/instrumentation/concurrent_ruby/instrumentation.rb +3 -4
  19. data/lib/new_relic/agent/instrumentation/concurrent_ruby/prepend.rb +1 -1
  20. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +1 -2
  21. data/lib/new_relic/agent/instrumentation/curb/instrumentation.rb +4 -0
  22. data/lib/new_relic/agent/instrumentation/delayed_job/instrumentation.rb +3 -0
  23. data/lib/new_relic/agent/instrumentation/elasticsearch/instrumentation.rb +4 -1
  24. data/lib/new_relic/agent/instrumentation/excon/middleware.rb +3 -0
  25. data/lib/new_relic/agent/instrumentation/fiber/chain.rb +10 -3
  26. data/lib/new_relic/agent/instrumentation/fiber/instrumentation.rb +1 -2
  27. data/lib/new_relic/agent/instrumentation/fiber/prepend.rb +10 -3
  28. data/lib/new_relic/agent/instrumentation/grape/instrumentation.rb +4 -0
  29. data/lib/new_relic/agent/instrumentation/grpc/client/instrumentation.rb +4 -0
  30. data/lib/new_relic/agent/instrumentation/grpc/server/instrumentation.rb +4 -0
  31. data/lib/new_relic/agent/instrumentation/grpc_client.rb +1 -1
  32. data/lib/new_relic/agent/instrumentation/grpc_server.rb +1 -1
  33. data/lib/new_relic/agent/instrumentation/httpclient/instrumentation.rb +4 -0
  34. data/lib/new_relic/agent/instrumentation/httprb/instrumentation.rb +4 -0
  35. data/lib/new_relic/agent/instrumentation/logger/instrumentation.rb +3 -0
  36. data/lib/new_relic/agent/instrumentation/memcache/instrumentation.rb +12 -3
  37. data/lib/new_relic/agent/instrumentation/memcache.rb +2 -2
  38. data/lib/new_relic/agent/instrumentation/net_http/instrumentation.rb +4 -0
  39. data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +4 -0
  40. data/lib/new_relic/agent/instrumentation/padrino/instrumentation.rb +4 -0
  41. data/lib/new_relic/agent/instrumentation/queue_time.rb +1 -1
  42. data/lib/new_relic/agent/instrumentation/rack/instrumentation.rb +6 -0
  43. data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +4 -0
  44. data/lib/new_relic/agent/instrumentation/rails_notifications/action_cable.rb +1 -1
  45. data/lib/new_relic/agent/instrumentation/rake/instrumentation.rb +4 -0
  46. data/lib/new_relic/agent/instrumentation/redis/instrumentation.rb +4 -0
  47. data/lib/new_relic/agent/instrumentation/resque/instrumentation.rb +4 -0
  48. data/lib/new_relic/agent/instrumentation/roda/chain.rb +43 -0
  49. data/lib/new_relic/agent/instrumentation/roda/instrumentation.rb +56 -0
  50. data/lib/new_relic/agent/instrumentation/roda/prepend.rb +24 -0
  51. data/lib/new_relic/agent/instrumentation/roda/roda_transaction_namer.rb +30 -0
  52. data/lib/new_relic/agent/instrumentation/roda.rb +34 -0
  53. data/lib/new_relic/agent/instrumentation/sequel.rb +1 -1
  54. data/lib/new_relic/agent/instrumentation/sidekiq/client.rb +4 -0
  55. data/lib/new_relic/agent/instrumentation/sidekiq/server.rb +26 -3
  56. data/lib/new_relic/agent/instrumentation/sidekiq.rb +2 -2
  57. data/lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb +4 -0
  58. data/lib/new_relic/agent/instrumentation/stripe.rb +28 -0
  59. data/lib/new_relic/agent/instrumentation/stripe_subscriber.rb +77 -0
  60. data/lib/new_relic/agent/instrumentation/thread/chain.rb +1 -1
  61. data/lib/new_relic/agent/instrumentation/thread/instrumentation.rb +0 -1
  62. data/lib/new_relic/agent/instrumentation/thread/prepend.rb +1 -1
  63. data/lib/new_relic/agent/instrumentation/tilt/instrumentation.rb +4 -0
  64. data/lib/new_relic/agent/instrumentation/typhoeus/instrumentation.rb +5 -1
  65. data/lib/new_relic/agent/log_event_aggregator.rb +49 -2
  66. data/lib/new_relic/agent/log_event_attributes.rb +115 -0
  67. data/lib/new_relic/agent/logging.rb +4 -4
  68. data/lib/new_relic/agent/method_tracer_helpers.rb +26 -5
  69. data/lib/new_relic/agent/new_relic_service.rb +33 -17
  70. data/lib/new_relic/agent/pipe_service.rb +1 -1
  71. data/lib/new_relic/agent/tracer.rb +7 -6
  72. data/lib/new_relic/agent/transaction/abstract_segment.rb +52 -0
  73. data/lib/new_relic/agent/transaction/request_attributes.rb +45 -7
  74. data/lib/new_relic/agent/transaction/tracing.rb +6 -0
  75. data/lib/new_relic/agent/transaction.rb +9 -4
  76. data/lib/new_relic/agent/utilization/vendor.rb +5 -7
  77. data/lib/new_relic/agent.rb +50 -1
  78. data/lib/new_relic/cli/command.rb +1 -0
  79. data/lib/new_relic/control/class_methods.rb +1 -7
  80. data/lib/new_relic/control/frameworks/roda.rb +20 -0
  81. data/lib/new_relic/control/instrumentation.rb +0 -14
  82. data/lib/new_relic/dependency_detection.rb +16 -1
  83. data/lib/new_relic/language_support.rb +5 -0
  84. data/lib/new_relic/latest_changes.rb +1 -1
  85. data/lib/new_relic/noticed_error.rb +5 -2
  86. data/lib/new_relic/rack/agent_hooks.rb +1 -1
  87. data/lib/new_relic/rack/agent_middleware.rb +0 -16
  88. data/lib/new_relic/rack/browser_monitoring.rb +1 -1
  89. data/lib/new_relic/supportability_helper.rb +2 -0
  90. data/lib/new_relic/traced_thread.rb +2 -3
  91. data/lib/new_relic/version.rb +1 -1
  92. data/lib/sequel/extensions/new_relic_instrumentation.rb +1 -1
  93. data/lib/tasks/bump_version.rake +21 -0
  94. data/lib/tasks/config.rake +3 -2
  95. data/lib/tasks/helpers/config.html.erb +93 -0
  96. data/lib/tasks/helpers/format.rb +11 -7
  97. data/lib/tasks/helpers/newrelicyml.rb +144 -0
  98. data/lib/tasks/helpers/version_bump.rb +62 -0
  99. data/lib/tasks/newrelicyml.rake +13 -0
  100. data/newrelic.yml +364 -267
  101. data/newrelic_rpm.gemspec +11 -7
  102. metadata +36 -25
  103. data/.gitignore +0 -43
  104. data/.project +0 -23
  105. data/.rubocop.yml +0 -1845
  106. data/.rubocop_todo.yml +0 -61
  107. data/.simplecov +0 -16
  108. data/.snyk +0 -11
  109. data/.yardopts +0 -27
  110. data/Brewfile +0 -13
  111. data/DOCKER.md +0 -167
  112. data/Dockerfile +0 -10
  113. data/Guardfile +0 -27
  114. data/config/database.yml +0 -5
  115. data/config.dot +0 -278
  116. data/docker-compose.yml +0 -107
  117. data/lefthook.yml +0 -9
  118. data/lib/tasks/helpers/removers.rb +0 -33
  119. data/lib/tasks/multiverse.rake +0 -6
  120. data/lib/tasks/multiverse.rb +0 -84
@@ -101,7 +101,7 @@ module NewRelic
101
101
  end
102
102
  else
103
103
  ::NewRelic::Agent.logger.info("#{environment_key} does not have a corresponding configuration setting (#{config_key} does not exist).")
104
- ::NewRelic::Agent.logger.info('Run `rake newrelic:config:docs` or visit https://newrelic.com/docs/ruby/ruby-agent-configuration to see a list of available configuration settings.')
104
+ ::NewRelic::Agent.logger.info('Run `rake newrelic:config:docs` or visit https://docs.newrelic.com/docs/apm/agents/ruby-agent/configuration/ruby-agent-configuration to see a list of available configuration settings.')
105
105
  self[config_key] = value
106
106
  end
107
107
  end
@@ -15,6 +15,8 @@ module NewRelic
15
15
  module Agent
16
16
  module Configuration
17
17
  class Manager
18
+ DEPENDENCY_DETECTION_VALUES = %i[prepend chain unsatisfied].freeze
19
+
18
20
  # Defining these explicitly saves object allocations that we incur
19
21
  # if we use Forwardable and def_delegators.
20
22
  def [](key)
@@ -357,7 +359,19 @@ module NewRelic
357
359
  reset_cache
358
360
  end
359
361
 
362
+ # reset the configuration hash, but do not replace previously auto
363
+ # determined dependency detection values with nil or 'auto'
360
364
  def reset_cache
365
+ return new_cache unless defined?(@cache) && @cache
366
+
367
+ preserved = @cache.select { |_k, v| DEPENDENCY_DETECTION_VALUES.include?(v) }
368
+ new_cache
369
+ preserved.each { |k, v| @cache[k] = v }
370
+
371
+ @cache
372
+ end
373
+
374
+ def new_cache
361
375
  @cache = Hash.new { |hash, key| hash[key] = self.fetch(key) }
362
376
  end
363
377
 
@@ -41,6 +41,7 @@ module NewRelic
41
41
 
42
42
  substitute_transaction_threshold(config)
43
43
  booleanify_values(config, 'agent_enabled', 'enabled')
44
+ apply_aliases(config)
44
45
 
45
46
  super(config, true)
46
47
  end
@@ -165,6 +166,18 @@ module NewRelic
165
166
  end
166
167
  result
167
168
  end
169
+
170
+ def apply_aliases(config)
171
+ DEFAULTS.each do |config_setting, value|
172
+ next unless value[:aliases]
173
+
174
+ value[:aliases].each do |config_alias|
175
+ next unless config[config_setting].nil? && !config[config_alias.to_s].nil?
176
+
177
+ config[config_setting] = config[config_alias.to_s]
178
+ end
179
+ end
180
+ end
168
181
  end
169
182
  end
170
183
  end
@@ -87,7 +87,7 @@ module NewRelic
87
87
  # header-friendly string returned from
88
88
  # {DistributedTracePayload#http_safe}
89
89
  #
90
- # @param transport_Type [String] May be one of: +HTTP+, +HTTPS+, +Kafka+, +JMS+,
90
+ # @param transport_type [String] May be one of: +HTTP+, +HTTPS+, +Kafka+, +JMS+,
91
91
  # +IronMQ+, +AMQP+, +Queue+, +Other+. Values are
92
92
  # case sensitive. All other values result in +Unknown+
93
93
  #
@@ -277,7 +277,7 @@ module NewRelic
277
277
  noticed_error.line_number = sense_method(exception, :line_number)
278
278
  noticed_error.stack_trace = truncate_trace(extract_stack_trace(exception))
279
279
 
280
- noticed_error.expected = !options.delete(:expected).nil? || expected?(exception)
280
+ noticed_error.expected = !!options.delete(:expected) || expected?(exception) # rubocop:disable Style/DoubleNegation
281
281
 
282
282
  noticed_error.attributes_from_notice_error = options.delete(:custom_params) || {}
283
283
 
@@ -23,7 +23,7 @@ module NewRelic
23
23
 
24
24
  def metric_name(name, payload)
25
25
  controller_name = controller_name_for_metric(payload)
26
- "Ruby/ActionController#{"/#{controller_name}" if controller_name}/#{name.gsub(/\.action_controller/, '')}"
26
+ "Ruby/ActionController#{"/#{controller_name}" if controller_name}/#{name.gsub('.action_controller', '')}"
27
27
  end
28
28
 
29
29
  def controller_name_for_metric(payload)
@@ -148,7 +148,7 @@ DependencyDetection.defer do
148
148
  end
149
149
 
150
150
  depends_on do
151
- !NewRelic::Agent.config[:disable_activerecord_instrumentation]
151
+ !NewRelic::Agent.config[:disable_active_record_instrumentation]
152
152
  end
153
153
 
154
154
  executes do
@@ -90,7 +90,8 @@ DependencyDetection.defer do
90
90
  end
91
91
 
92
92
  depends_on do
93
- !NewRelic::Agent.config[:disable_activerecord_instrumentation] &&
93
+ !NewRelic::Agent.config[:disable_active_record_instrumentation] &&
94
+ !NewRelic::Agent.config[:disable_active_record_notifications] &&
94
95
  !NewRelic::Agent::Instrumentation::ActiveRecordSubscriber.subscribed?
95
96
  end
96
97
 
@@ -6,8 +6,12 @@ module NewRelic
6
6
  module Agent
7
7
  module Instrumentation
8
8
  module ActiveSupportLogger
9
+ INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
10
+
9
11
  # Mark @skip_instrumenting on any broadcasted loggers to instrument Rails.logger only
10
12
  def broadcast_with_tracing(logger)
13
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
14
+
11
15
  NewRelic::Agent::Instrumentation::Logger.mark_skip_instrumenting(logger)
12
16
  yield
13
17
  rescue => error
@@ -12,6 +12,7 @@ module NewRelic
12
12
  DEFAULT_NAME = 'Default'
13
13
  DEFAULT_TYPE = :direct
14
14
  SLASH = '/'
15
+ INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
15
16
 
16
17
  def exchange_name(name)
17
18
  name.empty? ? DEFAULT_NAME : name
@@ -28,6 +29,8 @@ module NewRelic
28
29
  include Bunny
29
30
 
30
31
  def publish_with_tracing(payload, opts = {})
32
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
33
+
31
34
  begin
32
35
  destination = exchange_name(name)
33
36
 
@@ -62,6 +65,8 @@ module NewRelic
62
65
  include Bunny
63
66
 
64
67
  def pop_with_tracing
68
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
69
+
65
70
  bunny_error, delivery_info, message_properties, _payload = nil, nil, nil, nil
66
71
  begin
67
72
  t0 = Process.clock_gettime(Process::CLOCK_REALTIME)
@@ -104,6 +109,8 @@ module NewRelic
104
109
  end
105
110
 
106
111
  def purge_with_tracing
112
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
113
+
107
114
  begin
108
115
  type = server_named? ? :temporary_queue : :queue
109
116
  segment = NewRelic::Agent::Tracer.start_message_broker_segment(
@@ -129,6 +136,8 @@ module NewRelic
129
136
  include Bunny
130
137
 
131
138
  def call_with_tracing(*args)
139
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
140
+
132
141
  delivery_info, message_properties, _ = args
133
142
  queue_name = queue.respond_to?(:name) ? queue.name : queue
134
143
 
@@ -13,7 +13,7 @@ module NewRelic::Agent::Instrumentation
13
13
  def post(*args, &task)
14
14
  return post_without_new_relic(*args, &task) unless NewRelic::Agent::Tracer.tracing_enabled?
15
15
 
16
- traced_task = add_task_tracing(*args, &task)
16
+ traced_task = add_task_tracing(&task)
17
17
  post_without_new_relic(*args, &traced_task)
18
18
  end
19
19
  end
@@ -5,13 +5,12 @@
5
5
  module NewRelic::Agent::Instrumentation
6
6
  module ConcurrentRuby
7
7
  SEGMENT_NAME = 'Concurrent/Task'
8
- SUPPORTABILITY_METRIC = 'Supportability/ConcurrentRuby/Invoked'
8
+ INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
9
9
 
10
- def add_task_tracing(*args, &task)
11
- NewRelic::Agent.record_metric_once(SUPPORTABILITY_METRIC)
10
+ def add_task_tracing(&task)
11
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
12
12
 
13
13
  NewRelic::Agent::Tracer.thread_block_with_current_transaction(
14
- *args,
15
14
  segment_name: SEGMENT_NAME,
16
15
  parent: NewRelic::Agent::Tracer.current_segment,
17
16
  &task
@@ -10,7 +10,7 @@ module NewRelic::Agent::Instrumentation
10
10
  def post(*args, &task)
11
11
  return super(*args, &task) unless NewRelic::Agent::Tracer.tracing_enabled?
12
12
 
13
- traced_task = add_task_tracing(*args, &task)
13
+ traced_task = add_task_tracing(&task)
14
14
  super(*args, &traced_task)
15
15
  end
16
16
  end
@@ -41,8 +41,6 @@ module NewRelic
41
41
  clazz.extend(ClassMethodsShim)
42
42
  end
43
43
 
44
- def new_relic_trace_controller_action(*args); yield; end
45
-
46
44
  def perform_action_with_newrelic_trace(*args); yield; end
47
45
  end
48
46
 
@@ -245,6 +243,7 @@ module NewRelic
245
243
  when :background then ::NewRelic::Agent::Transaction::TASK_PREFIX
246
244
  when :rack then ::NewRelic::Agent::Transaction::RACK_PREFIX
247
245
  when :uri then ::NewRelic::Agent::Transaction::CONTROLLER_PREFIX
246
+ when :roda then ::NewRelic::Agent::Transaction::RODA_PREFIX
248
247
  when :sinatra then ::NewRelic::Agent::Transaction::SINATRA_PREFIX
249
248
  when :middleware then ::NewRelic::Agent::Transaction::MIDDLEWARE_PREFIX
250
249
  when :grape then ::NewRelic::Agent::Transaction::GRAPE_PREFIX
@@ -68,6 +68,8 @@ module NewRelic
68
68
  module Multi
69
69
  include NewRelic::Agent::MethodTracer
70
70
 
71
+ INSTRUMENTATION_NAME = 'Curb'
72
+
71
73
  # Add CAT with callbacks if the request is serial
72
74
  def add_with_tracing(curl)
73
75
  if curl.respond_to?(:_nr_serial) && curl._nr_serial
@@ -81,6 +83,8 @@ module NewRelic
81
83
  def perform_with_tracing
82
84
  return yield if first_request_is_serial?
83
85
 
86
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
87
+
84
88
  trace_execution_scoped('External/Multiple/Curb::Multi/perform') do
85
89
  yield
86
90
  end
@@ -31,8 +31,11 @@ module NewRelic
31
31
  include NewRelic::Agent::Instrumentation::ControllerInstrumentation
32
32
 
33
33
  NR_TRANSACTION_CATEGORY = 'OtherTransaction/DelayedJob'.freeze
34
+ INSTRUMENTATION_NAME = 'DelayedJob'
34
35
 
35
36
  def invoke_job_with_tracing
37
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
38
+
36
39
  options = {
37
40
  :category => NR_TRANSACTION_CATEGORY,
38
41
  :path => ::NewRelic::Agent::Instrumentation::DelayedJob::Naming.name_from_payload(payload_object)
@@ -8,15 +8,18 @@ module NewRelic::Agent::Instrumentation
8
8
  module Elasticsearch
9
9
  PRODUCT_NAME = 'Elasticsearch'
10
10
  OPERATION = 'perform_request'
11
+ INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
11
12
 
12
13
  def perform_request_with_tracing(method, path, params = {}, body = nil, headers = nil)
13
14
  return yield unless NewRelic::Agent::Tracer.tracing_enabled?
14
15
 
16
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
17
+
15
18
  segment = NewRelic::Agent::Tracer.start_datastore_segment(
16
19
  product: PRODUCT_NAME,
17
20
  operation: nr_operation || OPERATION,
18
21
  host: nr_hosts[:host],
19
- port_path_or_id: path,
22
+ port_path_or_id: nr_hosts[:port],
20
23
  database_name: nr_cluster_name
21
24
  )
22
25
  begin
@@ -6,6 +6,7 @@ module ::Excon
6
6
  module Middleware
7
7
  class NewRelicCrossAppTracing
8
8
  TRACE_DATA_IVAR = :@newrelic_trace_data
9
+ INSTRUMENTATION_NAME = 'Excon'
9
10
 
10
11
  def initialize(stack)
11
12
  @stack = stack
@@ -18,6 +19,8 @@ module ::Excon
18
19
  # :idempotent in the options, but there will be only a single
19
20
  # accompanying response_call/error_call.
20
21
  if datum[:connection] && !datum[:connection].instance_variable_get(TRACE_DATA_IVAR)
22
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
23
+
21
24
  wrapped_request = ::NewRelic::Agent::HTTPClients::ExconHTTPRequest.new(datum)
22
25
  segment = NewRelic::Agent::Tracer.start_external_request_segment(
23
26
  library: wrapped_request.type,
@@ -10,9 +10,16 @@ module NewRelic::Agent::Instrumentation
10
10
 
11
11
  alias_method(:initialize_without_new_relic, :initialize)
12
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) }
13
+ if RUBY_VERSION < '2.7.0'
14
+ def initialize(*_args, &block)
15
+ traced_block = add_thread_tracing(&block)
16
+ initialize_with_newrelic_tracing { initialize_without_new_relic(&traced_block) }
17
+ end
18
+ else
19
+ def initialize(**kwargs, &block)
20
+ traced_block = add_thread_tracing(&block)
21
+ initialize_with_newrelic_tracing { initialize_without_new_relic(**kwargs, &traced_block) }
22
+ end
16
23
  end
17
24
  end
18
25
  end
@@ -11,11 +11,10 @@ module NewRelic::Agent::Instrumentation
11
11
  yield
12
12
  end
13
13
 
14
- def add_thread_tracing(*args, &block)
14
+ def add_thread_tracing(&block)
15
15
  return block if !NewRelic::Agent::Tracer.thread_tracing_enabled?
16
16
 
17
17
  NewRelic::Agent::Tracer.thread_block_with_current_transaction(
18
- *args,
19
18
  segment_name: 'Ruby/Fiber',
20
19
  &block
21
20
  )
@@ -9,9 +9,16 @@ module NewRelic::Agent::Instrumentation
9
9
  module Prepend
10
10
  include NewRelic::Agent::Instrumentation::MonitoredFiber
11
11
 
12
- def initialize(*args, &block)
13
- traced_block = add_thread_tracing(*args, &block)
14
- initialize_with_newrelic_tracing { super(*args, &traced_block) }
12
+ if RUBY_VERSION < '2.7.0'
13
+ def initialize(*_args, &block)
14
+ traced_block = add_thread_tracing(&block)
15
+ initialize_with_newrelic_tracing { super(&traced_block) }
16
+ end
17
+ else
18
+ def initialize(**kawrgs, &block)
19
+ traced_block = add_thread_tracing(&block)
20
+ initialize_with_newrelic_tracing { super(**kawrgs, &traced_block) }
21
+ end
15
22
  end
16
23
  end
17
24
  end
@@ -9,6 +9,8 @@ module NewRelic::Agent::Instrumentation
9
9
  module Instrumentation
10
10
  extend self
11
11
 
12
+ INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
13
+
12
14
  # Since 1.2.0, the class `Grape::API` no longer refers to an API instance, rather, what used to be `Grape::API` is `Grape::API::Instance`
13
15
  # https://github.com/ruby-grape/grape/blob/c20a73ac1e3f3ba1082005ed61bf69452373ba87/UPGRADING.md#upgrading-to--120
14
16
  def instrumented_class
@@ -46,6 +48,8 @@ module NewRelic::Agent::Instrumentation
46
48
  def handle_transaction(endpoint, class_name, version)
47
49
  return unless endpoint && route = endpoint.route
48
50
 
51
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
52
+
49
53
  name_transaction(route, class_name, version)
50
54
  capture_params(endpoint)
51
55
  end
@@ -12,10 +12,14 @@ module NewRelic
12
12
  module Client
13
13
  include NewRelic::Agent::Instrumentation::GRPC::Helper
14
14
 
15
+ INSTRUMENTATION_NAME = 'gRPC_Client'
16
+
15
17
  def issue_request_with_tracing(grpc_type, method, requests, marshal, unmarshal,
16
18
  deadline:, return_op:, parent:, credentials:, metadata:)
17
19
  return yield unless trace_with_newrelic?
18
20
 
21
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
22
+
19
23
  segment = request_segment(method)
20
24
  request_wrapper = NewRelic::Agent::Instrumentation::GRPC::Client::RequestWrapper.new(@host)
21
25
  # do not insert CAT headers for gRPC requests https://github.com/newrelic/newrelic-ruby-agent/issues/1730
@@ -11,6 +11,8 @@ module NewRelic
11
11
  module Server
12
12
  include NewRelic::Agent::Instrumentation::GRPC::Helper
13
13
 
14
+ INSTRUMENTATION_NAME = 'gRPC_Server'
15
+
14
16
  DT_KEYS = [NewRelic::NEWRELIC_KEY, NewRelic::TRACEPARENT_KEY, NewRelic::TRACESTATE_KEY].freeze
15
17
  INSTANCE_VAR_HOST = :@host_nr
16
18
  INSTANCE_VAR_PORT = :@port_nr
@@ -23,6 +25,8 @@ module NewRelic
23
25
  def handle_with_tracing(streamer_type, active_call, mth, _inter_ctx)
24
26
  return yield unless trace_with_newrelic?
25
27
 
28
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
29
+
26
30
  metadata = metadata_for_call(active_call)
27
31
  txn = NewRelic::Agent::Transaction.start_new_transaction(NewRelic::Agent::Tracer.state,
28
32
  CATEGORY,
@@ -13,7 +13,7 @@ DependencyDetection.defer do
13
13
  end
14
14
 
15
15
  executes do
16
- supportability_name = 'gRPC_Client'
16
+ supportability_name = NewRelic::Agent::Instrumentation::GRPC::Client::INSTRUMENTATION_NAME
17
17
  if use_prepend?
18
18
  prepend_instrument GRPC::ClientStub, NewRelic::Agent::Instrumentation::GRPC::Client::Prepend, supportability_name
19
19
  else
@@ -14,7 +14,7 @@ DependencyDetection.defer do
14
14
  end
15
15
 
16
16
  executes do
17
- supportability_name = 'gRPC_Server'
17
+ supportability_name = NewRelic::Agent::Instrumentation::GRPC::Client::INSTRUMENTATION_NAME
18
18
  if use_prepend?
19
19
  prepend_instrument GRPC::RpcServer, NewRelic::Agent::Instrumentation::GRPC::Server::RpcServerPrepend, supportability_name
20
20
  prepend_instrument GRPC::RpcDesc, NewRelic::Agent::Instrumentation::GRPC::Server::RpcDescPrepend, supportability_name
@@ -5,7 +5,11 @@
5
5
  module NewRelic::Agent::Instrumentation
6
6
  module HTTPClient
7
7
  module Instrumentation
8
+ INSTRUMENTATION_NAME = 'HTTPClient'
9
+
8
10
  def with_tracing(request, connection)
11
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
12
+
9
13
  wrapped_request = NewRelic::Agent::HTTPClients::HTTPClientRequest.new(request)
10
14
  segment = NewRelic::Agent::Tracer.start_external_request_segment(
11
15
  library: wrapped_request.type,
@@ -4,7 +4,11 @@
4
4
 
5
5
  module NewRelic::Agent::Instrumentation
6
6
  module HTTPrb
7
+ INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
8
+
7
9
  def with_tracing(request)
10
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
11
+
8
12
  wrapped_request = ::NewRelic::Agent::HTTPClients::HTTPRequest.new(request)
9
13
 
10
14
  begin
@@ -6,6 +6,8 @@ module NewRelic
6
6
  module Agent
7
7
  module Instrumentation
8
8
  module Logger
9
+ INSTRUMENTATION_NAME = 'Logger'
10
+
9
11
  def skip_instrumenting?
10
12
  defined?(@skip_instrumenting) && @skip_instrumenting
11
13
  end
@@ -51,6 +53,7 @@ module NewRelic
51
53
  mark_skip_instrumenting
52
54
 
53
55
  unless ::NewRelic::Agent.agent.nil?
56
+ ::NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
54
57
  ::NewRelic::Agent.agent.log_event_aggregator.record(formatted_message, severity)
55
58
  formatted_message = LocalLogDecorator.decorate(formatted_message)
56
59
  end
@@ -10,9 +10,12 @@ module NewRelic::Agent::Instrumentation
10
10
  LOCALHOST = 'localhost'
11
11
  MULTIGET_METRIC_NAME = 'get_multi_request'
12
12
  MEMCACHED = 'Memcached'
13
+ INSTRUMENTATION_NAME = 'Dalli'
13
14
 
14
15
  def with_newrelic_tracing(operation, *args)
15
- segment = NewRelic::Agent::Tracer.start_datastore_segment( \
16
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
17
+
18
+ segment = NewRelic::Agent::Tracer.start_datastore_segment(
16
19
  product: MEMCACHED,
17
20
  operation: operation
18
21
  )
@@ -28,6 +31,8 @@ module NewRelic::Agent::Instrumentation
28
31
  end
29
32
 
30
33
  def server_for_key_with_newrelic_tracing
34
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
35
+
31
36
  yield.tap do |server|
32
37
  begin
33
38
  if txn = ::NewRelic::Agent::Tracer.current_transaction
@@ -43,7 +48,9 @@ module NewRelic::Agent::Instrumentation
43
48
  end
44
49
 
45
50
  def get_multi_with_newrelic_tracing(method_name)
46
- segment = NewRelic::Agent::Tracer.start_segment( \
51
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
52
+
53
+ segment = NewRelic::Agent::Tracer.start_segment(
47
54
  name: "Ruby/Memcached/Dalli/#{method_name}"
48
55
  )
49
56
 
@@ -55,7 +62,9 @@ module NewRelic::Agent::Instrumentation
55
62
  end
56
63
 
57
64
  def send_multiget_with_newrelic_tracing(keys)
58
- segment = ::NewRelic::Agent::Tracer.start_datastore_segment( \
65
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
66
+
67
+ segment = ::NewRelic::Agent::Tracer.start_datastore_segment(
59
68
  product: MEMCACHED,
60
69
  operation: MULTIGET_METRIC_NAME
61
70
  )
@@ -5,8 +5,8 @@
5
5
  # NOTE: there are multiple implementations of the Memcached client in Ruby,
6
6
  # each with slightly different APIs and semantics.
7
7
  # See:
8
- # http://www.deveiate.org/code/Ruby-MemCache/ (Gem: Ruby-MemCache)
9
- # http://seattlerb.rubyforge.org/memcache-client/ (Gem: memcache-client)
8
+ # https://rubygems.org/gems/Ruby-MemCache (Gem: Ruby-MemCache)
9
+ # https://github.com/mperham/memcache-client (Gem: memcache-client)
10
10
  # https://github.com/mperham/dalli (Gem: dalli)
11
11
 
12
12
  require_relative 'memcache/helper'
@@ -6,7 +6,11 @@ module NewRelic
6
6
  module Agent
7
7
  module Instrumentation
8
8
  module NetHTTP
9
+ INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
10
+
9
11
  def request_with_tracing(request)
12
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
13
+
10
14
  wrapped_request = NewRelic::Agent::HTTPClients::NetHTTPRequest.new(self, request)
11
15
 
12
16
  segment = NewRelic::Agent::Tracer.start_external_request_segment(
@@ -47,6 +47,10 @@ module NewRelic
47
47
  end
48
48
  end
49
49
 
50
+ # The agent doesn't use the traditional ActiveSupport::Notifications.subscribe
51
+ # pattern due to threading issues discovered on initial instrumentation.
52
+ # Instead we define a #start and #finish method, which Rails responds to.
53
+ # See: https://github.com/rails/rails/issues/12069
50
54
  def start(name, id, payload)
51
55
  return unless state.is_execution_traced?
52
56
 
@@ -4,7 +4,11 @@
4
4
 
5
5
  module NewRelic::Agent::Instrumentation
6
6
  module Padrino
7
+ INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
8
+
7
9
  def invoke_route_with_tracing(*args)
10
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
11
+
8
12
  begin
9
13
  env['newrelic.last_route'] = args[0].original_path
10
14
  rescue => e
@@ -5,7 +5,7 @@
5
5
  module NewRelic
6
6
  module Agent
7
7
  module Instrumentation
8
- # https://newrelic.com/docs/features/tracking-front-end-time
8
+ # https://docs.newrelic.com/docs/features/tracking-front-end-time
9
9
  # Record queue time metrics based on any of three headers
10
10
  # which can be set on the request.
11
11
  module QueueTime
@@ -6,6 +6,8 @@ module NewRelic
6
6
  module Agent
7
7
  module Instrumentation
8
8
  module RackBuilder
9
+ INSTRUMENTATION_NAME = 'Rack'
10
+
9
11
  def self.track_deferred_detection(builder_class)
10
12
  class << builder_class
11
13
  attr_accessor :_nr_deferred_detection_ran
@@ -51,6 +53,8 @@ module NewRelic
51
53
  def run_with_tracing(app)
52
54
  return yield(app) unless middleware_instrumentation_enabled?
53
55
 
56
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
57
+
54
58
  yield(::NewRelic::Agent::Instrumentation::MiddlewareProxy.wrap(app, true))
55
59
  end
56
60
 
@@ -58,6 +62,8 @@ module NewRelic
58
62
  return if middleware_class.nil?
59
63
  return yield(middleware_class) unless middleware_instrumentation_enabled?
60
64
 
65
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
66
+
61
67
  yield(::NewRelic::Agent::Instrumentation::MiddlewareProxy.for_class(middleware_class))
62
68
  end
63
69
  end
@@ -9,6 +9,8 @@ module NewRelic
9
9
  module Instrumentation
10
10
  module Rails3
11
11
  module ActionController
12
+ INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
13
+
12
14
  # determine the path that is used in the metric name for
13
15
  # the called controller action
14
16
  def newrelic_metric_path(action_name_override = nil)
@@ -21,6 +23,8 @@ module NewRelic
21
23
  end
22
24
 
23
25
  def process_action(*args) # THREAD_LOCAL_ACCESS
26
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
27
+
24
28
  munged_params = NewRelic::Agent::ParameterFiltering.filter_rails_request_parameters(request.filtered_parameters)
25
29
  perform_action_with_newrelic_trace(:category => :controller,
26
30
  :name => self.action_name,
@@ -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(/\A(?:perform_action|transmit|broadcast)\.action_cable\z/,
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