newrelic_rpm 3.12.0.288 → 3.12.1.298

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +42 -0
  3. data/Rakefile +5 -5
  4. data/lib/new_relic/agent.rb +23 -11
  5. data/lib/new_relic/agent/agent.rb +17 -67
  6. data/lib/new_relic/agent/agent_logger.rb +9 -33
  7. data/lib/new_relic/agent/attribute_processing.rb +2 -2
  8. data/lib/new_relic/agent/autostart.rb +1 -18
  9. data/lib/new_relic/agent/aws_info.rb +90 -0
  10. data/lib/new_relic/agent/configuration/default_source.rb +45 -16
  11. data/lib/new_relic/agent/configuration/dotted_hash.rb +0 -2
  12. data/lib/new_relic/agent/configuration/high_security_source.rb +1 -1
  13. data/lib/new_relic/agent/configuration/manager.rb +1 -31
  14. data/lib/new_relic/agent/configuration/server_source.rb +0 -1
  15. data/lib/new_relic/agent/configuration/yaml_source.rb +26 -7
  16. data/lib/new_relic/agent/database.rb +5 -5
  17. data/lib/new_relic/agent/database/postgres_explain_obfuscator.rb +0 -1
  18. data/lib/new_relic/agent/datastores/metric_helper.rb +15 -3
  19. data/lib/new_relic/agent/error_collector.rb +28 -18
  20. data/lib/new_relic/agent/instrumentation/active_record.rb +8 -2
  21. data/lib/new_relic/agent/instrumentation/active_record_4.rb +1 -0
  22. data/lib/new_relic/agent/instrumentation/active_record_helper.rb +49 -1
  23. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +2 -2
  24. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +9 -0
  25. data/lib/new_relic/agent/instrumentation/grape.rb +1 -1
  26. data/lib/new_relic/agent/instrumentation/resque.rb +8 -20
  27. data/lib/new_relic/agent/instrumentation/sequel.rb +0 -2
  28. data/lib/new_relic/agent/instrumentation/sidekiq.rb +6 -0
  29. data/lib/new_relic/agent/log_once.rb +39 -0
  30. data/lib/new_relic/agent/memory_logger.rb +8 -1
  31. data/lib/new_relic/agent/method_tracer.rb +5 -1
  32. data/lib/new_relic/agent/new_relic_service.rb +13 -14
  33. data/lib/new_relic/agent/samplers/cpu_sampler.rb +1 -0
  34. data/lib/new_relic/agent/samplers/memory_sampler.rb +6 -3
  35. data/lib/new_relic/agent/sql_sampler.rb +4 -15
  36. data/lib/new_relic/agent/stats_engine/metric_stats.rb +1 -1
  37. data/lib/new_relic/agent/stats_engine/samplers.rb +0 -6
  38. data/lib/new_relic/agent/stats_engine/stats_hash.rb +92 -35
  39. data/lib/new_relic/agent/system_info.rb +53 -6
  40. data/lib/new_relic/agent/transaction.rb +4 -13
  41. data/lib/new_relic/agent/transaction/attributes.rb +2 -0
  42. data/lib/new_relic/agent/transaction/trace_node.rb +1 -1
  43. data/lib/new_relic/agent/transaction_event_aggregator.rb +1 -9
  44. data/lib/new_relic/agent/transaction_sample_builder.rb +0 -6
  45. data/lib/new_relic/agent/transaction_sampler.rb +1 -13
  46. data/lib/new_relic/agent/utilization_data.rb +29 -42
  47. data/lib/new_relic/agent/worker_loop.rb +2 -3
  48. data/lib/new_relic/cli/commands/deployments.rb +5 -0
  49. data/lib/new_relic/coerce.rb +1 -1
  50. data/lib/new_relic/collection_helper.rb +0 -2
  51. data/lib/new_relic/control/instance_methods.rb +4 -1
  52. data/lib/new_relic/control/instrumentation.rb +1 -9
  53. data/lib/new_relic/control/server_methods.rb +3 -56
  54. data/lib/new_relic/helper.rb +1 -0
  55. data/lib/new_relic/language_support.rb +21 -0
  56. data/lib/new_relic/local_environment.rb +1 -0
  57. data/lib/new_relic/metric_data.rb +1 -1
  58. data/lib/new_relic/noticed_error.rb +1 -1
  59. data/lib/new_relic/rack/agent_middleware.rb +9 -0
  60. data/lib/new_relic/version.rb +1 -1
  61. data/lib/sequel/extensions/newrelic_instrumentation.rb +2 -2
  62. data/lib/tasks/multiverse.rake +2 -0
  63. data/lib/tasks/multiverse.rb +50 -0
  64. data/test/agent_helper.rb +24 -5
  65. data/test/fixtures/cross_agent_tests/aws.json +218 -0
  66. data/test/fixtures/cross_agent_tests/docker_container_id/cases.json +40 -11
  67. data/test/fixtures/cross_agent_tests/docker_container_id/invalid-characters.txt +9 -0
  68. data/test/fixtures/cross_agent_tests/docker_container_id/invalid-length.txt +9 -0
  69. data/test/multiverse/lib/multiverse/suite.rb +3 -0
  70. data/test/multiverse/suites/active_record/Envfile +18 -12
  71. data/test/multiverse/suites/active_record/active_record_test.rb +203 -9
  72. data/test/multiverse/suites/active_record/app/models/models.rb +16 -9
  73. data/test/multiverse/suites/active_record/config/database.rb +3 -2
  74. data/test/multiverse/suites/active_record/db/migrate/20150413011200_add_timestamps_to_orders.rb +16 -0
  75. data/test/multiverse/suites/active_record/db/migrate/20150414084400_create_groups.rb +21 -0
  76. data/test/multiverse/suites/agent_only/agent_attributes_test.rb +26 -3
  77. data/test/multiverse/suites/agent_only/config/newrelic.yml +1 -1
  78. data/test/multiverse/suites/agent_only/script/public_api_when_disabled.rb +68 -0
  79. data/test/multiverse/suites/agent_only/service_timeout_test.rb +1 -1
  80. data/test/multiverse/suites/agent_only/ssl_test.rb +2 -1
  81. data/test/multiverse/suites/agent_only/start_up_test.rb +20 -1
  82. data/test/multiverse/suites/agent_only/utilization_data_collection_test.rb +43 -104
  83. data/test/multiverse/suites/bare/standalone_instrumentation_test.rb +2 -2
  84. data/test/multiverse/suites/high_security/high_security_test.rb +2 -2
  85. data/test/multiverse/suites/rack/http_response_code_test.rb +4 -4
  86. data/test/multiverse/suites/rails/error_tracing_test.rb +1 -1
  87. data/test/multiverse/suites/sidekiq/sidekiq_instrumentation_test.rb +38 -0
  88. data/test/multiverse/suites/sidekiq/test_worker.rb +13 -1
  89. data/test/new_relic/agent/agent_test.rb +0 -70
  90. data/test/new_relic/agent/attribute_processing_test.rb +10 -5
  91. data/test/new_relic/agent/autostart_test.rb +0 -31
  92. data/test/new_relic/agent/aws_info_test.rb +61 -0
  93. data/test/new_relic/agent/configuration/manager_test.rb +1 -1
  94. data/test/new_relic/agent/configuration/yaml_source_test.rb +25 -1
  95. data/test/new_relic/agent/database_test.rb +16 -15
  96. data/test/new_relic/agent/datastores/metric_helper_test.rb +35 -0
  97. data/test/new_relic/agent/error_collector_test.rb +28 -5
  98. data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +23 -20
  99. data/test/new_relic/agent/memory_logger_test.rb +18 -0
  100. data/test/new_relic/agent/new_relic_service_test.rb +2 -9
  101. data/test/new_relic/agent/rpm_agent_test.rb +0 -10
  102. data/test/new_relic/agent/sql_sampler_test.rb +4 -4
  103. data/test/new_relic/agent/stats_engine/stats_hash_test.rb +18 -22
  104. data/test/new_relic/agent/system_info_test.rb +81 -23
  105. data/test/new_relic/agent/transaction_event_aggregator_test.rb +0 -7
  106. data/test/new_relic/agent/transaction_test.rb +1 -1
  107. data/test/new_relic/agent/utilization_data_test.rb +135 -6
  108. data/test/new_relic/cli/commands/deployments_test.rb +12 -2
  109. data/test/new_relic/control/instrumentation_test.rb +0 -15
  110. data/test/new_relic/control_test.rb +0 -63
  111. data/test/new_relic/fake_collector.rb +4 -17
  112. data/test/new_relic/language_support_test.rb +30 -0
  113. data/test/new_relic/license_test.rb +2 -0
  114. data/test/new_relic/multiverse_helpers.rb +12 -0
  115. data/test/performance/suites/stats_hash.rb +6 -5
  116. data/test/test_helper.rb +1 -2
  117. metadata +13 -4
  118. data/lib/new_relic/agent/shim_agent.rb +0 -33
  119. data/test/new_relic/agent/shim_agent_test.rb +0 -20
