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.
Files changed (113) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG +74 -3
  3. data/GUIDELINES_FOR_CONTRIBUTING.md +19 -15
  4. data/README.md +1 -1
  5. data/Rakefile +22 -1
  6. data/lib/new_relic/agent/agent.rb +17 -5
  7. data/lib/new_relic/agent/agent_logger.rb +4 -0
  8. data/lib/new_relic/agent/configuration/default_source.rb +45 -1
  9. data/lib/new_relic/agent/configuration/manager.rb +43 -7
  10. data/lib/new_relic/agent/cross_app_monitor.rb +0 -3
  11. data/lib/new_relic/agent/cross_app_tracing.rb +8 -5
  12. data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +4 -1
  13. data/lib/new_relic/agent/instrumentation/active_job.rb +93 -0
  14. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +2 -1
  15. data/lib/new_relic/agent/instrumentation/middleware_tracing.rb +2 -2
  16. data/lib/new_relic/agent/instrumentation/sinatra.rb +1 -2
  17. data/lib/new_relic/agent/new_relic_service.rb +1 -1
  18. data/lib/new_relic/agent/new_relic_service/json_marshaller.rb +20 -1
  19. data/lib/new_relic/agent/new_relic_service/pruby_marshaller.rb +5 -1
  20. data/lib/new_relic/agent/pipe_channel_manager.rb +32 -11
  21. data/lib/new_relic/agent/threading/agent_thread.rb +1 -1
  22. data/lib/new_relic/agent/threading/backtrace_node.rb +4 -3
  23. data/lib/new_relic/agent/transaction.rb +27 -6
  24. data/lib/new_relic/agent/transaction_state.rb +3 -3
  25. data/lib/new_relic/agent/vm/mri_vm.rb +3 -3
  26. data/lib/new_relic/control/frameworks/rails3.rb +1 -16
  27. data/lib/new_relic/control/instance_methods.rb +2 -0
  28. data/lib/new_relic/json_wrapper.rb +18 -3
  29. data/lib/new_relic/rack/browser_monitoring.rb +7 -5
  30. data/lib/new_relic/rack/developer_mode.rb +2 -0
  31. data/lib/new_relic/rack/error_collector.rb +12 -51
  32. data/lib/new_relic/transaction_sample.rb +0 -4
  33. data/lib/new_relic/transaction_sample/segment.rb +0 -4
  34. data/lib/new_relic/version.rb +1 -1
  35. data/newrelic_rpm.gemspec +3 -2
  36. data/test/agent_helper.rb +1 -1
  37. data/test/config/test.cert.crt +16 -12
  38. data/test/config/test.cert.key +13 -13
  39. data/test/environments/lib/environments/runner.rb +3 -0
  40. data/test/environments/rails30/Gemfile +2 -2
  41. data/test/environments/rails31/Gemfile +2 -2
  42. data/test/environments/rails32/Gemfile +2 -2
  43. data/test/environments/rails40/Gemfile +2 -4
  44. data/test/environments/rails41/Gemfile +2 -4
  45. data/test/environments/rails42/Gemfile +2 -4
  46. data/test/fixtures/cross_agent_tests/attribute_configuration.json +349 -0
  47. data/test/fixtures/cross_agent_tests/labels.json +31 -2
  48. data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/README.md +16 -0
  49. data/test/fixtures/cross_agent_tests/rum_client_config.json +9 -9
  50. data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/empty_head +4 -0
  51. data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/no_end_header.html +6 -0
  52. data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/x_ua_meta_tag_multiple_tags.html +12 -0
  53. data/test/multiverse/lib/multiverse/runner.rb +33 -1
  54. data/test/multiverse/lib/multiverse/suite.rb +79 -7
  55. data/test/multiverse/suites/active_record/Envfile +1 -1
  56. data/test/multiverse/suites/agent_only/encoding_handling_test.rb +1 -1
  57. data/test/multiverse/suites/agent_only/labels_test.rb +2 -1
  58. data/test/multiverse/suites/agent_only/set_transaction_name_test.rb +2 -3
  59. data/test/multiverse/suites/agent_only/thread_profiling_test.rb +6 -6
  60. data/test/multiverse/suites/capistrano/Envfile +2 -2
  61. data/test/multiverse/suites/capistrano2/Envfile +4 -0
  62. data/test/multiverse/suites/curb/Envfile +4 -0
  63. data/test/multiverse/suites/high_security/config/newrelic.yml +5 -2
  64. data/test/multiverse/suites/high_security/high_security_test.rb +10 -8
  65. data/test/multiverse/suites/json/Envfile +23 -0
  66. data/test/multiverse/suites/json/config/newrelic.yml +22 -0
  67. data/test/multiverse/suites/json/json_test.rb +17 -0
  68. data/test/multiverse/suites/marshalling/marshalling_test.rb +2 -45
  69. data/test/multiverse/suites/rails/Envfile +3 -3
  70. data/test/multiverse/suites/rails/activejob_test.rb +137 -0
  71. data/test/multiverse/suites/rails/error_tracing_test.rb +15 -8
  72. data/test/multiverse/suites/rails/parameter_capture_test.rb +39 -19
  73. data/test/multiverse/suites/sequel/Envfile +5 -5
  74. data/test/multiverse/suites/sidekiq/Envfile +2 -2
  75. data/test/multiverse/suites/sinatra/Envfile +2 -1
  76. data/test/multiverse/suites/yajl/Envfile +13 -0
  77. data/test/multiverse/suites/yajl/config/newrelic.yml +21 -0
  78. data/test/multiverse/suites/yajl/yajl_test.rb +19 -0
  79. data/test/new_relic/agent/agent_logger_test.rb +10 -0
  80. data/test/new_relic/agent/agent_test.rb +7 -1
  81. data/test/new_relic/agent/configuration/default_source_test.rb +24 -0
  82. data/test/new_relic/agent/configuration/manager_test.rb +60 -2
  83. data/test/new_relic/agent/configuration/orphan_configuration_test.rb +25 -13
  84. data/test/new_relic/agent/cross_app_tracing_test.rb +10 -1
  85. data/test/new_relic/agent/instrumentation/active_job_test.rb +20 -0
  86. data/test/new_relic/agent/instrumentation/active_record_test.rb +10 -17
  87. data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +15 -0
  88. data/test/new_relic/agent/instrumentation/sinatra_test.rb +1 -1
  89. data/test/new_relic/agent/new_relic_service_test.rb +24 -0
  90. data/test/new_relic/agent/pipe_channel_manager_test.rb +44 -2
  91. data/test/new_relic/agent/threading/agent_thread_test.rb +1 -2
  92. data/test/new_relic/agent/threading/backtrace_node_test.rb +12 -0
  93. data/test/new_relic/agent/transaction_state_test.rb +3 -6
  94. data/test/new_relic/agent/transaction_test.rb +163 -0
  95. data/test/new_relic/agent_test.rb +13 -1
  96. data/test/new_relic/fake_collector.rb +5 -5
  97. data/test/new_relic/fake_server.rb +5 -3
  98. data/test/new_relic/http_client_test_cases.rb +0 -4
  99. data/test/new_relic/marshalling_test_cases.rb +54 -0
  100. data/test/new_relic/multiverse_helpers.rb +2 -2
  101. data/test/new_relic/rack/browser_monitoring_test.rb +6 -0
  102. data/test/new_relic/rack/developer_mode_test.rb +8 -0
  103. data/test/new_relic/rack/error_collector_test.rb +0 -41
  104. data/test/new_relic/transaction_sample/segment_test.rb +0 -13
  105. data/test/new_relic/transaction_sample_test.rb +1 -11
  106. data/test/performance/lib/performance/instrumentation/perf_tools.rb +1 -1
  107. data/test/performance/lib/performance/runner.rb +1 -1
  108. data/test/performance/script/runner +2 -1
  109. data/test/performance/suites/rum_autoinsertion.rb +12 -2
  110. metadata +24 -11
  111. metadata.gz.sig +0 -0
  112. data/test/config/test.cert.csr +0 -11
  113. 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(params)
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] = trace_options[:request] || (respond_to?(:request) && 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
@@ -62,9 +62,9 @@ module NewRelic
62
62
  end
63
63
 
64
64
  result
65
- rescue => e
65
+ rescue Exception => e
66
66
  NewRelic::Agent.notice_error(e)
67
- raise
67
+ raise e
68
68
  ensure
69
69
  Transaction.stop(state)
70
70
  end
@@ -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 = 12
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
- return_value(NewRelic::JSONWrapper.load(data)) if data && data != ''
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
- return unless data && data != ''
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
- @pipes[id] = Pipe.new
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
- pipes_to_listen_to = @pipes.values.map{|pipe| pipe.out} + [wake.out]
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
- @pipes.each do |id, pipe|
194
- pipe.close if pipe
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
- @pipes.values.each do |pipe|
243
- if pipe.last_read.to_f + @timeout < Time.now.to_f
244
- pipe.close unless pipe.closed?
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
- @pipes.values.find{|pipe| pipe.out == out_handle }
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
@@ -40,7 +40,7 @@ module NewRelic
40
40
  state = TransactionState.tl_state_for(thread)
41
41
  if state.in_background_transaction?
42
42
  :background
43
- elsif state.in_request_transaction?
43
+ elsif state.in_web_transaction?
44
44
  :request
45
45
  else
46
46
  :other
@@ -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 =~ /(.*)\:(\d+)\:in `(.*)'/
128
- [$1, $3, $2] # sic
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[:referer] = referer if referer
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