newrelic_rpm 6.14.0 → 6.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +52 -2
  3. data/lib/new_relic/agent.rb +1 -0
  4. data/lib/new_relic/agent/agent.rb +2 -4
  5. data/lib/new_relic/agent/configuration/default_source.rb +13 -1
  6. data/lib/new_relic/agent/database_adapter.rb +33 -0
  7. data/lib/new_relic/agent/instrumentation/active_record_helper.rb +21 -68
  8. data/lib/new_relic/agent/instrumentation/active_record_prepend.rb +23 -57
  9. data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +0 -15
  10. data/lib/new_relic/agent/instrumentation/bunny.rb +27 -71
  11. data/lib/new_relic/agent/instrumentation/curb.rb +12 -30
  12. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +8 -21
  13. data/lib/new_relic/agent/instrumentation/net.rb +33 -57
  14. data/lib/new_relic/agent/instrumentation/net_prepend.rb +21 -53
  15. data/lib/new_relic/agent/instrumentation/padrino.rb +15 -37
  16. data/lib/new_relic/agent/instrumentation/rack.rb +6 -17
  17. data/lib/new_relic/agent/instrumentation/rake.rb +19 -53
  18. data/lib/new_relic/agent/instrumentation/redis.rb +59 -138
  19. data/lib/new_relic/agent/instrumentation/sidekiq.rb +1 -1
  20. data/lib/new_relic/agent/instrumentation/sinatra.rb +22 -62
  21. data/lib/new_relic/agent/span_event_primitive.rb +10 -8
  22. data/lib/new_relic/agent/transaction/abstract_segment.rb +1 -1
  23. data/lib/new_relic/agent/vm/mri_vm.rb +6 -4
  24. data/lib/new_relic/cli/commands/deployments.rb +0 -1
  25. data/lib/new_relic/dependency_detection.rb +4 -0
  26. data/lib/new_relic/environment_report.rb +1 -13
  27. data/lib/new_relic/supportability_helper.rb +1 -0
  28. data/lib/new_relic/version.rb +1 -1
  29. data/test/agent_helper.rb +1 -0
  30. metadata +3 -2
@@ -55,158 +55,79 @@ DependencyDetection.defer do
55
55
  Redis::Client.class_eval do
56
56
  alias_method :call_without_new_relic, :call
57
57
 
58
- if RUBY_VERSION < "2.7.0"
59
- def call(*args, &block)
60
- operation = args[0][0]
61
- statement = ::NewRelic::Agent::Datastores::Redis.format_command(args[0])
62
-
63
- hostname = NewRelic::Agent::Instrumentation::Redis.host_for(self)
64
- port_path_or_id = NewRelic::Agent::Instrumentation::Redis.port_path_or_id_for(self)
65
-
66
- segment = NewRelic::Agent::Tracer.start_datastore_segment(
67
- product: NewRelic::Agent::Datastores::Redis::PRODUCT_NAME,
68
- operation: operation,
69
- host: hostname,
70
- port_path_or_id: port_path_or_id,
71
- database_name: db
72
- )
73
- begin
74
- segment.notice_nosql_statement(statement) if statement
75
- NewRelic::Agent::Tracer.capture_segment_error segment do
76
- call_without_new_relic(*args, &block)
77
- end
78
- ensure
79
- segment.finish if segment
80
- end
81
- end
82
- else
83
- def call(*args, **kwargs, &block)
84
- operation = args[0][0]
85
- statement = ::NewRelic::Agent::Datastores::Redis.format_command(args[0])
86
-
87
- hostname = NewRelic::Agent::Instrumentation::Redis.host_for(self)
88
- port_path_or_id = NewRelic::Agent::Instrumentation::Redis.port_path_or_id_for(self)
89
-
90
- segment = NewRelic::Agent::Tracer.start_datastore_segment(
91
- product: NewRelic::Agent::Datastores::Redis::PRODUCT_NAME,
92
- operation: operation,
93
- host: hostname,
94
- port_path_or_id: port_path_or_id,
95
- database_name: db
96
- )
97
- begin
98
- segment.notice_nosql_statement(statement) if statement
99
- NewRelic::Agent::Tracer.capture_segment_error segment do
100
- call_without_new_relic(*args, **kwargs, &block)
101
- end
102
- ensure
103
- segment.finish if segment
58
+ def call(*args, &block)
59
+ operation = args[0][0]
60
+ statement = ::NewRelic::Agent::Datastores::Redis.format_command(args[0])
61
+
62
+ hostname = NewRelic::Agent::Instrumentation::Redis.host_for(self)
63
+ port_path_or_id = NewRelic::Agent::Instrumentation::Redis.port_path_or_id_for(self)
64
+
65
+ segment = NewRelic::Agent::Tracer.start_datastore_segment(
66
+ product: NewRelic::Agent::Datastores::Redis::PRODUCT_NAME,
67
+ operation: operation,
68
+ host: hostname,
69
+ port_path_or_id: port_path_or_id,
70
+ database_name: db
71
+ )
72
+ begin
73
+ segment.notice_nosql_statement(statement) if statement
74
+ NewRelic::Agent::Tracer.capture_segment_error segment do
75
+ call_without_new_relic(*args, &block)
104
76
  end
