newrelic_rpm 3.9.5.251 → 3.9.6.257
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/CHANGELOG +74 -3
- data/GUIDELINES_FOR_CONTRIBUTING.md +19 -15
- data/README.md +1 -1
- data/Rakefile +22 -1
- data/lib/new_relic/agent/agent.rb +17 -5
- data/lib/new_relic/agent/agent_logger.rb +4 -0
- data/lib/new_relic/agent/configuration/default_source.rb +45 -1
- data/lib/new_relic/agent/configuration/manager.rb +43 -7
- data/lib/new_relic/agent/cross_app_monitor.rb +0 -3
- data/lib/new_relic/agent/cross_app_tracing.rb +8 -5
- data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +4 -1
- data/lib/new_relic/agent/instrumentation/active_job.rb +93 -0
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +2 -1
- data/lib/new_relic/agent/instrumentation/middleware_tracing.rb +2 -2
- data/lib/new_relic/agent/instrumentation/sinatra.rb +1 -2
- data/lib/new_relic/agent/new_relic_service.rb +1 -1
- data/lib/new_relic/agent/new_relic_service/json_marshaller.rb +20 -1
- data/lib/new_relic/agent/new_relic_service/pruby_marshaller.rb +5 -1
- data/lib/new_relic/agent/pipe_channel_manager.rb +32 -11
- data/lib/new_relic/agent/threading/agent_thread.rb +1 -1
- data/lib/new_relic/agent/threading/backtrace_node.rb +4 -3
- data/lib/new_relic/agent/transaction.rb +27 -6
- data/lib/new_relic/agent/transaction_state.rb +3 -3
- data/lib/new_relic/agent/vm/mri_vm.rb +3 -3
- data/lib/new_relic/control/frameworks/rails3.rb +1 -16
- data/lib/new_relic/control/instance_methods.rb +2 -0
- data/lib/new_relic/json_wrapper.rb +18 -3
- data/lib/new_relic/rack/browser_monitoring.rb +7 -5
- data/lib/new_relic/rack/developer_mode.rb +2 -0
- data/lib/new_relic/rack/error_collector.rb +12 -51
- data/lib/new_relic/transaction_sample.rb +0 -4
- data/lib/new_relic/transaction_sample/segment.rb +0 -4
- data/lib/new_relic/version.rb +1 -1
- data/newrelic_rpm.gemspec +3 -2
- data/test/agent_helper.rb +1 -1
- data/test/config/test.cert.crt +16 -12
- data/test/config/test.cert.key +13 -13
- data/test/environments/lib/environments/runner.rb +3 -0
- data/test/environments/rails30/Gemfile +2 -2
- data/test/environments/rails31/Gemfile +2 -2
- data/test/environments/rails32/Gemfile +2 -2
- data/test/environments/rails40/Gemfile +2 -4
- data/test/environments/rails41/Gemfile +2 -4
- data/test/environments/rails42/Gemfile +2 -4
- data/test/fixtures/cross_agent_tests/attribute_configuration.json +349 -0
- data/test/fixtures/cross_agent_tests/labels.json +31 -2
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/README.md +16 -0
- data/test/fixtures/cross_agent_tests/rum_client_config.json +9 -9
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/empty_head +4 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/no_end_header.html +6 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/x_ua_meta_tag_multiple_tags.html +12 -0
- data/test/multiverse/lib/multiverse/runner.rb +33 -1
- data/test/multiverse/lib/multiverse/suite.rb +79 -7
- data/test/multiverse/suites/active_record/Envfile +1 -1
- data/test/multiverse/suites/agent_only/encoding_handling_test.rb +1 -1
- data/test/multiverse/suites/agent_only/labels_test.rb +2 -1
- data/test/multiverse/suites/agent_only/set_transaction_name_test.rb +2 -3
- data/test/multiverse/suites/agent_only/thread_profiling_test.rb +6 -6
- data/test/multiverse/suites/capistrano/Envfile +2 -2
- data/test/multiverse/suites/capistrano2/Envfile +4 -0
- data/test/multiverse/suites/curb/Envfile +4 -0
- data/test/multiverse/suites/high_security/config/newrelic.yml +5 -2
- data/test/multiverse/suites/high_security/high_security_test.rb +10 -8
- data/test/multiverse/suites/json/Envfile +23 -0
- data/test/multiverse/suites/json/config/newrelic.yml +22 -0
- data/test/multiverse/suites/json/json_test.rb +17 -0
- data/test/multiverse/suites/marshalling/marshalling_test.rb +2 -45
- data/test/multiverse/suites/rails/Envfile +3 -3
- data/test/multiverse/suites/rails/activejob_test.rb +137 -0
- data/test/multiverse/suites/rails/error_tracing_test.rb +15 -8
- data/test/multiverse/suites/rails/parameter_capture_test.rb +39 -19
- data/test/multiverse/suites/sequel/Envfile +5 -5
- data/test/multiverse/suites/sidekiq/Envfile +2 -2
- data/test/multiverse/suites/sinatra/Envfile +2 -1
- data/test/multiverse/suites/yajl/Envfile +13 -0
- data/test/multiverse/suites/yajl/config/newrelic.yml +21 -0
- data/test/multiverse/suites/yajl/yajl_test.rb +19 -0
- data/test/new_relic/agent/agent_logger_test.rb +10 -0
- data/test/new_relic/agent/agent_test.rb +7 -1
- data/test/new_relic/agent/configuration/default_source_test.rb +24 -0
- data/test/new_relic/agent/configuration/manager_test.rb +60 -2
- data/test/new_relic/agent/configuration/orphan_configuration_test.rb +25 -13
- data/test/new_relic/agent/cross_app_tracing_test.rb +10 -1
- data/test/new_relic/agent/instrumentation/active_job_test.rb +20 -0
- data/test/new_relic/agent/instrumentation/active_record_test.rb +10 -17
- data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +15 -0
- data/test/new_relic/agent/instrumentation/sinatra_test.rb +1 -1
- data/test/new_relic/agent/new_relic_service_test.rb +24 -0
- data/test/new_relic/agent/pipe_channel_manager_test.rb +44 -2
- data/test/new_relic/agent/threading/agent_thread_test.rb +1 -2
- data/test/new_relic/agent/threading/backtrace_node_test.rb +12 -0
- data/test/new_relic/agent/transaction_state_test.rb +3 -6
- data/test/new_relic/agent/transaction_test.rb +163 -0
- data/test/new_relic/agent_test.rb +13 -1
- data/test/new_relic/fake_collector.rb +5 -5
- data/test/new_relic/fake_server.rb +5 -3
- data/test/new_relic/http_client_test_cases.rb +0 -4
- data/test/new_relic/marshalling_test_cases.rb +54 -0
- data/test/new_relic/multiverse_helpers.rb +2 -2
- data/test/new_relic/rack/browser_monitoring_test.rb +6 -0
- data/test/new_relic/rack/developer_mode_test.rb +8 -0
- data/test/new_relic/rack/error_collector_test.rb +0 -41
- data/test/new_relic/transaction_sample/segment_test.rb +0 -13
- data/test/new_relic/transaction_sample_test.rb +1 -11
- data/test/performance/lib/performance/instrumentation/perf_tools.rb +1 -1
- data/test/performance/lib/performance/runner.rb +1 -1
- data/test/performance/script/runner +2 -1
- data/test/performance/suites/rum_autoinsertion.rb +12 -2
- metadata +24 -11
- metadata.gz.sig +0 -0
- data/test/config/test.cert.csr +0 -11
- data/test/config/testing-privkey.pem +0 -18
@@ -37,8 +37,10 @@ module NewRelic
|
|
37
37
|
state = NewRelic::Agent::TransactionState.tl_get
|
38
38
|
return yield unless state.is_execution_traced?
|
39
39
|
|
40
|
+
# It's important to set t0 outside the ensured block, otherwise there's
|
41
|
+
# a race condition if we raise after begin but before t0's set.
|
42
|
+
t0 = Time.now
|
40
43
|
begin
|
41
|
-
t0 = Time.now
|
42
44
|
segment = start_trace(state, t0, request)
|
43
45
|
response = yield
|
44
46
|
ensure
|
@@ -91,6 +93,11 @@ module NewRelic
|
|
91
93
|
# * to_hash - Converts response headers to a Hash
|
92
94
|
#
|
93
95
|
def finish_trace(state, t0, segment, request, response)
|
96
|
+
unless t0
|
97
|
+
NewRelic::Agent.logger.error("HTTP request trace finished without start time. This is probably an agent bug.")
|
98
|
+
return
|
99
|
+
end
|
100
|
+
|
94
101
|
t1 = Time.now
|
95
102
|
duration = t1.to_f - t0.to_f
|
96
103
|
|
@@ -237,8 +244,6 @@ module NewRelic
|
|
237
244
|
def response_is_crossapp?( response )
|
238
245
|
return false unless cross_app_enabled?
|
239
246
|
unless response[NR_APPDATA_HEADER]
|
240
|
-
NewRelic::Agent.logger.debug "Response doesn't have the %p header: %p" %
|
241
|
-
[ NR_APPDATA_HEADER, response.to_hash ]
|
242
247
|
return false
|
243
248
|
end
|
244
249
|
|
@@ -254,8 +259,6 @@ module NewRelic
|
|
254
259
|
check_crossapp_id( xp_id )
|
255
260
|
check_transaction_name( txn_name )
|
256
261
|
|
257
|
-
NewRelic::Agent.logger.debug "CAT xp_id: %p, txn_name: %p." % [ xp_id, txn_name ]
|
258
|
-
|
259
262
|
metrics = []
|
260
263
|
metrics << "ExternalApp/#{request.host}/#{xp_id}/all"
|
261
264
|
metrics << "ExternalTransaction/#{request.host}/#{xp_id}/#{txn_name}"
|
@@ -58,8 +58,11 @@ module NewRelic
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def filter(params)
|
61
|
+
munged_params = params.dup
|
62
|
+
munged_params.delete('controller')
|
63
|
+
munged_params.delete('action')
|
61
64
|
filters = Rails.application.config.filter_parameters
|
62
|
-
ActionDispatch::Http::ParameterFilter.new(filters).filter(
|
65
|
+
ActionDispatch::Http::ParameterFilter.new(filters).filter(munged_params)
|
63
66
|
end
|
64
67
|
end
|
65
68
|
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# This file is distributed under New Relic's license terms.
|
3
|
+
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
|
4
|
+
|
5
|
+
DependencyDetection.defer do
|
6
|
+
named :activejob
|
7
|
+
|
8
|
+
depends_on do
|
9
|
+
defined?(::ActiveJob::Base)
|
10
|
+
end
|
11
|
+
|
12
|
+
executes do
|
13
|
+
::NewRelic::Agent.logger.info 'Installing ActiveJob instrumentation'
|
14
|
+
|
15
|
+
::ActiveJob::Base.around_enqueue do |job, block|
|
16
|
+
::NewRelic::Agent::Instrumentation::ActiveJobHelper.enqueue(job, block)
|
17
|
+
end
|
18
|
+
|
19
|
+
::ActiveJob::Base.around_perform do |job, block|
|
20
|
+
::NewRelic::Agent::Instrumentation::ActiveJobHelper.perform(job, block)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module NewRelic
|
26
|
+
module Agent
|
27
|
+
module Instrumentation
|
28
|
+
module ActiveJobHelper
|
29
|
+
include ::NewRelic::Agent::MethodTracer
|
30
|
+
|
31
|
+
def self.enqueue(job, block)
|
32
|
+
run_in_trace(job, block, :Produce)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.perform(job, block)
|
36
|
+
state = ::NewRelic::Agent::TransactionState.tl_get
|
37
|
+
|
38
|
+
# Don't nest transactions if we're already in a web transaction.
|
39
|
+
# Probably inline processing the job if that happens, so just trace.
|
40
|
+
if state.in_web_transaction?
|
41
|
+
run_in_trace(job, block, :Consume)
|
42
|
+
elsif state.in_background_transaction?
|
43
|
+
::NewRelic::Agent::Transaction.set_default_transaction_name(
|
44
|
+
transaction_name_suffix_for_job(job),
|
45
|
+
:category => transaction_category)
|
46
|
+
block.call
|
47
|
+
else
|
48
|
+
run_in_transaction(state, job, block)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.run_in_trace(job, block, event)
|
53
|
+
trace_execution_scoped("MessageBroker/#{adapter}/Queue/#{event}/Named/#{job.queue_name}") do
|
54
|
+
block.call
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.run_in_transaction(state, job, block)
|
59
|
+
begin
|
60
|
+
::NewRelic::Agent::Transaction.start(state, :other,
|
61
|
+
:transaction_name => transaction_name_for_job(job))
|
62
|
+
block.call
|
63
|
+
ensure
|
64
|
+
::NewRelic::Agent::Transaction.stop(state)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.transaction_category
|
69
|
+
"OtherTransaction/#{adapter}"
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.transaction_name_suffix_for_job(job)
|
73
|
+
"#{job.class}/execute"
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.transaction_name_for_job(job)
|
77
|
+
"#{transaction_category}/#{transaction_name_suffix_for_job(job)}"
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.adapter
|
81
|
+
clean_adapter_name(::ActiveJob::Base.queue_adapter.name)
|
82
|
+
end
|
83
|
+
|
84
|
+
ADAPTER_REGEX = /ActiveJob::QueueAdapters::(.*)Adapter/
|
85
|
+
|
86
|
+
def self.clean_adapter_name(name)
|
87
|
+
name = "ActiveJob::#{$1}" if ADAPTER_REGEX =~ name
|
88
|
+
name
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -430,7 +430,8 @@ module NewRelic
|
|
430
430
|
|
431
431
|
def create_transaction_options(trace_options, available_params)
|
432
432
|
txn_options = {}
|
433
|
-
txn_options[:request]
|
433
|
+
txn_options[:request] = trace_options[:request]
|
434
|
+
txn_options[:request] ||= request if respond_to?(:request)
|
434
435
|
|
435
436
|
if available_params
|
436
437
|
txn_options[:filtered_params] = (respond_to?(:filter_parameters)) ? filter_parameters(available_params) : available_params
|
@@ -86,8 +86,7 @@ module NewRelic
|
|
86
86
|
module ClassMethods
|
87
87
|
def newrelic_middlewares
|
88
88
|
[ NewRelic::Rack::AgentHooks,
|
89
|
-
NewRelic::Rack::BrowserMonitoring
|
90
|
-
NewRelic::Rack::ErrorCollector ]
|
89
|
+
NewRelic::Rack::BrowserMonitoring ]
|
91
90
|
end
|
92
91
|
|
93
92
|
def build_with_newrelic(*args, &block)
|
@@ -15,7 +15,7 @@ module NewRelic
|
|
15
15
|
# Specifies the version of the agent's communication protocol with
|
16
16
|
# the NewRelic hosted site.
|
17
17
|
|
18
|
-
PROTOCOL_VERSION =
|
18
|
+
PROTOCOL_VERSION = 14
|
19
19
|
# 1f147a42: v10 (tag 3.5.3.17)
|
20
20
|
# cf0d1ff1: v9 (tag 3.5.0)
|
21
21
|
# 14105: v8 (tag 2.10.3)
|
@@ -14,6 +14,20 @@ module NewRelic
|
|
14
14
|
unless self.class.is_supported?
|
15
15
|
::NewRelic::Agent.logger.warn "The JSON marshaller in use (#{NewRelic::JSONWrapper.backend_name}) is not recommended. Ensure the 'json' gem is available in your application for better performance."
|
16
16
|
end
|
17
|
+
warn_for_yajl
|
18
|
+
end
|
19
|
+
|
20
|
+
OK_YAJL_VERSION = NewRelic::VersionNumber.new("1.2.1")
|
21
|
+
|
22
|
+
def warn_for_yajl
|
23
|
+
if defined?(::Yajl)
|
24
|
+
require 'yajl/version'
|
25
|
+
if NewRelic::VersionNumber.new(::Yajl::VERSION) < OK_YAJL_VERSION
|
26
|
+
::NewRelic::Agent.logger.warn "Detected yajl-ruby version #{::Yajl::VERSION} which can cause segfaults with newrelic_rpm's thread profiling features. We strongly recommend you upgrade to the latest yajl-ruby version available."
|
27
|
+
end
|
28
|
+
end
|
29
|
+
rescue => err
|
30
|
+
::NewRelic::Agent.logger.warn "Failed trying to watch for problematic yajl-ruby version.", err
|
17
31
|
end
|
18
32
|
|
19
33
|
def dump(ruby, opts={})
|
@@ -29,7 +43,12 @@ module NewRelic
|
|
29
43
|
end
|
30
44
|
|
31
45
|
def load(data)
|
32
|
-
|
46
|
+
if data.nil? || data.empty?
|
47
|
+
::NewRelic::Agent.logger.error "Empty JSON response from collector: '#{data.inspect}'"
|
48
|
+
return nil
|
49
|
+
end
|
50
|
+
|
51
|
+
return_value(NewRelic::JSONWrapper.load(data))
|
33
52
|
rescue => e
|
34
53
|
::NewRelic::Agent.logger.debug "#{e.class.name} : #{e.message} encountered loading collector response: #{data}"
|
35
54
|
raise
|
@@ -30,7 +30,11 @@ module NewRelic
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def load(data)
|
33
|
-
|
33
|
+
if data.nil? || data.empty?
|
34
|
+
::NewRelic::Agent.logger.error "Empty pruby response from collector: '#{data.inspect}'"
|
35
|
+
return nil
|
36
|
+
end
|
37
|
+
|
34
38
|
NewRelic::LanguageSupport.with_cautious_gc do
|
35
39
|
return_value(Marshal.load(data))
|
36
40
|
end
|
@@ -129,10 +129,19 @@ module NewRelic
|
|
129
129
|
|
130
130
|
class Listener
|
131
131
|
attr_reader :thread
|
132
|
+
|
133
|
+
# This attr_accessor intentionally provides unsynchronized access to the
|
134
|
+
# @pipes hash. It is used to look up the write end of the pipe from
|
135
|
+
# within the Resque child process, and must be unsynchronized in order
|
136
|
+
# to avoid a potential deadlock in which the PipeChannelManager::Listener
|
137
|
+
# thread in the parent process is holding the @pipes_lock at the time of
|
138
|
+
# the fork.
|
132
139
|
attr_accessor :pipes, :timeout, :select_timeout
|
133
140
|
|
134
141
|
def initialize
|
135
142
|
@pipes = {}
|
143
|
+
@pipes_lock = Mutex.new
|
144
|
+
|
136
145
|
@timeout = 360
|
137
146
|
@select_timeout = 60
|
138
147
|
end
|
@@ -142,7 +151,10 @@ module NewRelic
|
|
142
151
|
end
|
143
152
|
|
144
153
|
def register_pipe(id)
|
145
|
-
@
|
154
|
+
@pipes_lock.synchronize do
|
155
|
+
@pipes[id] = Pipe.new
|
156
|
+
end
|
157
|
+
|
146
158
|
wakeup
|
147
159
|
end
|
148
160
|
|
@@ -153,7 +165,10 @@ module NewRelic
|
|
153
165
|
now = nil
|
154
166
|
loop do
|
155
167
|
clean_up_pipes
|
156
|
-
|
168
|
+
|
169
|
+
pipes_to_listen_to = @pipes_lock.synchronize do
|
170
|
+
@pipes.values.map{|pipe| pipe.out} + [wake.out]
|
171
|
+
end
|
157
172
|
|
158
173
|
NewRelic::Agent.record_metric('Supportability/Listeners',
|
159
174
|
(Time.now - now).to_f) if now
|
@@ -190,10 +205,12 @@ module NewRelic
|
|
190
205
|
end
|
191
206
|
|
192
207
|
def close_all_pipes
|
193
|
-
@
|
194
|
-
|
208
|
+
@pipes_lock.synchronize do
|
209
|
+
@pipes.each do |id, pipe|
|
210
|
+
pipe.close if pipe
|
211
|
+
end
|
212
|
+
@pipes = {}
|
195
213
|
end
|
196
|
-
@pipes = {}
|
197
214
|
end
|
198
215
|
|
199
216
|
def wake
|
@@ -235,20 +252,24 @@ module NewRelic
|
|
235
252
|
end
|
236
253
|
|
237
254
|
def should_keep_listening?
|
238
|
-
@started || @pipes.values.find{|pipe| !pipe.in.closed?}
|
255
|
+
@started || @pipes_lock.synchronize { @pipes.values.find{|pipe| !pipe.in.closed?} }
|
239
256
|
end
|
240
257
|
|
241
258
|
def clean_up_pipes
|
242
|
-
@
|
243
|
-
|
244
|
-
pipe.
|
259
|
+
@pipes_lock.synchronize do
|
260
|
+
@pipes.values.each do |pipe|
|
261
|
+
if pipe.last_read.to_f + @timeout < Time.now.to_f
|
262
|
+
pipe.close unless pipe.closed?
|
263
|
+
end
|
245
264
|
end
|
265
|
+
@pipes.reject! {|id, pipe| pipe.out.closed? }
|
246
266
|
end
|
247
|
-
@pipes.reject! {|id, pipe| pipe.out.closed? }
|
248
267
|
end
|
249
268
|
|
250
269
|
def find_pipe_for_handle(out_handle)
|
251
|
-
@
|
270
|
+
@pipes_lock.synchronize do
|
271
|
+
@pipes.values.find{|pipe| pipe.out == out_handle }
|
272
|
+
end
|
252
273
|
end
|
253
274
|
end
|
254
275
|
end
|
@@ -6,6 +6,7 @@ module NewRelic
|
|
6
6
|
module Agent
|
7
7
|
module Threading
|
8
8
|
MAX_THREAD_PROFILE_DEPTH = 500
|
9
|
+
UNKNOWN_LINE_NUMBER = -1
|
9
10
|
|
10
11
|
class BacktraceBase
|
11
12
|
attr_reader :children
|
@@ -108,7 +109,7 @@ module NewRelic
|
|
108
109
|
|
109
110
|
file, method, line = parse_backtrace_frame(@raw_line)
|
110
111
|
|
111
|
-
@as_array << [string(file), string(method), int(line)]
|
112
|
+
@as_array << [string(file), string(method), line ? int(line) : UNKNOWN_LINE_NUMBER]
|
112
113
|
@as_array << int(@runnable_count)
|
113
114
|
@as_array << 0
|
114
115
|
@as_array << child_arrays
|
@@ -124,8 +125,8 @@ module NewRelic
|
|
124
125
|
|
125
126
|
# Returns [filename, method, line number]
|
126
127
|
def parse_backtrace_frame(frame)
|
127
|
-
frame =~ /(
|
128
|
-
[$1, $
|
128
|
+
frame =~ /([^:]*)(\:(\d+))?\:in `(.*)'/
|
129
|
+
[$1, $4, $3] # sic
|
129
130
|
end
|
130
131
|
end
|
131
132
|
|
@@ -22,6 +22,7 @@ module NewRelic
|
|
22
22
|
TASK_PREFIX = 'OtherTransaction/Background/'.freeze
|
23
23
|
RACK_PREFIX = 'Controller/Rack/'.freeze
|
24
24
|
SINATRA_PREFIX = 'Controller/Sinatra/'.freeze
|
25
|
+
OTHER_TRANSACTION_PREFIX = 'OtherTransaction/'.freeze
|
25
26
|
|
26
27
|
CONTROLLER_MIDDLEWARE_PREFIX = 'Controller/Middleware/Rack'.freeze
|
27
28
|
|
@@ -183,7 +184,7 @@ module NewRelic
|
|
183
184
|
end
|
184
185
|
|
185
186
|
def self.nested_transaction_name(name)
|
186
|
-
if name.start_with?(CONTROLLER_PREFIX)
|
187
|
+
if name.start_with?(CONTROLLER_PREFIX) || name.start_with?(OTHER_TRANSACTION_PREFIX)
|
187
188
|
"#{SUBTRANSACTION_PREFIX}#{name}"
|
188
189
|
else
|
189
190
|
name
|
@@ -368,6 +369,7 @@ module NewRelic
|
|
368
369
|
def stop(state, end_time)
|
369
370
|
return if !state.is_execution_traced?
|
370
371
|
freeze_name_and_execute_if_not_ignored
|
372
|
+
ignore! if user_defined_rules_ignore?
|
371
373
|
|
372
374
|
if @name_from_child
|
373
375
|
name = Transaction.nested_transaction_name(@default_name)
|
@@ -399,6 +401,17 @@ module NewRelic
|
|
399
401
|
commit!(state, end_time, name) unless @ignore_this_transaction
|
400
402
|
end
|
401
403
|
|
404
|
+
def user_defined_rules_ignore?
|
405
|
+
return if (rules = NewRelic::Agent.config[:"rules.ignore_url_regexes"]).empty?
|
406
|
+
|
407
|
+
parsed = NewRelic::Agent::HTTPClients::URIUtil.parse_url(uri)
|
408
|
+
filtered_uri = NewRelic::Agent::HTTPClients::URIUtil.filter_uri(parsed)
|
409
|
+
|
410
|
+
rules.any? do |rule|
|
411
|
+
filtered_uri.match(rule)
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
402
415
|
def commit!(state, end_time, outermost_segment_name)
|
403
416
|
record_transaction_cpu(state)
|
404
417
|
gc_stop_snapshot = NewRelic::Agent::StatsEngine::GCProfiler.take_snapshot
|
@@ -422,7 +435,7 @@ module NewRelic
|
|
422
435
|
def record_summary_metrics(outermost_segment_name, end_time)
|
423
436
|
metrics = summary_metrics
|
424
437
|
metrics << @frozen_name unless @frozen_name == outermost_segment_name
|
425
|
-
@metrics.record_unscoped(metrics, end_time - start_time, 0)
|
438
|
+
@metrics.record_unscoped(metrics, end_time.to_f - start_time.to_f, 0)
|
426
439
|
end
|
427
440
|
|
428
441
|
# This event is fired when the transaction is fully completed. The metric
|
@@ -557,8 +570,8 @@ module NewRelic
|
|
557
570
|
def self.extract_request_options(options)
|
558
571
|
req = options.delete(:request)
|
559
572
|
if req
|
573
|
+
options[:uri] = uri_from_request(req)
|
560
574
|
options[:referer] = referer_from_request(req)
|
561
|
-
options[:uri] = uri_from_request(req)
|
562
575
|
end
|
563
576
|
options
|
564
577
|
end
|
@@ -566,13 +579,13 @@ module NewRelic
|
|
566
579
|
|
567
580
|
# Do not call this. Invoke the class method instead.
|
568
581
|
def notice_error(error, options={}) # :nodoc:
|
569
|
-
options[:
|
582
|
+
options[:uri] ||= uri if uri
|
583
|
+
options[:referer] ||= referer if referer
|
570
584
|
|
571
585
|
if filtered_params && !filtered_params.empty?
|
572
586
|
options[:request_params] = filtered_params
|
573
587
|
end
|
574
588
|
|
575
|
-
options[:uri] = uri if uri
|
576
589
|
options.merge!(custom_parameters)
|
577
590
|
|
578
591
|
if @exceptions[error]
|
@@ -771,11 +784,19 @@ module NewRelic
|
|
771
784
|
p.stime + p.utime
|
772
785
|
end
|
773
786
|
|
787
|
+
JRUBY_CPU_TIME_ERROR = "Error calculating JRuby CPU Time".freeze
|
774
788
|
def jruby_cpu_time
|
775
789
|
return nil unless @@java_classes_loaded
|
776
|
-
threadMBean = ManagementFactory.getThreadMXBean()
|
790
|
+
threadMBean = Java::JavaLangManagement::ManagementFactory.getThreadMXBean()
|
791
|
+
|
792
|
+
return nil unless threadMBean.isCurrentThreadCpuTimeSupported
|
777
793
|
java_utime = threadMBean.getCurrentThreadUserTime() # ns
|
794
|
+
|
778
795
|
-1 == java_utime ? 0.0 : java_utime/1e9
|
796
|
+
rescue => e
|
797
|
+
::NewRelic::Agent.logger.log_once(:warn, :jruby_cpu_time, JRUBY_CPU_TIME_ERROR, e)
|
798
|
+
::NewRelic::Agent.logger.debug(JRUBY_CPU_TIME_ERROR, e)
|
799
|
+
nil
|
779
800
|
end
|
780
801
|
|
781
802
|
def agent
|