@@ -10,7 +10,7 @@ development:
10
10
  app_name: test
11
11
  host: 127.0.0.1
12
12
  api_host: 127.0.0.1
13
- port: <%= $collector && $collector.port %>
13
+ port: <%= $collector ||= nil; $collector && $collector.port %>
14
14
  transaction_tracer:
15
15
  record_sql: obfuscated
16
16
  enabled: true
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+ # This file is distributed under New Relic's license terms.
4
+ # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
5
+
6
+ ENV["NEW_RELIC_LOG_FILE_PATH"] = "STDOUT"
7
+
8
+ # This file tries to require the minimum amount of the agent, and then call
9
+ # public API methods on it to ensure that they don't raise exceptions. It is
10
+ # expected to be called from a driver test which will check for failure in the
11
+ # status code and/or output.
12
+
13
+ require 'new_relic/agent'
14
+
15
+ NewRelic::Agent.record_metric("Custom/Record", 1)
16
+ NewRelic::Agent.increment_metric("Custom/Increment", 1)
17
+
18
+ NewRelic::Agent.require_test_helper
19
+ NewRelic::Agent.add_instrumentation("*_foobar.rb")
20
+
21
+ NewRelic::Agent.ignore_error_filter do
22
+ end
23
+
24
+ NewRelic::Agent.notice_error(StandardError.new("Always an option"))
25
+
26
+ NewRelic::Agent.record_custom_event(:DontStart, :dont => "even")
27
+
28
+ NewRelic::Agent.ignore_transaction
29
+ NewRelic::Agent.ignore_apdex
30
+ NewRelic::Agent.ignore_enduser
31
+
32
+ NewRelic::Agent.disable_all_tracing do
33
+ end
34
+
35
+ NewRelic::Agent.disable_transaction_tracing do
36
+ end
37
+
38
+ NewRelic::Agent.disable_sql_recording do
39
+ end
40
+
41
+ NewRelic::Agent.set_transaction_name("Something/Different")
42
+ NewRelic::Agent.get_transaction_name
43
+
44
+ NewRelic::Agent.with_database_metric_name("Model", "Method") do
45
+ end
46
+
47
+ NewRelic::Agent.set_sql_obfuscator do
48
+ end
49
+
50
+ NewRelic::Agent.browser_timing_header
51
+ NewRelic::Agent.browser_timing_footer
52
+
53
+ NewRelic::Agent.add_custom_attributes(:custom => "attributes")
54
+ NewRelic::Agent.add_custom_parameters(:custom => "parameters")
55
+ NewRelic::Agent.add_request_parameters(:request => "parameters")
56
+ NewRelic::Agent.set_user_attributes(:user => "attributes")
57
+
58
+ NewRelic::Agent.get_stats("Foo/Bar")
59
+ NewRelic::Agent.get_stats_no_scope("Foo/Bar")
60
+ NewRelic::Agent.reset_stats
61
+ NewRelic::Agent.drop_buffered_data
62
+
63
+ NewRelic::Agent.abort_transaction!
64
+
65
+ NewRelic::Agent.after_fork(options={})
66
+ NewRelic::Agent.shutdown(options={})
67
+
68
+ NewRelic::Agent::Deprecator.deprecate("SomeClass#old_method")
@@ -24,7 +24,7 @@ class ServiceTimeoutTest < Minitest::Test
24
24
  end