77
+ ensure
78
+ segment.finish if segment
105
79
  end
106
80
  end
107
-
108
-
109
-
81
+
110
82
  alias_method :call_pipeline_without_new_relic, :call_pipeline
111
83
 
112
- if RUBY_VERSION < "2.7.0"
113
- def call_pipeline(*args, &block)
114
- pipeline = args[0]
115
- operation = pipeline.is_a?(::Redis::Pipeline::Multi) ? NewRelic::Agent::Datastores::Redis::MULTI_OPERATION : NewRelic::Agent::Datastores::Redis::PIPELINE_OPERATION
116
- statement = ::NewRelic::Agent::Datastores::Redis.format_pipeline_commands(pipeline.commands)
117
-
118
- hostname = NewRelic::Agent::Instrumentation::Redis.host_for(self)
119
- port_path_or_id = NewRelic::Agent::Instrumentation::Redis.port_path_or_id_for(self)
120
-
121
- segment = NewRelic::Agent::Tracer.start_datastore_segment(
122
- product: NewRelic::Agent::Datastores::Redis::PRODUCT_NAME,
123
- operation: operation,
124
- host: hostname,
125
- port_path_or_id: port_path_or_id,
126
- database_name: db
127
- )
128
- begin
129
- segment.notice_nosql_statement(statement)
130
- NewRelic::Agent::Tracer.capture_segment_error segment do
131
- call_pipeline_without_new_relic(*args, &block)
132
- end
133
- ensure
134
- segment.finish if segment
135
- end
136
- end
137
- else
138
- def call_pipeline(*args, **kwargs, &block)
139
- pipeline = args[0]
140
- operation = pipeline.is_a?(::Redis::Pipeline::Multi) ? NewRelic::Agent::Datastores::Redis::MULTI_OPERATION : NewRelic::Agent::Datastores::Redis::PIPELINE_OPERATION
141
- statement = ::NewRelic::Agent::Datastores::Redis.format_pipeline_commands(pipeline.commands)
142
-
143
- hostname = NewRelic::Agent::Instrumentation::Redis.host_for(self)
144
- port_path_or_id = NewRelic::Agent::Instrumentation::Redis.port_path_or_id_for(self)
145
-
146
- segment = NewRelic::Agent::Tracer.start_datastore_segment(
147
- product: NewRelic::Agent::Datastores::Redis::PRODUCT_NAME,
148
- operation: operation,
149
- host: hostname,
150
- port_path_or_id: port_path_or_id,
151
- database_name: db
152
- )
153
- begin
154
- segment.notice_nosql_statement(statement)
155
- NewRelic::Agent::Tracer.capture_segment_error segment do
156
- call_pipeline_without_new_relic(*args, **kwargs, &block)
157
- end
158
- ensure
159
- segment.finish if segment
84
+ def call_pipeline(*args, &block)
85
+ pipeline = args[0]
86
+ operation = pipeline.is_a?(::Redis::Pipeline::Multi) ? NewRelic::Agent::Datastores::Redis::MULTI_OPERATION : NewRelic::Agent::Datastores::Redis::PIPELINE_OPERATION
87
+ statement = ::NewRelic::Agent::Datastores::Redis.format_pipeline_commands(pipeline.commands)
88
+
89
+ hostname = NewRelic::Agent::Instrumentation::Redis.host_for(self)
90
+ port_path_or_id = NewRelic::Agent::Instrumentation::Redis.port_path_or_id_for(self)
91
+
92
+ segment = NewRelic::Agent::Tracer.start_datastore_segment(
93
+ product: NewRelic::Agent::Datastores::Redis::PRODUCT_NAME,
94
+ operation: operation,
95
+ host: hostname,
96
+ port_path_or_id: port_path_or_id,
97
+ database_name: db
98
+ )
99
+ begin
100
+ segment.notice_nosql_statement(statement)
101
+ NewRelic::Agent::Tracer.capture_segment_error segment do
102
+ call_pipeline_without_new_relic(*args, &block)
160
103
  end
