newrelic_rpm 3.6.3.111 → 3.6.4.113.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/CHANGELOG +14 -1
  2. data/lib/new_relic/agent/agent.rb +14 -6
  3. data/lib/new_relic/agent/configuration/defaults.rb +8 -3
  4. data/lib/new_relic/agent/configuration/manager.rb +32 -1
  5. data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +2 -2
  6. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +7 -11
  7. data/lib/new_relic/agent/instrumentation/resque.rb +2 -1
  8. data/lib/new_relic/agent/method_tracer.rb +4 -6
  9. data/lib/new_relic/agent/pipe_service.rb +4 -0
  10. data/lib/new_relic/agent/request_sampler.rb +46 -1
  11. data/lib/new_relic/agent/stats_engine/metric_stats.rb +11 -10
  12. data/lib/new_relic/agent/stats_engine/stats_hash.rb +12 -0
  13. data/lib/new_relic/agent/stats_engine/transactions.rb +1 -28
  14. data/lib/new_relic/agent/thread_profiler.rb +3 -3
  15. data/lib/new_relic/agent/transaction.rb +29 -15
  16. data/lib/new_relic/build.rb +2 -2
  17. data/lib/new_relic/noticed_error.rb +28 -12
  18. data/lib/new_relic/version.rb +1 -1
  19. data/test/agent_helper.rb +25 -0
  20. data/test/multiverse/suites/agent_only/key_transactions_test.rb +11 -11
  21. data/test/multiverse/suites/rails/request_statistics_test.rb +14 -20
  22. data/test/multiverse/suites/resque/Envfile +0 -1
  23. data/test/multiverse/suites/resque/config/newrelic.yml +1 -1
  24. data/test/multiverse/suites/resque/instrumentation_test.rb +16 -107
  25. data/test/new_relic/agent/agent/connect_test.rb +3 -3
  26. data/test/new_relic/agent/agent/start_test.rb +2 -0
  27. data/test/new_relic/agent/configuration/manager_test.rb +10 -0
  28. data/test/new_relic/agent/error_collector_test.rb +9 -9
  29. data/test/new_relic/agent/method_tracer_test.rb +8 -1
  30. data/test/new_relic/agent/request_sampler_test.rb +10 -0
  31. data/test/new_relic/agent/stats_engine/metric_stats_test.rb +40 -4
  32. data/test/new_relic/agent/transaction_test.rb +23 -0
  33. data/test/new_relic/noticed_error_test.rb +84 -2
  34. data/test/test_helper.rb +2 -16
  35. data.tar.gz.sig +0 -0
  36. metadata +11 -6
  37. metadata.gz.sig +0 -0
@@ -84,21 +84,21 @@ class NewRelic::Agent::Agent::ConnectTest < Test::Unit::TestCase
84
84
  end
85
85
 
86
86
  def test_connect_settings_have_environment_report
