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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +52 -2
- data/lib/new_relic/agent.rb +1 -0
- data/lib/new_relic/agent/agent.rb +2 -4
- data/lib/new_relic/agent/configuration/default_source.rb +13 -1
- data/lib/new_relic/agent/database_adapter.rb +33 -0
- data/lib/new_relic/agent/instrumentation/active_record_helper.rb +21 -68
- data/lib/new_relic/agent/instrumentation/active_record_prepend.rb +23 -57
- data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +0 -15
- data/lib/new_relic/agent/instrumentation/bunny.rb +27 -71
- data/lib/new_relic/agent/instrumentation/curb.rb +12 -30
- data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +8 -21
- data/lib/new_relic/agent/instrumentation/net.rb +33 -57
- data/lib/new_relic/agent/instrumentation/net_prepend.rb +21 -53
- data/lib/new_relic/agent/instrumentation/padrino.rb +15 -37
- data/lib/new_relic/agent/instrumentation/rack.rb +6 -17
- data/lib/new_relic/agent/instrumentation/rake.rb +19 -53
- data/lib/new_relic/agent/instrumentation/redis.rb +59 -138
- data/lib/new_relic/agent/instrumentation/sidekiq.rb +1 -1
- data/lib/new_relic/agent/instrumentation/sinatra.rb +22 -62
- data/lib/new_relic/agent/span_event_primitive.rb +10 -8
- data/lib/new_relic/agent/transaction/abstract_segment.rb +1 -1
- data/lib/new_relic/agent/vm/mri_vm.rb +6 -4
- data/lib/new_relic/cli/commands/deployments.rb +0 -1
- data/lib/new_relic/dependency_detection.rb +4 -0
- data/lib/new_relic/environment_report.rb +1 -13
- data/lib/new_relic/supportability_helper.rb +1 -0
- data/lib/new_relic/version.rb +1 -1
- data/test/agent_helper.rb +1 -0
- 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
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
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
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
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
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
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]
|
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
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
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
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
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
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
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
|
-
|
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
|
-
|
170
|
-
|
175
|
+
agent_attributes = segment.attributes
|
176
|
+
.agent_attributes_for(NewRelic::Agent::AttributeFilter::DST_SPAN_EVENTS)
|
171
177
|
error_attributes = error_attributes(segment)
|
172
|
-
|
173
|
-
|
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
|
@@ -45,9 +45,11 @@ module NewRelic
|
|
45
45
|
|
46
46
|
def gather_ruby_vm_stats(snap)
|
47
47
|
if supports?(:method_cache_invalidations)
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
@@ -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' )
|
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 }
|