104
+ ensure
105
+ segment.finish if segment
161
106
  end
162
107
  end
163
108
 
164
109
  alias_method :connect_without_new_relic, :connect
165
110
 
166
- if RUBY_VERSION < "2.7.0"
167
- def connect(*args, &block)
168
- hostname = NewRelic::Agent::Instrumentation::Redis.host_for(self)
169
- port_path_or_id = NewRelic::Agent::Instrumentation::Redis.port_path_or_id_for(self)
170
-
171
- segment = NewRelic::Agent::Tracer.start_datastore_segment(
172
- product: NewRelic::Agent::Datastores::Redis::PRODUCT_NAME,
173
- operation: NewRelic::Agent::Datastores::Redis::CONNECT,
174
- host: hostname,
175
- port_path_or_id: port_path_or_id,
176
- database_name: db
177
- )
178
-
179
- begin
180
- NewRelic::Agent::Tracer.capture_segment_error segment do
181
- connect_without_new_relic(*args, &block)
182
- end
183
- ensure
184
- segment.finish if segment
185
- end
186
- end
187
- else
188
- def connect(*args, **kwargs, &block)
189
- hostname = NewRelic::Agent::Instrumentation::Redis.host_for(self)
190
- port_path_or_id = NewRelic::Agent::Instrumentation::Redis.port_path_or_id_for(self)
191
-
192
- segment = NewRelic::Agent::Tracer.start_datastore_segment(
193
- product: NewRelic::Agent::Datastores::Redis::PRODUCT_NAME,
194
- operation: NewRelic::Agent::Datastores::Redis::CONNECT,
195
- host: hostname,
196
- port_path_or_id: port_path_or_id,
197
- database_name: db
198
- )
199
-
200
- begin
201
- NewRelic::Agent::Tracer.capture_segment_error segment do
202
- connect_without_new_relic(*args, **kwargs, &block)
203
- end
204
- ensure
205
- segment.finish if segment
111
+ def connect(*args, &block)
112
+ hostname = NewRelic::Agent::Instrumentation::Redis.host_for(self)
113
+ port_path_or_id = NewRelic::Agent::Instrumentation::Redis.port_path_or_id_for(self)
114
+
115
+ segment = NewRelic::Agent::Tracer.start_datastore_segment(
116
+ product: NewRelic::Agent::Datastores::Redis::PRODUCT_NAME,
117
+ operation: NewRelic::Agent::Datastores::Redis::CONNECT,
118
+ host: hostname,
119
+ port_path_or_id: port_path_or_id,
120
+ database_name: db
121
+ )
122
+
123
+ begin
124
+ NewRelic::Agent::Tracer.capture_segment_error segment do
125
+ connect_without_new_relic(*args, &block)
206
126
  end
127
+ ensure
128
+ segment.finish if segment
207
129
  end
208
130
  end
209
-
210
131
  end
211
132
  end
212
133
  end
@@ -46,7 +46,7 @@ DependencyDetection.defer do
46
46
  end
47
47
  class Client
48
48
  def call(_worker_class, job, *_)
49
- job[NewRelic::NEWRELIC_KEY] = distributed_tracing_headers if ::NewRelic::Agent.config[:'distributed_tracing.enabled']
49
+ job[NewRelic::NEWRELIC_KEY] ||= distributed_tracing_headers if ::NewRelic::Agent.config[:'distributed_tracing.enabled']
50
50
  yield
51
51
  end
52
52
 
@@ -92,24 +92,13 @@ module NewRelic
92
92
  middlewares
93
93
  end
94
94
 
95
- if RUBY_VERSION < "2.7.0"
96
- def build_with_newrelic(*args, &block)
97
- unless NewRelic::Agent.config[:disable_sinatra_auto_middleware]
98
- newrelic_middlewares.each do |middleware_class|
99
- try_to_use(self, middleware_class)
100
- end
95
+ def build_with_newrelic(*args, &block)
96
+ unless NewRelic::Agent.config[:disable_sinatra_auto_middleware]
97
+ newrelic_middlewares.each do |middleware_class|
98
+ try_to_use(self, middleware_class)
101
99
  end
102
- build_without_newrelic(*args, &block)
103
- end
104
- else
105
- def build_with_newrelic(*args, **kwargs, &block)
106
- unless NewRelic::Agent.config[:disable_sinatra_auto_middleware]
107
- newrelic_middlewares.each do |middleware_class|
108
- try_to_use(self, middleware_class)
109
- end
110
- end
111
- build_without_newrelic(*args, **kwargs, &block)
112
100
  end