87
- assert NewRelic::Agent.agent.connect_settings[:environment].detect{ |(k, v)|
87
+ NewRelic::Agent.agent.generate_environment_report
88
+ assert NewRelic::Agent.agent.connect_settings[:environment].detect{ |(k, _)|
88
89
  k == 'Gems'
89
90
  }, "expected connect_settings to include gems from environment"
90
91
  end
91
92
 
92
93
  def test_environment_for_connect_negative
93
94
  with_config(:send_environment_info => false) do
95
+ NewRelic::Agent.agent.generate_environment_report
94
96
  assert_equal [], NewRelic::Agent.agent.connect_settings[:environment]
95
97
  end
96
98
  end
97
99
 
98
100
  def test_connect_settings
99
- control = mocked_control
100
101
  NewRelic::Agent.config.expects(:app_names)
101
- self.expects(:environment_for_connect)
102
102
  keys = %w(pid host app_name language agent_version environment settings)
103
103
  value = connect_settings
104
104
  keys.each do |k|
@@ -51,6 +51,7 @@ class NewRelic::Agent::Agent::StartTest < Test::Unit::TestCase
51
51
  end
52
52
 
53
53
  def test_check_config_and_start_agent_normal
54
+ self.expects(:generate_environment_report)
54
55
  self.expects(:start_worker_thread)
55
56
  self.expects(:install_exit_handler)
56
57
  with_config(:sync_startup => false, :monitor_mode => true, :license_key => 'a' * 40) do
@@ -59,6 +60,7 @@ class NewRelic::Agent::Agent::StartTest < Test::Unit::TestCase
59
60
  end
60
61
 
61
62
  def test_check_config_and_start_agent_sync
63
+ self.expects(:generate_environment_report)
62
64
  self.expects(:connect_in_foreground)
63
65
  self.expects(:start_worker_thread)
64
66
  self.expects(:install_exit_handler)
@@ -213,6 +213,16 @@ module NewRelic::Agent::Configuration
213
213
  assert_equal false, called
214
214
  end
215
215
 
216
+ def test_high_security_enables_strip_exception_messages
217
+ @manager.apply_config(:high_security => true)
218
+
219
+ assert_truthy @manager[:'strip_exception_messages.enabled']
220
+ end
221
+
222
+ def test_stripped_exceptions_whitelist_contains_only_valid_exception_classes
223
+ @manager.apply_config(:'strip_exception_messages.whitelist' => 'LocalJumpError, NonExistentException')
224
+ assert_equal [LocalJumpError], @manager.stripped_exceptions_whitelist
225
+ end
216
226
 
217
227
  def test_should_log_when_applying
218
228
  expects_logging(:debug, anything, includes("asdf"))
@@ -36,7 +36,8 @@ class NewRelic::Agent::ErrorCollectorTest < Test::Unit::TestCase
36
36
  assert_equal '', err.params[:request_uri]
37
37
  assert_equal '', err.params[:request_referer]
38
38
  assert_equal 'path', err.path
39
- assert_equal 'Error', err.exception_class
39
+ assert_equal 'Error', err.exception_name_for_collector
40
+ assert_equal String, err.exception_class
40
41
  end
41
42
 
42
43
  def test_simple
@@ -50,10 +51,11 @@ class NewRelic::Agent::ErrorCollectorTest < Test::Unit::TestCase
50
51
  err = errors.first
51
52
  assert_equal 'message', err.message
52
53
  assert_equal 'y', err.params[:request_params][:x]
53
- assert err.params[:request_uri] == '/myurl/'
54
- assert err.params[:request_referer] == "test_referer"
55
- assert err.path == 'path'
56
- assert err.exception_class == 'StandardError'
54
+ assert_equal '/myurl/', err.params[:request_uri]
55
+ assert_equal 'test_referer', err.params[:request_referer]
56
+ assert_equal 'path', err.path
57
+ assert_equal StandardError, err.exception_class
58
+ assert_equal 'StandardError', err.exception_name_for_collector
57
59
 
58
60
  # the collector should now return an empty array since nothing
59
61
  # has been added since its last harvest
@@ -183,10 +185,8 @@ class NewRelic::Agent::ErrorCollectorTest < Test::Unit::TestCase
183
185
  old_errors = []
184
186
  errors = @error_collector.harvest_errors([])
185
187
 
186
- assert_equal('YO SQL BAD: serect * flom test where foo = ?',
187
- errors[0].message)
188
- assert_equal('YO SQL BAD: serect * flom test where foo in (?,?,?,?,?)',
189
- errors[1].message)
188
+ assert_equal(NewRelic::NoticedError::STRIPPED_EXCEPTION_REPLACEMENT_MESSAGE, errors[0].message)
189
+ assert_equal(NewRelic::NoticedError::STRIPPED_EXCEPTION_REPLACEMENT_MESSAGE, errors[1].message)
190
190
  end
191
191
  end
192
192
 
@@ -92,9 +92,16 @@ class NewRelic::Agent::MethodTracerTest < Test::Unit::TestCase
92
92
  assert_equal '12345', TestModuleWithLog.other_method
93
93
  end
94
94
 
95
+ def test_record_metrics_does_not_raise_outside_transaction
96
+ assert_nothing_raised do
97
+ NewRelic::Agent::MethodTracer::InstanceMethods::TraceExecutionScoped.record_metrics('a', ['b'], 12, 10, :metric => true)
98
+ end
99
+ expected = { :call_count => 1, :total_call_time => 12, :total_exclusive_time => 10 }
100
+ assert_metrics_recorded('a' => expected, 'b' => expected)
101
+ end
102
+
95
103
  def test_trace_execution_scoped_records_metric_data
96
104
  metric = "hello"
97
- freeze_time
98
105
  self.class.trace_execution_scoped(metric) do
99
106
  advance_time 0.05
100
107
  end
@@ -132,6 +132,16 @@ class NewRelic::Agent::RequestSamplerTest < Test::Unit::TestCase
132
132
  end
133
133
  end
134
134
 
135
+ def test_limits_total_sample_count_even_without_throttle
136
+ freeze_time
137
+ with_sampler_config( :'request_sampler.sample_rate_ms' => 60_000 ) do
138
+ 15.times do
139
+ @event_listener.notify( :transaction_finished, 'Controller/foo/bar', 0.1)
140
+ advance_time(60.001)
141
+ end
142
+ assert_equal(10, @sampler.samples.size)
143
+ end
144
+ end
135
145
 
136
146
  #
137
147
  # Helpers
@@ -120,10 +120,8 @@ class NewRelic::Agent::MetricStatsTest < Test::Unit::TestCase
120
120
  in_transaction('scopey') do
121
121
  @engine.record_metrics('foo', 42)
122
122
  end
123
- unscoped_stats = @engine.get_stats('foo', false)
124
- scoped_stats = @engine.get_stats('foo', true, true, 'scopey')
125
- assert_equal(1, unscoped_stats.call_count)
126
- assert_equal(0, scoped_stats.call_count)
123
+ assert_metrics_recorded('foo' => { :call_count => 1, :total_call_time => 42 })
124
+ assert_metrics_not_recorded([['foo', 'scopey']])
127
125
  end
128
126
 
129
127
  def test_record_metrics_records_to_scoped_metric_if_requested
@@ -193,4 +191,42 @@ class NewRelic::Agent::MetricStatsTest < Test::Unit::TestCase
193
191
 
194
192
  assert_equal 1, @engine.lookup_stats('foo').call_count
195
193
  end
194
+
195
+ def test_record_supportability_metric_timed_records_duration_of_block
196
+ freeze_time
197
+ 2.times do
198
+ @engine.record_supportability_metric_timed('foo/bar') { advance_time(2.0) }
199
+ end
200
+
201
+ assert_metrics_recorded(['Supportability/foo/bar'] => {
202
+ :call_count => 2,
203
+ :total_call_time => 4.0
204
+ })
205
+ end
206
+
207
+ def test_record_supportability_metric_timed_does_not_break_when_block_raises
208
+ begin
209
+ freeze_time
210
+ @engine.record_supportability_metric_timed('foo/bar') do
211
+ advance_time(2.0)
212
+ 1 / 0
213
+ end
214
+ rescue ZeroDivisionError
215
+ nil
216
+ end
217
+
218
+ assert_metrics_recorded(['Supportability/foo/bar'] => {
219
+ :call_count => 1,
220
+ :total_call_time => 2.0
221
+ })
222
+ end
223
+
224
+ def test_record_supportability_metric_count_records_counts_only
225
+ @engine.record_supportability_metric_count('foo/bar', 1)
226
+ @engine.record_supportability_metric_count('foo/bar', 42)
227
+ assert_metrics_recorded(['Supportability/foo/bar'] => {
228
+ :call_count => 42,
229
+ :total_call_time => 0
230
+ })
231
+ end
196
232
  end
@@ -215,4 +215,27 @@ class NewRelic::Agent::TransactionTest < Test::Unit::TestCase
215
215
 
216
216
  assert_equal 2.1, options[:web_duration]
217
217
  end
218
+
219
+ def test_parent_returns_parent_transaction_if_there_is_one
220
+ txn, outer_txn = nil
221
+ in_transaction('outer') do
222
+ outer_txn = NewRelic::Agent::Transaction.current
223
+ in_transaction('inner') do
224
+ txn = NewRelic::Agent::Transaction.parent
225
+ end
226
+ end
227
+ assert_same(outer_txn, txn)
228
+ end
229
+
230
+ def test_parent_returns_nil_if_there_is_no_parent
231
+ txn = 'this is a non-nil placeholder'
232
+ in_transaction('outer') do
233
+ txn = NewRelic::Agent::Transaction.parent
234
+ end
235
+ assert_nil(txn)
236
+ end
237
+
238
+ def test_parent_returns_nil_if_outside_transaction_entirely
239
+ assert_nil(NewRelic::Agent::Transaction.parent)
240
+ end
218
241
  end
@@ -4,6 +4,10 @@
4
4
 
5
5
  require File.expand_path(File.join(File.dirname(__FILE__),'..','test_helper'))
6
6
 
7
+ class NoticedErrorTestException < StandardError; end
8
+ class ParentException < Exception; end
9
+ class ChildException < ParentException; end
10
+
7
11
  class NewRelic::Agent::NoticedErrorTest < Test::Unit::TestCase
8
12
  def setup
9
13
  @path = 'foo/bar/baz'
@@ -12,10 +16,10 @@ class NewRelic::Agent::NoticedErrorTest < Test::Unit::TestCase
12
16
  end
13
17
 
14
18
  def test_to_collector_array
15
- e = Exception.new('test exception')
19
+ e = NoticedErrorTestException.new('test exception')
16
20
  error = NewRelic::NoticedError.new(@path, @params, e, @time)
17
21
  expected = [
18
- (@time.to_f * 1000).round, @path, 'test exception', 'Exception', @params
22
+ (@time.to_f * 1000).round, @path, 'test exception', 'NoticedErrorTestException', @params
19
23
  ]
20
24
  assert_equal expected, error.to_collector_array
21
25
  end
@@ -33,4 +37,82 @@ class NewRelic::Agent::NoticedErrorTest < Test::Unit::TestCase
33
37
  error = NewRelic::NoticedError.new(@path, @params, e, @time)
34
38
  assert_equal(String, error.message.class)
35
39
  end
40
+
41
+ def test_strips_message_from_exceptions_in_high_security_mode
42
+ with_config(:high_security => true) do
43
+ e = NoticedErrorTestException.new('test exception')
44
+ error = NewRelic::NoticedError.new(@path, @params, e, @time)
45
+
46
+ assert_equal NewRelic::NoticedError::STRIPPED_EXCEPTION_REPLACEMENT_MESSAGE, error.message
47
+ end
48
+ end
49
+
50
+ def test_permits_messages_from_whitelisted_exceptions_in_high_security_mode
51
+ with_config(:'strip_exception_messages.whitelist' => 'NoticedErrorTestException') do
52
+ e = NoticedErrorTestException.new('whitelisted test exception')
53
+ error = NewRelic::NoticedError.new(@path, @params, e, @time)
54
+
55
+ assert_equal 'whitelisted test exception', error.message
56
+ end
57
+ end
58
+
59
+ def test_whitelisted_returns_nil_with_an_empty_whitelist
60
+ with_config(:'strip_exception_messages.whitelist' => '') do
61
+ e = NoticedErrorTestException.new('whitelisted test exception')
62
+ error = NewRelic::NoticedError.new(@path, @params, e, @time)
63
+
64
+ assert_falsy error.whitelisted?
65
+ end
66
+ end
67
+
68
+ def test_whitelisted_returns_nil_when_error_is_not_in_whitelist
69
+ with_config(:'strip_exception_messages.whitelist' => 'YourErrorIsInAnotherCastle') do
70
+ e = NoticedErrorTestException.new('whitelisted test exception')
71
+ error = NewRelic::NoticedError.new(@path, @params, e, @time)
72
+
73
+ assert_falsy error.whitelisted?
74
+ end
75
+ end
76
+
77
+ def test_whitelisted_is_true_when_error_is_in_whitelist
78
+ with_config(:'strip_exception_messages.whitelist' => 'OtherException,NoticedErrorTestException') do
79
+ test_exception_class = NoticedErrorTestException
80
+ e = test_exception_class.new('whitelisted test exception')
81
+ error = NewRelic::NoticedError.new(@path, @params, e, @time)
82
+
83
+ assert_truthy error.whitelisted?
84
+ end
85
+ end
86
+
87
+ def test_whitelisted_ignores_nonexistent_exception_types_in_whitelist
88
+ with_config(:'strip_exception_messages.whitelist' => 'NonExistent::Exception,NoticedErrorTestException') do
89
+ test_exception_class = NoticedErrorTestException
90
+ e = test_exception_class.new('whitelisted test exception')
91
+ error = NewRelic::NoticedError.new(@path, @params, e, @time)
92
+
93
+ assert_truthy error.whitelisted?
94
+ end
95
+ end
96
+
97
+ def test_whitelisted_is_true_when_an_exceptions_ancestor_is_whitelisted
98
+ with_config(:'strip_exception_messages.whitelist' => 'ParentException') do
99
+ e = ChildException.new('whitelisted test exception')
100
+ error = NewRelic::NoticedError.new(@path, @params, e, @time)
101
+
102
+ assert_truthy error.whitelisted?
103
+ end
104
+ end
105
+
106
+ def test_exception_name_for_collector_returns_error_for_non_exceptions
107
+ error = NewRelic::NoticedError.new(@path, @params, nil, @time)
108
+
109
+ assert_equal 'Error', error.exception_name_for_collector
110
+ end
111
+
112
+ def test_exception_name_for_collector_returns_class_name_for_exceptions
113
+ e = NoticedErrorTestException.new('test exception')
114
+ error = NewRelic::NoticedError.new(@path, @params, e, @time)
115
+
116
+ assert_equal 'NoticedErrorTestException', error.exception_name_for_collector
117
+ end
36
118
  end
data/test/test_helper.rb CHANGED
@@ -86,7 +86,8 @@ def default_service(stubbed_method_overrides = {})
86
86
  :error_data => nil,
87
87
  :transaction_sample_data => nil,
88
88
  :sql_trace_data => nil,
89
- :get_agent_commands => []
89
+ :get_agent_commands => [],
90
+ :analytic_event_data => nil
90
91
  }