25
25
 
26
26
  def test_service_timeout
27
- server = NewRelic::Control::Server.new('localhost',@port,'127.0.0.1')
27
+ server = NewRelic::Control::Server.new('localhost', @port)
28
28
  NewRelic::Agent.config.add_config_for_testing(:timeout => 0.1)
29
29
 
30
30
  service = NewRelic::Agent::NewRelicService.new('deadbeef', server)
@@ -8,7 +8,8 @@ class SSLTest < Minitest::Test
8
8
 
9
9
  def setup
10
10
  # Similar to how jruby 1.6.8 behaves when jruby-openssl isn't installed
11
- Net::HTTPSession.any_instance.stubs('use_ssl=').raises(LoadError)
11
+ Net::HTTPSession.any_instance.stubs('use_ssl=').with(true).raises(LoadError)
12
+ Net::HTTPSession.any_instance.stubs('use_ssl=').with(false).returns(nil)
12
13
  end
13
14
 
14
15
  def test_agent_shuts_down_when_ssl_is_on_but_unavailable
@@ -6,6 +6,8 @@
6
6
  require 'open3'
7
7
 
8
8
  class StartUpTest < Minitest::Test
9
+ GIT_NOISE = "fatal: Not a git repository (or any of the parent directories): .git\n"
10
+
9
11
  def test_should_not_print_to_stdout_when_logging_available