101
+ build_without_newrelic(*args, &block)
113
102
  end
114
103
 
115
104
  def try_to_use(app, clazz)
@@ -119,26 +108,14 @@ module NewRelic
119
108
  end
120
109
 
121
110
  # Capture last route we've seen. Will set for transaction on route_eval
122
- if RUBY_VERSION < "2.7.0"
123
- def process_route_with_newrelic(*args, &block)
124
- begin
125
- env["newrelic.last_route"] = args[0]
126
- rescue => e
127
- ::NewRelic::Agent.logger.debug("Failed determining last route in Sinatra", e)
128
- end
129
-
130
- process_route_without_newrelic(*args, &block)
131
- end
132
- else
133
- def process_route_with_newrelic(*args, **kwargs, &block)
134
- begin
135
- env["newrelic.last_route"] = args[0]
136
- rescue => e
137
- ::NewRelic::Agent.logger.debug("Failed determining last route in Sinatra", e)
138
- end
139
-
140
- process_route_without_newrelic(*args, **kwargs, &block)
111
+ def process_route_with_newrelic(*args, &block)
112
+ begin
113
+ env["newrelic.last_route"] = args[0]
114
+ rescue => e
115
+ ::NewRelic::Agent.logger.debug("Failed determining last route in Sinatra", e)
141
116
  end
117
+
118
+ process_route_without_newrelic(*args, &block)
142
119
  end
143
120
 
144
121
  # If a transaction name is already set, this call will tromple over it.
@@ -147,34 +124,18 @@ module NewRelic
147
124
  #
148
125
  # If we're ignored, this remains safe, since set_transaction_name
149
126
  # care for the gating on the transaction's existence for us.
150
- if RUBY_VERSION < "2.7.0"
151
- def route_eval_with_newrelic(*args, &block)
152
- begin
153
- txn_name = TransactionNamer.transaction_name_for_route(env, request)
154
- unless txn_name.nil?
155
- ::NewRelic::Agent::Transaction.set_default_transaction_name(
156
- "#{self.class.name}/#{txn_name}", :sinatra)
157
- end
158
- rescue => e
159
- ::NewRelic::Agent.logger.debug("Failed during route_eval to set transaction name", e)
160
- end
161
-
162
- route_eval_without_newrelic(*args, &block)
163
- end
164
- else
165
- def route_eval_with_newrelic(*args, **kwargs, &block)
166
- begin
167
- txn_name = TransactionNamer.transaction_name_for_route(env, request)
168
- unless txn_name.nil?
169
- ::NewRelic::Agent::Transaction.set_default_transaction_name(
170
- "#{self.class.name}/#{txn_name}", :sinatra)
171
- end
172
- rescue => e
173
- ::NewRelic::Agent.logger.debug("Failed during route_eval to set transaction name", e)
127
+ def route_eval_with_newrelic(*args, &block)
128
+ begin
129
+ txn_name = TransactionNamer.transaction_name_for_route(env, request)
130
+ unless txn_name.nil?
131
+ ::NewRelic::Agent::Transaction.set_default_transaction_name(
132
+ "#{self.class.name}/#{txn_name}", :sinatra)
174
133
  end
175
-
176
- route_eval_without_newrelic(*args, **kwargs, &block)
134
+ rescue => e
135
+ ::NewRelic::Agent.logger.debug("Failed during route_eval to set transaction name", e)
177
136
  end
137
+
138
+ route_eval_without_newrelic(*args, &block)
178
139
  end
179
140
 
180
141
  def dispatch_with_newrelic #THREAD_LOCAL_ACCESS
@@ -220,7 +181,6 @@ module NewRelic
220
181
  def ignore_enduser?
221
182
  Ignorer.should_ignore?(self, :enduser)
222
183
  end
223
-
224
184
  end
225
185
  end
226
186
  end
@@ -165,16 +165,18 @@ module NewRelic
165
165
  end
166
166
  end
167
167
 
168
+ def merge_and_freeze_attributes agent_attributes, error_attributes
169
+ return agent_attributes.freeze unless error_attributes
170
+ return error_attributes.freeze if agent_attributes.equal?(NewRelic::EMPTY_HASH)
171
+ agent_attributes.merge!(error_attributes).freeze
172
+ end
173
+
168
174
  def agent_attributes segment