91
92
 
92
93
  service.stubs(stubbed_method_defaults.merge(stubbed_method_overrides))
@@ -108,21 +109,6 @@ class Test::Unit::TestCase
108
109
  end
109
110
  end
110
111
 
111
- def with_config(config_hash, opts={})
112
- opts = { :level => 0, :do_not_cast => false }.merge(opts)
113
- if opts[:do_not_cast]
114
- config = config_hash
115
- else
116
- config = NewRelic::Agent::Configuration::DottedHash.new(config_hash)
117
- end
118
- NewRelic::Agent.config.apply_config(config, opts[:level])
119
- begin
120
- yield
121
- ensure
122
- NewRelic::Agent.config.remove_config(config)
123
- end
124
- end
125
-
126
112
  def with_verbose_logging
127
113
  orig_logger = NewRelic::Agent.logger
128
114
  $stderr.puts '', '---', ''
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: newrelic_rpm
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.6.3.111
5
- prerelease:
4
+ version: 3.6.4.113.beta
5
+ prerelease: 10
6
6
  platform: ruby
7
7
  authors:
8
8
  - Jason Clark
@@ -41,7 +41,7 @@ cert_chain:
41
41
  cHUySWFQWE92bTNUOEc0TzZxWnZobkxoL1VpZW4rK0RqOGVGQmVjVFBvTThw