10
12
  ruby = 'require "newrelic_rpm"; NewRelic::Agent.manual_start; NewRelic::Agent.shutdown'
11
13
  cmd = "bundle exec ruby -e '#{ruby}'"
@@ -16,7 +18,7 @@ class StartUpTest < Minitest::Test
16
18
  expected_noise = [
17
19
  "JRuby limited openssl loaded. http://jruby.org/openssl\n",
18
20
  "gem install jruby-openssl for full support.\n",
19
- "fatal: Not a git repository (or any of the parent directories): .git\n",
21
+ GIT_NOISE,
20
22
  /Exception\: java\.lang.*\n/]
21
23
 
22
24
  expected_noise.each {|noise| output.gsub!(noise, "")}
@@ -32,6 +34,10 @@ class StartUpTest < Minitest::Test
32
34
  assert_runs_without_errors("bundle exec ruby script/symbol_env.rb")
33
35
  end
34
36
 
37
+ def test_can_call_public_api_methods_when_agent_disabled
38
+ assert_runs_without_errors("bundle exec ruby script/public_api_when_disabled.rb")
39
+ end
40
+
35
41
  def test_manual_start_logs_about_mismatched_environment
36
42
  output = `bundle exec ruby script/env_change.rb`
37
43
 
@@ -46,8 +52,21 @@ class StartUpTest < Minitest::Test
46
52
  assert_equal('my great app', NewRelic::Agent.config[:app_name])
47
53
  end
48
54
 
55
+ # Older rubies have a lot of warnings that we don't care much about. Track it
56
+ # going forward from Ruby 2.1.
57
+ if RUBY_VERSION >= "2.1"
58
+ def test_no_warnings
59
+ output = `bundle exec ruby -w -r bundler/setup -r newrelic_rpm -e 'puts NewRelic::VERSION::STRING' 2>&1`
60
+ output.gsub!(GIT_NOISE, "")
61
+ output.chomp!
62
+
63
+ assert_equal NewRelic::VERSION::STRING, output
64
+ end
65
+ end
66
+
49
67
  def assert_runs_without_errors(command)
50
68
  output = `#{command}`
69
+ assert_equal 0, $?.exitstatus
51
70
 
52
71
  problems = output.scan(/ERROR : .*/)
53
72
  assert_empty problems
@@ -8,124 +8,63 @@ require 'fake_instance_metadata_service'
8
8
  class UtilizationDataCollectionTest < Minitest::Test
9
9
  include MultiverseHelpers
10
10
 