169
- attributes = segment.attributes
170
- agent_attributes = attributes.agent_attributes_for(NewRelic::Agent::AttributeFilter::DST_SPAN_EVENTS)
175
+ agent_attributes = segment.attributes
176
+ .agent_attributes_for(NewRelic::Agent::AttributeFilter::DST_SPAN_EVENTS)
171
177
  error_attributes = error_attributes(segment)
172
- if agent_attributes || error_attributes
173
- agent_attributes.merge!(error_attributes) if error_attributes
174
- agent_attributes.freeze
175
- else
176
- NewRelic::EMPTY_HASH
177
- end
178
+ return NewRelic::EMPTY_HASH unless agent_attributes || error_attributes
179
+ merge_and_freeze_attributes(agent_attributes, error_attributes)
178
180
  end
179
181
 
180
182
  def parent_guid segment
@@ -167,7 +167,7 @@ module NewRelic
167
167
 
168
168
  if finished?
169
169
  transaction.async = true
170
- parent.descendant_complete self, segment
170
+ parent.descendant_complete(self, segment) if parent
171
171
  end
172
172
  end
173
173
 
@@ -45,9 +45,11 @@ module NewRelic
45
45
 
46
46
  def gather_ruby_vm_stats(snap)
47
47
  if supports?(:method_cache_invalidations)
48
- vm_stats = RubyVM.stat
49
- snap.method_cache_invalidations = vm_stats[:global_method_state]
50
- snap.constant_cache_invalidations = vm_stats[:global_constant_state]
48
+ snap.method_cache_invalidations = RubyVM.stat[:global_method_state]
49
+ end
50
+
51
+ if supports?(:constant_cache_invalidations)
52
+ snap.constant_cache_invalidations = RubyVM.stat[:global_constant_state]
51
53
  end
52
54
  end
53
55
 
@@ -66,7 +68,7 @@ module NewRelic
66
68
  when :minor_gc_count
67
69
  RUBY_VERSION >= '2.1.0'
68
70
  when :method_cache_invalidations
69
- RUBY_VERSION >= '2.1.0'
71
+ RUBY_VERSION >= '2.1.0' && RUBY_VERSION < '3.0.0'
70
72
  when :constant_cache_invalidations
71
73
  RUBY_VERSION >= '2.1.0'
72
74
  else
@@ -7,7 +7,6 @@
7
7
 
8
8
  require 'yaml'
9
9
  require 'net/http'
10
- require 'rexml/document'
11
10
  require 'new_relic/agent/hostname'
12
11
 
13
12
  # We need to use the Control object but we don't want to load
@@ -67,6 +67,10 @@ module DependencyDetection
67
67
  !executed and check_dependencies
68
68
  end
69
69
 
70
+ def source_location_for klass, method_name
71
+ Object.instance_method(:method).bind(klass.allocate).call(method_name).source_location.to_s
72
+ end
73
+
70
74
  def execute
71
75
  @executes.each do |x|
72
76
  begin
@@ -69,19 +69,7 @@ module NewRelic
69
69
  report_on('Arch' ) { ::NewRelic::Agent::SystemInfo.processor_arch }
70
70
  report_on('OS version' ) { ::NewRelic::Agent::SystemInfo.os_version }
71
71
  report_on('OS' ) { ::NewRelic::Agent::SystemInfo.ruby_os_identifier }
72
- report_on('Database adapter' ) do
73
- begin
74
- if ::ActiveRecord::Base.respond_to?(:connection_db_config)
75
- ActiveRecord::Base.configurations.configs_for(env_name: NewRelic::Control.instance.env, name: "primary")
76
- .connection_db_config.configuration_hash['adapter']
77
- else
78
- ActiveRecord::Base.configurations.configs_for(env_name: NewRelic::Control.instance.env, spec_name: "primary").config['adapter']
79
- end
80
-
81
- rescue NoMethodError
82
- ActiveRecord::Base.configurations[NewRelic::Control.instance.env]['adapter']
83
- end
84
- end
72
+ report_on('Database adapter' ) { ::NewRelic::Agent::DatabaseAdapter.value }
85
73
  report_on('Framework' ) { Agent.config[:framework].to_s }
86
74
  report_on('Dispatcher' ) { Agent.config[:dispatcher].to_s }
87
75
  report_on('Environment' ) { NewRelic::Control.instance.env }
@@ -11,6 +11,7 @@ module NewRelic
11
11
  # transaction, just to eke out a bit less performance hit
12
12
  #
13
13
  API_SUPPORTABILITY_METRICS = [
14
+ :insert_distributed_trace_headers,
14
15
  :accept_distributed_trace_headers,
15
16
  :create_distributed_trace_headers,
16
17
  :add_custom_attributes,