42
42
  VmpLM3BoNQpuL0V3dVpDY0U2Z2h0Q0NNCi0tLS0tRU5EIENFUlRJRklDQVRF
43
43
  LS0tLS0K
44
- date: 2013-06-06 00:00:00.000000000 Z
44
+ date: 2013-06-12 00:00:00.000000000 Z
45
45
  dependencies: []
46
46
  description: ! 'New Relic is a performance management system, developed by New Relic,
47
47
 
@@ -531,9 +531,14 @@ files:
531
531
  - lib/new_relic/build.rb
532
532
  homepage: http://www.github.com/newrelic/rpm
533
533
  licenses: []
534
- post_install_message: ! "# New Relic Ruby Agent Release Notes #\n\n## v3.6.3 ##\n\n*
535
- Better Sinatra Support\n\n A number of improvements have been made to our Sinatra
536
- instrumentation.\n More details: https://newrelic.com/docs/ruby/sinatra-support-in-the-ruby-agent\n\n
534
+ post_install_message: ! "# New Relic Ruby Agent Release Notes #\n\n## v3.6.4 ##\n\n*
535
+ Exception Whitelist\n\n We've improved exception message handling for applications
536
+ running in\n high security mode. Enabling 'high_security' now removes exception
537
+ messages\n entirely rather than simply obfuscating any SQL.\n\n By default this
538
+ feature affects all exceptions, though you can configure a\n whitelist of exceptions
539
+ whose messages should be left intact.\n\n More details: https://newrelic.com/docs/ruby/ruby-agent-configuration\n\n##
540
+ 3.6.3 ##\n\n* Better Sinatra Support\n\n A number of improvements have been made
541
+ to our Sinatra instrumentation.\n More details: https://newrelic.com/docs/ruby/sinatra-support-in-the-ruby-agent\n\n
537
542
  \ Sinatra instrumentation has been updated to more accurately reflect the final\n
538
543
  \ route that was actually executed, taking pass and conditions into account.\n\n
539
544
  \ New Relic middlewares for error collection, real user monitoring, and cross\n
metadata.gz.sig CHANGED
Binary file