11
- setup_and_teardown_agent do
12
- $collector.stub('connect',
13
- {
14
- "agent_run_id" => 42,
15
- "collect_utilization" => true
11
+ def test_sends_all_utilization_data_on_connect
12
+ expected = {
13
+ "hostname" => "host",
14
+ "metadata_version" => 1,
15
+ "logical_processors" => 5,
16
+ "total_ram_mib" => 128,
17
+ "vendors" => {
18
+ "aws" => {
19
+ "id" => "i-e7e85ce1",
20
+ "type" => "m3.medium",
21
+ "zone" => "us-west-2b"
22
+ },
23
+ "docker" => {
24
+ "id"=>"47cbd16b77c50cbf71401"
25
+ }
16
26
  }
17
- )
18
- end
19
-
20
- def test_hostname
21
- NewRelic::Agent::Hostname.stubs(:get).returns("hostile")
22
- trigger_usage_data_collection_and_submission
23
-
24
- data = last_submitted_utilization_data
25
- assert_equal("hostile", data.hostname)
26
- end
27
-
28
- def test_gathers_instance_metadata
29
- instance_type = 'test.type'
30
-
31
- with_fake_metadata_service do |service|
32
- service.set_response_for_path('/2008-02-01/meta-data/instance-type', instance_type)
33
- trigger_usage_data_collection_and_submission
34
- end
35
-
36
- data = last_submitted_utilization_data
37
- assert_equal(instance_type, data.instance_type)
38
- end
27
+ }
39
28
 
40
- def test_omits_instance_metadata_if_contains_invalid_characters
41
- instance_type = '<script>lol</script>'
29
+ NewRelic::Agent::Hostname.stubs(:get).returns("host")
30
+ NewRelic::Agent::SystemInfo.stubs(:docker_container_id).returns("47cbd16b77c50cbf71401")
31
+ NewRelic::Agent::SystemInfo.stubs(:num_logical_processors).returns(5)
32
+ NewRelic::Agent::SystemInfo.stubs(:ram_in_mib).returns(128)
42
33
 
43
34
  with_fake_metadata_service do |service|
44
- service.set_response_for_path('/2008-02-01/meta-data/instance-type', instance_type)
45
- trigger_usage_data_collection_and_submission
46
- end
35
+ service.set_response_for_path('/2008-02-01/meta-data/instance-id', expected["vendors"]["aws"]["id"])
36
+ service.set_response_for_path('/2008-02-01/meta-data/instance-type', expected["vendors"]["aws"]["type"])
37
+ service.set_response_for_path('/2008-02-01/meta-data/placement/availability-zone', expected["vendors"]["aws"]["zone"])
47
38
 
48
- data = last_submitted_utilization_data
49
- assert_nil(data.instance_type)
50
- end
39
+ # this will trigger the agent to connect and send utilization data
40
+ setup_agent
51
41
 
52
- def test_omits_instance_metadata_if_too_long
53
- instance_type = 'a' * 1024
54
-
55
- with_fake_metadata_service do |service|
56
- service.set_response_for_path('/2008-02-01/meta-data/instance-type', instance_type)
57
- trigger_usage_data_collection_and_submission
42
+ assert_equal expected, single_connect_posted.utilization
58
43
  end
59
-
60
- data = last_submitted_utilization_data
61
- assert_nil(data.instance_type)
62
- end
63
-
64
- def test_gathers_cpu_metadata
65
- fake_processor_info = { :num_logical_processors => 8 }
66
- NewRelic::Agent::SystemInfo.stubs(:get_processor_info).returns(fake_processor_info)
67
-
68
- trigger_usage_data_collection_and_submission
69
-
70
- data = last_submitted_utilization_data
71
- assert_equal(fake_processor_info[:num_logical_processors], data.cpu_count)
72
- end
73
-
74
- def test_nil_cpu_values_reported
75
- fake_processor_info = { :num_logical_processors => nil }
76
- NewRelic::Agent::SystemInfo.stubs(:get_processor_info).returns(fake_processor_info)
77
-
78
- trigger_usage_data_collection_and_submission
79
-
80
- data = last_submitted_utilization_data
81
- assert_nil(data.cpu_count)
82
- end
83
-
84
- def test_gathers_docker_container_id
85
- NewRelic::Agent::SystemInfo.stubs(:docker_container_id).returns("whale")
86
-
87
- trigger_usage_data_collection_and_submission
88
-
89
- data = last_submitted_utilization_data
90
- assert_equal "whale", data.container_id
91
44
  end
92
45
 
93
- def test_nil_docker_container_id
94
- NewRelic::Agent::SystemInfo.stubs(:docker_container_id).returns(nil)
95
-
96
- trigger_usage_data_collection_and_submission
97
-
98
- data = last_submitted_utilization_data
99
- assert_nil data.container_id
100
- end
101
-
102
- def test_retries_upon_failure_to_submit_usage_data
103
- $collector.stub_exception('utilization_data', nil, 503).once
104
-
105
- trigger_usage_data_collection_and_submission
106
- first_attempt = last_submitted_utilization_data
107
-
108
- $collector.reset
109
-
110
- trigger_usage_data_collection_and_submission
111
- next_attempt = last_submitted_utilization_data
112
-
113
- assert_equal(first_attempt, next_attempt)
114
- end
46
+ def test_omits_sending_vendor_data_on_connect_when_not_available
47
+ expected = {
48
+ "hostname" => "host",
49
+ "metadata_version" => 1,
50
+ "logical_processors" => 5,
51
+ "total_ram_mib" => 128
52
+ }
115
53
 
116
- def last_submitted_utilization_data
117
- submissions = $collector.calls_for(:utilization_data)
118
- assert_equal(1, submissions.size)
54
+ NewRelic::Agent::Hostname.stubs(:get).returns("host")
55
+ NewRelic::Agent::SystemInfo.stubs(:num_logical_processors).returns(5)
56
+ NewRelic::Agent::SystemInfo.stubs(:ram_in_mib).returns(128)
119
57
 
120
- data = submissions.last
121
- assert_equal(4, data.body.size)
58
+ # this will trigger the agent to connect and send utilization data
59
+ setup_agent
122
60
 
123
- data
61
+ assert_equal expected, single_connect_posted.utilization
124
62
  end
125
63
 
126
- def trigger_usage_data_collection_and_submission
127
- if NewRelic::Agent.config[:collect_utilization]
128
- agent.send(:transmit_utilization_data)
64
+ def test_utilization_data_not_sent_when_disabled
65
+ with_config :disable_utilization => true do
66
+ setup_agent
67
+ assert_nil single_connect_posted.utilization, "Expected utilization data to be nil"
129
68
  end
130
69
  end
131
70
 
@@ -4,11 +4,11 @@
4
4
 
5
5
  # This test is based on the example code at:
6
6
  # https://docs.newrelic.com/docs/ruby/ruby-custom-metric-collection#example_class
7
- #
7
+ #
8
8
  # See https://newrelic.atlassian.net/browse/RUBY-1116 for details on how this
9
9
  # was broken previously.
10
10
 
11
- require 'new_relic/agent/method_tracer'
11
+ require 'new_relic/agent/method_tracer'
12
12
 
13
13
  class StandaloneInstrumentationTest < Minitest::Test
14
14
  class InstrumentedClass
@@ -165,7 +165,7 @@ class HighSecurityTest < Minitest::Test
165
165
 
166
166
  run_harvest
167
167
 
168
- expected = { "httpResponseCode" => 200 }
168
+ expected = { "httpResponseCode" => "200" }
169
169
  assert_equal expected, single_transaction_trace_posted.agent_attributes
170
170
  end
171
171
 
@@ -179,7 +179,7 @@ class HighSecurityTest < Minitest::Test
179
179
 
180
180
  run_harvest
181
181
 
182
- expected = { "httpResponseCode" => 500 }
182
+ expected = { "httpResponseCode" => "500" }
183
183
  assert_equal expected, single_error_posted.agent_attributes
184
184
  end
185
185
 
@@ -27,22 +27,22 @@ class HttpResponseCodeTest < Minitest::Test
27
27
  def test_records_http_response_code_on_analytics_events
28
28
  rsp = get '/', { 'override-response-code' => 404 }
29
29
  assert_equal(404, rsp.status)
30
- assert_equal('404', get_last_analytics_event[0]['httpResponseCode'])
30
+ assert_equal("404", get_last_analytics_event[2][:httpResponseCode])
31
31
 
32
32
  rsp = get '/', { 'override-response-code' => 302 }
33
33
  assert_equal(302, rsp.status)
34
- assert_equal('302', get_last_analytics_event[0]['httpResponseCode'])
34
+ assert_equal("302", get_last_analytics_event[2][:httpResponseCode])
35
35
  end
36
36
 
37
37
  def test_skips_http_response_code_if_middleware_tracing_disabled
38
38
  with_config(:disable_middleware_instrumentation => true) do
39
39
  rsp = get '/', { 'override-response-code' => 404 }
40
40
  assert_equal(404, rsp.status)
41
- assert_nil get_last_analytics_event[0]['httpResponseCode']
41
+ assert_nil get_last_analytics_event[2][:httpResponseCode]
42
42
 
43
43
  rsp = get '/', { 'override-response-code' => 302 }
44
44
  assert_equal(302, rsp.status)
45
- assert_nil get_last_analytics_event[0]['httpResponseCode']
45
+ assert_nil get_last_analytics_event[2][:httpResponseCode]
46
46
  end
47
47
  end
48
48
  end
@@ -117,7 +117,7 @@ class ErrorsWithoutSSCTest < RailsMultiverseTest
117
117
 
118
118
  expected_params = {
119
119
  'request.parameters.eat' => 'static',
120
- 'httpResponseCode' => 500
120
+ 'httpResponseCode' => '500'
121
121
  }
122
122
 
123
123
  attributes = agent_attributes_for_single_error_posted
@@ -122,6 +122,30 @@ class SidekiqTest < Minitest::Test
122
122
  assert_attributes_on_events
123
123
  end
124
124
 
125
+ def test_captures_errors_from_job
126
+ TestWorker.fail = true
127
+ run_jobs
128
+ assert_error_for_each_job
129
+ ensure
130
+ TestWorker.fail = false
131
+ end
132
+
133
+ # In <= 2.x of Sidekiq, internal errors (or potentially errors further out
134
+ # the middleware stack) wouldn't get noticed, but there was no propery hook
135
+ # to catch it. 3.x+ gives us a error_handler, so only add our misbehaving
136
+ # middleware for those cases.
137
+ if Sidekiq::VERSION >= '3'
138
+ def test_captures_sidekiq_internal_errors
139
+ # Ugly, but need to coerce an internal error in Sidekiq that doesn't bail
140
+ # from processing entirely. This fouls up Sidekiq::Processor#stats in a
141
+ # spot that calls handle exception but doesn't die.
142
+ Redis.any_instance.stubs(:hmset).raises("Uh oh")
143
+ run_jobs
144
+
145
+ assert_error_for_each_job(nil)
146
+ end
147
+ end
148
+
125
149
  def assert_metric_and_call_count(name, expected_call_count)
126
150
  metric_data = $collector.calls_for('metric_data')
127
151
  assert_equal(1, metric_data.size, "expected exactly one metric_data post from agent")
@@ -178,4 +202,18 @@ class SidekiqTest < Minitest::Test
178
202
  end
179
203
  end
180
204
  end
205
+
206
+ def assert_error_for_each_job(txn_name=TRANSACTION_NAME)
207
+ error_posts = $collector.calls_for("error_data")
208
+ assert_equal 1, error_posts.length, "Wrong number of error posts!"
209
+
210
+ errors = error_posts.first
211
+ assert_equal JOB_COUNT, errors.errors.length, "Wrong number of errors noticed!"
212
+
213
+ assert_metric_and_call_count('Errors/all', JOB_COUNT)
214
+ if txn_name
215
+ assert_metric_and_call_count('Errors/allOther', JOB_COUNT)
216
+ assert_metric_and_call_count("Errors/#{TRANSACTION_NAME}", JOB_COUNT)
217
+ end
218
+ end
181
219
  end
@@ -53,7 +53,19 @@ class TestWorker
53
53
  end
54
54
  end
55
55
 
56
+ def self.fail=(val)
57
+ @fail = val
58
+ end
59
+
60
+ def self.am_i_a_failure?
61
+ @fail
62
+ end
63
+
56
64
  def perform(key, val)
57
- TestWorker.record(key, val)
65
+ if self.class.am_i_a_failure?
66
+ raise "Uh oh"
67
+ else
68
+ TestWorker.record(key, val)
69
+ end
58
70
  end
59
71
  end