newrelic_rpm 6.5.0.357 → 6.10.0.364

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +65 -5
  4. data/CHANGELOG.md +243 -0
  5. data/Guardfile +18 -1
  6. data/lib/new_relic/agent.rb +89 -7
  7. data/lib/new_relic/agent/agent.rb +116 -57
  8. data/lib/new_relic/agent/agent_logger.rb +4 -0
  9. data/lib/new_relic/agent/attribute_filter.rb +7 -7
  10. data/lib/new_relic/agent/attributes.rb +150 -0
  11. data/lib/new_relic/agent/autostart.rb +19 -14
  12. data/lib/new_relic/agent/configuration/default_source.rb +132 -13
  13. data/lib/new_relic/agent/configuration/event_harvest_config.rb +11 -5
  14. data/lib/new_relic/agent/configuration/manager.rb +13 -9
  15. data/lib/new_relic/agent/configuration/server_source.rb +3 -2
  16. data/lib/new_relic/agent/configuration/yaml_source.rb +11 -6
  17. data/lib/new_relic/agent/connect/request_builder.rb +5 -13
  18. data/lib/new_relic/agent/connect/response_handler.rb +1 -1
  19. data/lib/new_relic/agent/database.rb +1 -2
  20. data/lib/new_relic/agent/datastores/mongo.rb +1 -1
  21. data/lib/new_relic/agent/datastores/mongo/event_formatter.rb +2 -2
  22. data/lib/new_relic/agent/datastores/mongo/obfuscator.rb +8 -8
  23. data/lib/new_relic/agent/distributed_tracing.rb +155 -6
  24. data/lib/new_relic/agent/{cross_app_payload.rb → distributed_tracing/cross_app_payload.rb} +0 -0
  25. data/lib/new_relic/agent/{cross_app_tracing.rb → distributed_tracing/cross_app_tracing.rb} +60 -45
  26. data/lib/new_relic/agent/distributed_tracing/distributed_trace_intrinsics.rb +80 -0
  27. data/lib/new_relic/agent/distributed_tracing/distributed_trace_metrics.rb +75 -0
  28. data/lib/new_relic/agent/{distributed_trace_payload.rb → distributed_tracing/distributed_trace_payload.rb} +23 -99
  29. data/lib/new_relic/agent/distributed_tracing/distributed_trace_transport_type.rb +39 -0
  30. data/lib/new_relic/agent/distributed_tracing/trace_context.rb +246 -0
  31. data/lib/new_relic/agent/distributed_tracing/trace_context_payload.rb +126 -0
  32. data/lib/new_relic/agent/error_collector.rb +35 -18
  33. data/lib/new_relic/agent/error_event_aggregator.rb +9 -6
  34. data/lib/new_relic/agent/error_trace_aggregator.rb +1 -0
  35. data/lib/new_relic/agent/event_aggregator.rb +26 -32
  36. data/lib/new_relic/agent/external.rb +7 -7
  37. data/lib/new_relic/agent/guid_generator.rb +28 -0
  38. data/lib/new_relic/agent/hostname.rb +7 -1
  39. data/lib/new_relic/agent/http_clients/abstract.rb +82 -0
  40. data/lib/new_relic/agent/http_clients/curb_wrappers.rb +24 -19
  41. data/lib/new_relic/agent/http_clients/excon_wrappers.rb +28 -13
  42. data/lib/new_relic/agent/http_clients/http_rb_wrappers.rb +17 -21
  43. data/lib/new_relic/agent/http_clients/httpclient_wrappers.rb +10 -11
  44. data/lib/new_relic/agent/http_clients/net_http_wrappers.rb +16 -4
  45. data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +4 -6
  46. data/lib/new_relic/agent/http_clients/uri_util.rb +3 -2
  47. data/lib/new_relic/agent/instrumentation/action_cable_subscriber.rb +5 -7
  48. data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +4 -0
  49. data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +11 -2
  50. data/lib/new_relic/agent/instrumentation/active_record.rb +4 -2
  51. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +7 -2
  52. data/lib/new_relic/agent/instrumentation/active_storage_subscriber.rb +8 -4
  53. data/lib/new_relic/agent/instrumentation/bunny.rb +45 -28
  54. data/lib/new_relic/agent/instrumentation/curb.rb +59 -18
  55. data/lib/new_relic/agent/instrumentation/data_mapper.rb +3 -1
  56. data/lib/new_relic/agent/instrumentation/excon.rb +1 -1
  57. data/lib/new_relic/agent/instrumentation/excon/connection.rb +6 -3
  58. data/lib/new_relic/agent/instrumentation/excon/middleware.rb +2 -1
  59. data/lib/new_relic/agent/instrumentation/grape.rb +5 -10
  60. data/lib/new_relic/agent/instrumentation/http.rb +6 -3
  61. data/lib/new_relic/agent/instrumentation/httpclient.rb +5 -3
  62. data/lib/new_relic/agent/instrumentation/memcache.rb +3 -1
  63. data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +6 -2
  64. data/lib/new_relic/agent/instrumentation/mongo.rb +9 -3
  65. data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +13 -0
  66. data/lib/new_relic/agent/instrumentation/net.rb +6 -3
  67. data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +25 -1
  68. data/lib/new_relic/agent/instrumentation/rails_notifications/action_cable.rb +2 -3
  69. data/lib/new_relic/agent/instrumentation/redis.rb +9 -3
  70. data/lib/new_relic/agent/instrumentation/resque.rb +3 -0
  71. data/lib/new_relic/agent/instrumentation/sidekiq.rb +0 -1
  72. data/lib/new_relic/agent/instrumentation/typhoeus.rb +23 -6
  73. data/lib/new_relic/agent/javascript_instrumentor.rb +1 -1
  74. data/lib/new_relic/agent/logging.rb +139 -0
  75. data/lib/new_relic/agent/messaging.rb +5 -73
  76. data/lib/new_relic/agent/method_tracer.rb +3 -2
  77. data/lib/new_relic/agent/method_tracer_helpers.rb +2 -2
  78. data/lib/new_relic/agent/monitors.rb +27 -0
  79. data/lib/new_relic/agent/monitors/cross_app_monitor.rb +110 -0
  80. data/lib/new_relic/agent/monitors/distributed_tracing_monitor.rb +27 -0
  81. data/lib/new_relic/agent/{inbound_request_monitor.rb → monitors/inbound_request_monitor.rb} +3 -3
  82. data/lib/new_relic/agent/{synthetics_monitor.rb → monitors/synthetics_monitor.rb} +2 -4
  83. data/lib/new_relic/agent/new_relic_service.rb +7 -5
  84. data/lib/new_relic/agent/noticible_error.rb +22 -0
  85. data/lib/new_relic/agent/span_event_aggregator.rb +2 -4
  86. data/lib/new_relic/agent/span_event_primitive.rb +82 -53
  87. data/lib/new_relic/agent/sql_sampler.rb +3 -3
  88. data/lib/new_relic/agent/supported_versions.rb +2 -2
  89. data/lib/new_relic/agent/tracer.rb +65 -18
  90. data/lib/new_relic/agent/transaction.rb +84 -79
  91. data/lib/new_relic/agent/transaction/abstract_segment.rb +28 -2
  92. data/lib/new_relic/agent/transaction/distributed_tracer.rb +171 -0
  93. data/lib/new_relic/agent/transaction/distributed_tracing.rb +57 -146
  94. data/lib/new_relic/agent/transaction/external_request_segment.rb +29 -36
  95. data/lib/new_relic/agent/transaction/message_broker_segment.rb +3 -11
  96. data/lib/new_relic/agent/transaction/segment.rb +7 -1
  97. data/lib/new_relic/agent/transaction/trace.rb +2 -4
  98. data/lib/new_relic/agent/transaction/trace_context.rb +168 -0
  99. data/lib/new_relic/agent/transaction/trace_node.rb +10 -8
  100. data/lib/new_relic/agent/transaction_error_primitive.rb +10 -15
  101. data/lib/new_relic/agent/transaction_event_primitive.rb +28 -39
  102. data/lib/new_relic/agent/transaction_event_recorder.rb +3 -3
  103. data/lib/new_relic/cli/commands/deployments.rb +1 -1
  104. data/lib/new_relic/cli/commands/install.rb +3 -2
  105. data/lib/new_relic/coerce.rb +31 -6
  106. data/lib/new_relic/constants.rb +34 -0
  107. data/lib/new_relic/control/instance_methods.rb +10 -1
  108. data/lib/new_relic/dependency_detection.rb +4 -4
  109. data/lib/new_relic/noticed_error.rb +38 -17
  110. data/lib/new_relic/rack/browser_monitoring.rb +5 -0
  111. data/lib/new_relic/supportability_helper.rb +14 -0
  112. data/lib/new_relic/version.rb +1 -1
  113. data/lib/tasks/multiverse.rb +25 -0
  114. data/lib/tasks/tests.rake +6 -1
  115. data/newrelic_rpm.gemspec +16 -5
  116. data/test/agent_helper.rb +329 -70
  117. data/true +0 -0
  118. metadata +98 -30
  119. data/lib/new_relic/agent/cross_app_monitor.rb +0 -110
  120. data/lib/new_relic/agent/distributed_trace_monitor.rb +0 -40
  121. data/lib/new_relic/agent/http_clients/abstract_request.rb +0 -31
  122. data/lib/new_relic/agent/transaction/attributes.rb +0 -154
  123. data/lib/tasks/versions.html.erb +0 -28
  124. data/lib/tasks/versions.postface.html +0 -8
  125. data/lib/tasks/versions.preface.html +0 -9
  126. data/lib/tasks/versions.rake +0 -65
  127. data/lib/tasks/versions.txt.erb +0 -14
@@ -140,7 +140,9 @@ module NewRelic
140
140
  )
141
141
 
142
142
  begin
143
- self.send("#{method_name}_without_newrelic", *args, &blk)
143
+ NewRelic::Agent::Tracer.capture_segment_error segment do
144
+ self.send("#{method_name}_without_newrelic", *args, &blk)
145
+ end
144
146
  rescue ::DataObjects::ConnectionError => e
145
147
  raise
146
148
  rescue ::DataObjects::SQLError => e
@@ -42,7 +42,7 @@ DependencyDetection.defer do
42
42
  end
43
43
 
44
44
  def install_excon_instrumentation(excon_version)
45
- require 'new_relic/agent/cross_app_tracing'
45
+ require 'new_relic/agent/distributed_tracing/cross_app_tracing'
46
46
  require 'new_relic/agent/http_clients/excon_wrappers'
47
47
 
48
48
  if excon_version >= EXCON_MIDDLEWARE_MIN_VERSION
@@ -4,8 +4,9 @@
4
4
 
5
5
  module ::Excon
6
6
  class Connection
7
+ # @connection is deprecated in newer excon versions and replaced with @data
7
8
  def newrelic_connection_params
8
- (@connection || @data)
9
+ (@data || @connection)
9
10
  end
10
11
 
11
12
  def newrelic_resolved_request_params(request_params)
@@ -27,10 +28,12 @@ module ::Excon
27
28
  response = nil
28
29
  segment.add_request_headers wrapped_request
29
30
 
30
- response = request_without_newrelic_trace(resolved_params, &block)
31
+ response = NewRelic::Agent::Tracer.capture_segment_error segment do
32
+ request_without_newrelic_trace(resolved_params, &block)
33
+ end
31
34
 
32
35
  wrapped_response = ::NewRelic::Agent::HTTPClients::ExconHTTPResponse.new(response)
33
- segment.read_response_headers wrapped_response
36
+ segment.process_response_headers wrapped_response
34
37
 
35
38
  response
36
39
  ensure
@@ -49,11 +49,12 @@ module ::Excon
49
49
  segment = datum[:connection] && datum[:connection].instance_variable_get(TRACE_DATA_IVAR)
50
50
  if segment
51
51
  begin
52
+ segment.notice_error(datum[:error]) if datum[:error]
52
53
  datum[:connection].instance_variable_set(TRACE_DATA_IVAR, nil)
53
54
 
54
55
  if datum[:response]
55
56
  wrapped_response = ::NewRelic::Agent::HTTPClients::ExconHTTPResponse.new(datum[:response])
56
- segment.read_response_headers wrapped_response
57
+ segment.process_response_headers wrapped_response
57
58
  end
58
59
  ensure
59
60
  segment.finish if segment
@@ -14,7 +14,6 @@ module NewRelic
14
14
  API_VERSION = 'api.version'.freeze
15
15
  FORMAT_REGEX = /\(\/?\.[\:\w]*\)/.freeze # either :format (< 0.12.0) or .ext (>= 0.12.0)
16
16
  VERSION_REGEX = /:version(\/|$)/.freeze
17
- EMPTY_STRING = ''.freeze
18
17
  MIN_VERSION = Gem::Version.new("0.2.0")
19
18
  PIPE_STRING = '|'.freeze
20
19
 
@@ -33,7 +32,7 @@ module NewRelic
33
32
  end
34
33
 
35
34
  def name_for_transaction(route, class_name, version)
36
- action_name = route.path.sub(FORMAT_REGEX, EMPTY_STRING)
35
+ action_name = route.path.sub(FORMAT_REGEX, NewRelic::EMPTY_STR)
37
36
  method_name = route.request_method
38
37
  version ||= route.version
39
38
 
@@ -42,7 +41,7 @@ module NewRelic
42
41
  version = version.join(PIPE_STRING) if Array === version
43
42
 
44
43
  if version
45
- action_name = action_name.sub(VERSION_REGEX, EMPTY_STRING)
44
+ action_name = action_name.sub(VERSION_REGEX, NewRelic::EMPTY_STR)
46
45
  "#{class_name}-#{version}#{action_name} (#{method_name})"
47
46
  else
48
47
  "#{class_name}#{action_name} (#{method_name})"
@@ -50,12 +49,12 @@ module NewRelic
50
49
  end
51
50
 
52
51
  def name_for_transaction_deprecated(route, class_name, version)
53
- action_name = route.route_path.sub(FORMAT_REGEX, EMPTY_STRING)
52
+ action_name = route.route_path.sub(FORMAT_REGEX, NewRelic::EMPTY_STR)
54
53
  method_name = route.route_method
55
54
  version ||= route.route_version
56
55
 
57
56
  if version
58
- action_name = action_name.sub(VERSION_REGEX, EMPTY_STRING)
57
+ action_name = action_name.sub(VERSION_REGEX, NewRelic::EMPTY_STR)
59
58
  "#{class_name}-#{version}#{action_name} (#{method_name})"
60
59
  else
61
60
  "#{class_name}#{action_name} (#{method_name})"
@@ -118,11 +117,7 @@ DependencyDetection.defer do
118
117
 
119
118
  # Since 1.2.0, the class `Grape::API` no longer refers to an API instance, rather, what used to be `Grape::API` is `Grape::API::Instance`
120
119
  # https://github.com/ruby-grape/grape/blob/c20a73ac1e3f3ba1082005ed61bf69452373ba87/UPGRADING.md#upgrading-to--120
121
- grape_api_class = if defined?(Grape::API::Instance)
122
- ::Grape::API::Instance
123
- else
124
- ::Grape::API
125
- end
120
+ grape_api_class = defined?(Grape::API::Instance) ? ::Grape::API::Instance : ::Grape::API
126
121
 
127
122
  grape_api_class.class_eval do
128
123
  def call_with_new_relic(env)
@@ -11,7 +11,7 @@ DependencyDetection.defer do
11
11
 
12
12
  executes do
13
13
  ::NewRelic::Agent.logger.info 'Installing http.rb instrumentation'
14
- require 'new_relic/agent/cross_app_tracing'
14
+ require 'new_relic/agent/distributed_tracing/cross_app_tracing'
15
15
  require 'new_relic/agent/http_clients/http_rb_wrappers'
16
16
  end
17
17
 
@@ -29,9 +29,12 @@ DependencyDetection.defer do
29
29
 
30
30
  segment.add_request_headers wrapped_request
31
31
 
32
- response = perform_without_newrelic_trace(request, options)
32
+ response = NewRelic::Agent::Tracer.capture_segment_error segment do
33
+ perform_without_newrelic_trace(request, options)
34
+ end
35
+
33
36
  wrapped_response = ::NewRelic::Agent::HTTPClients::HTTPResponse.new response
34
- segment.read_response_headers wrapped_response
37
+ segment.process_response_headers wrapped_response
35
38
 
36
39
  response
37
40
  ensure
@@ -20,7 +20,7 @@ DependencyDetection.defer do
20
20
 
21
21
  executes do
22
22
  ::NewRelic::Agent.logger.info 'Installing HTTPClient instrumentation'
23
- require 'new_relic/agent/cross_app_tracing'
23
+ require 'new_relic/agent/distributed_tracing/cross_app_tracing'
24
24
  require 'new_relic/agent/http_clients/httpclient_wrappers'
25
25
  end
26
26
 
@@ -38,12 +38,14 @@ DependencyDetection.defer do
38
38
  response = nil
39
39
  segment.add_request_headers wrapped_request
40
40
 
41
- do_get_block_without_newrelic(req, proxy, conn, &block)
41
+ NewRelic::Agent::Tracer.capture_segment_error segment do
42
+ do_get_block_without_newrelic(req, proxy, conn, &block)
43
+ end
42
44
  response = conn.pop
43
45
  conn.push response
44
46
 
45
47
  wrapped_response = ::NewRelic::Agent::HTTPClients::HTTPClientResponse.new(response)
46
- segment.read_response_headers wrapped_response
48
+ segment.process_response_headers wrapped_response
47
49
 
48
50
  response
49
51
  ensure
@@ -46,7 +46,9 @@ module NewRelic
46
46
  operation: method_name
47
47
  )
48
48
  begin
49
- send method_name_without, *args, &block
49
+ NewRelic::Agent::Tracer.capture_segment_error segment do
50
+ send method_name_without, *args, &block
51
+ end
50
52
  ensure
51
53
  if NewRelic::Agent.config[:capture_memcache_keys]
52
54
  segment.notice_nosql_statement "#{method_name} #{args.first.inspect}"
@@ -66,7 +66,9 @@ module NewRelic
66
66
  ::NewRelic::Agent::Instrumentation::Memcache::Dalli.assign_instance_to(segment, self)
67
67
 
68
68
  begin
69
- send_multiget_without_newrelic_trace(keys)
69
+ NewRelic::Agent::Tracer.capture_segment_error segment do
70
+ send_multiget_without_newrelic_trace(keys)
71
+ end
70
72
  ensure
71
73
  if ::NewRelic::Agent.config[:capture_memcache_keys]
72
74
  segment.notice_nosql_statement "#{SEND_MULTIGET_METRIC_NAME} #{keys.inspect}"
@@ -87,7 +89,9 @@ module NewRelic
87
89
  define_method method_name do |*args, &block|
88
90
  segment = NewRelic::Agent::Tracer.start_segment name: "Ruby/Memcached/Dalli/#{method_name}"
89
91
  begin
90
- __send__ method_name_without, *args, &block
92
+ NewRelic::Agent::Tracer.capture_segment_error segment do
93
+ __send__ method_name_without, *args, &block
94
+ end
91
95
  ensure
92
96
  segment.finish if segment
93
97
  end
@@ -87,7 +87,9 @@ DependencyDetection.defer do
87
87
 
88
88
  begin
89
89
  result = NewRelic::Agent.disable_all_tracing do
90
- instrument_without_new_relic_trace(name, payload, &block)
90
+ NewRelic::Agent::Tracer.capture_segment_error segment do
91
+ instrument_without_new_relic_trace(name, payload, &block)
92
+ end
91
93
  end
92
94
 
93
95
  new_relic_notice_statement(segment, payload, name) if segment
@@ -109,7 +111,9 @@ DependencyDetection.defer do
109
111
 
110
112
  begin
111
113
  result = NewRelic::Agent.disable_all_tracing do
112
- save_without_new_relic_trace(doc, opts, &block)
114
+ NewRelic::Agent::Tracer.capture_segment_error segment do
115
+ save_without_new_relic_trace(doc, opts, &block)
116
+ end
113
117
  end
114
118
 
115
119
  new_relic_notice_statement(segment, doc, :save) if segment
@@ -131,7 +135,9 @@ DependencyDetection.defer do
131
135
 
132
136
  begin
133
137
  result = NewRelic::Agent.disable_all_tracing do
134
- ensure_index_without_new_relic_trace(spec, opts, &block)
138
+ NewRelic::Agent::Tracer.capture_segment_error segment do
139
+ ensure_index_without_new_relic_trace(spec, opts, &block)
140
+ end
135
141
  end
136
142
 
137
143
  spec = case spec
@@ -19,10 +19,23 @@ module NewRelic
19
19
  end
20
20
  end
21
21
 
22
+ ERROR_KEYS = %w{ writeErrors writeConcernError writeConcernErrors }.freeze
23
+
24
+ def error_present?(event)
25
+ if reply = event.reply
26
+ ERROR_KEYS.detect{ |key| reply[key] }
27
+ end
28
+ end
29
+
22
30
  def completed(event)
23
31
  begin
24
32
  return unless NewRelic::Agent::Tracer.tracing_enabled?
25
33
  segment = segments.delete(event.operation_id)
34
+ if segment && (error_key = error_present?(event))
35
+ # taking the last error as there can potentially be many
36
+ attributes = event.reply[error_key][-1]
37
+ segment.notice_error Mongo::Error.new("%s (%s)" % [attributes["errmsg"], attributes["code"]])
38
+ end
26
39
  segment.finish if segment
27
40
  rescue Exception => e
28
41
  log_notification_error('completed', e)
@@ -11,7 +11,7 @@ DependencyDetection.defer do
11
11
 
12
12
  executes do
13
13
  ::NewRelic::Agent.logger.info 'Installing Net instrumentation'
14
- require 'new_relic/agent/cross_app_tracing'
14
+ require 'new_relic/agent/distributed_tracing/cross_app_tracing'
15
15
  require 'new_relic/agent/http_clients/net_http_wrappers'
16
16
  end
17
17
 
@@ -33,10 +33,13 @@ DependencyDetection.defer do
33
33
  # RUBY-1244 Disable further tracing in request to avoid double
34
34
  # counting if connection wasn't started (which calls request again).
35
35
  NewRelic::Agent.disable_all_tracing do
36
- response = request_without_newrelic_trace( request, *args, &block )
36
+ response = NewRelic::Agent::Tracer.capture_segment_error segment do
37
+ request_without_newrelic_trace(request, *args, &block)
38
+ end
37
39
  end
38
40
 
39
- segment.read_response_headers response
41
+ wrapped_response = NewRelic::Agent::HTTPClients::NetHTTPResponse.new response
42
+ segment.process_response_headers wrapped_response
40
43
  response
41
44
  ensure
42
45
  segment.finish
@@ -8,6 +8,7 @@ module NewRelic
8
8
  class NotificationsSubscriber
9
9
  def initialize
10
10
  @queue_key = ['NewRelic', self.class.name, object_id].join('-')
11
+ define_exception_method
11
12
  end
12
13
 
13
14
  def self.subscribed?
@@ -22,7 +23,7 @@ module NewRelic
22
23
 
23
24
  notifier = ActiveSupport::Notifications.notifier
24
25
 
25
- instance_variable_names.each do |name|
26
+ instance_variable_names.each do |name|
26
27
  if notifier.instance_variable_defined?(name)
27
28
  subscribers = notifier.instance_variable_get(name)
28
29
  if subscribers.is_a? Array
@@ -69,6 +70,29 @@ module NewRelic
69
70
  def state
70
71
  NewRelic::Agent::Tracer.state
71
72
  end
73
+
74
+ def define_exception_method
75
+ # we don't expect this to be called more than once, but we're being
76
+ # defensive.
77
+ return if defined?(exception_object)
78
+ return unless defined?(::ActiveSupport)
79
+ if ::ActiveSupport::VERSION::STRING < "5.0.0"
80
+ # Earlier versions of Rails did not add the exception itself to the
81
+ # payload asssessible via :exception_object, so we create a stand-in
82
+ # error object from the given class name and message.
83
+ # NOTE: no backtrace available this way, but we can notice the error
84
+ # well enough to send the necessary info the UI requires to present it.
85
+ def exception_object(payload)
86
+ exception_class, message = payload[:exception]
87
+ return nil unless exception_class
88
+ NewRelic::Agent::NoticibleError.new exception_class, message
89
+ end
90
+ else
91
+ def exception_object(payload)
92
+ payload[:exception_object]
93
+ end
94
+ end
95
+ end
72
96
  end
73
97
 
74
98
  end
@@ -28,9 +28,8 @@ DependencyDetection.defer do
28
28
  NewRelic::Agent::Instrumentation::ActionCableSubscriber.new)
29
29
 
30
30
  ActiveSupport.on_load(:action_cable) do
31
- ::NewRelic::Agent::PrependSupportability.record_metrics_for(
32
- ::ActionCable::Engine,
33
- ::ActionCable::RemoteConnections)
31
+ ::NewRelic::Agent::PrependSupportability.record_metrics_for(::ActionCable::Engine) if defined?(::ActionCable::Engine)
32
+ ::NewRelic::Agent::PrependSupportability.record_metrics_for(::ActionCable::RemoteConnections) if defined?(::ActionCable::RemoteConnections)
34
33
  end
35
34
  end
36
35
  end
@@ -71,7 +71,9 @@ DependencyDetection.defer do
71
71
  )
72
72
  begin
73
73
  segment.notice_nosql_statement(statement) if statement
74
- call_without_new_relic(*args, &block)
74
+ NewRelic::Agent::Tracer.capture_segment_error segment do
75
+ call_without_new_relic(*args, &block)
76
+ end
75
77
  ensure
76
78
  segment.finish if segment
77
79
  end
@@ -96,7 +98,9 @@ DependencyDetection.defer do
96
98
  )
97
99
  begin
98
100
  segment.notice_nosql_statement(statement)
99
- call_pipeline_without_new_relic(*args, &block)
101
+ NewRelic::Agent::Tracer.capture_segment_error segment do
102
+ call_pipeline_without_new_relic(*args, &block)
103
+ end
100
104
  ensure
101
105
  segment.finish if segment
102
106
  end
@@ -117,7 +121,9 @@ DependencyDetection.defer do
117
121
  )
118
122
 
119
123
  begin
120
- connect_without_new_relic(*args, &block)
124
+ NewRelic::Agent::Tracer.capture_segment_error segment do
125
+ connect_without_new_relic(*args, &block)
126
+ end
121
127
  ensure
122
128
  segment.finish if segment
123
129
  end
@@ -43,6 +43,9 @@ DependencyDetection.defer do
43
43
  perform_without_instrumentation
44
44
  end
45
45
  ensure
46
+ # Stopping the event loop before flushing the pipe.
47
+ # The goal is to avoid conflict during write.
48
+ NewRelic::Agent.agent.stop_event_loop
46
49
  NewRelic::Agent.agent.flush_pipe_data
47
50
  end
48
51
  end
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # This file is distributed under New Relic's license terms.
3
2
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
3
 
@@ -15,7 +15,7 @@ DependencyDetection.defer do
15
15
 
16
16
  executes do
17
17
  ::NewRelic::Agent.logger.info 'Installing Typhoeus instrumentation'
18
- require 'new_relic/agent/cross_app_tracing'
18
+ require 'new_relic/agent/distributed_tracing/cross_app_tracing'
19
19
  require 'new_relic/agent/http_clients/typhoeus_wrappers'
20
20
  end
21
21
 
@@ -60,10 +60,10 @@ module NewRelic
60
60
  module Instrumentation
61
61
  module TyphoeusTracing
62
62
 
63
- HYDRA_SEGMENT_NAME = "External/Multiple/Typhoeus::Hydra/run"
64
-
63
+ HYDRA_SEGMENT_NAME = "External/Multiple/Typhoeus::Hydra/run"
64
+ NOTICIBLE_ERROR_CLASS = "Typhoeus::Errors::TyphoeusError"
65
+
65
66
  EARLIEST_VERSION = Gem::Version.new("0.5.3")
66
-
67
67
  def self.is_supported_version?
68
68
  Gem::Version.new(Typhoeus::VERSION) >= NewRelic::Agent::Instrumentation::TyphoeusTracing::EARLIEST_VERSION
69
69
  end
@@ -72,6 +72,17 @@ module NewRelic
72
72
  request.respond_to?(:hydra) && request.hydra
73
73
  end
74
74
 
75
+ def self.response_message(response)
76
+ if response.respond_to?(:response_message)
77
+ response.response_message
78
+ elsif response.respond_to?(:return_message)
79
+ response.return_message
80
+ else
81
+ # 0.5.4 seems to have lost xxxx_message methods altogether.
82
+ "timeout"
83
+ end
84
+ end
85
+
75
86
  def self.trace(request)
76
87
  state = NewRelic::Agent::Tracer.state
77
88
  return unless state.is_execution_traced?
@@ -92,8 +103,14 @@ module NewRelic
92
103
  segment.add_request_headers wrapped_request
93
104
 
94
105
  callback = Proc.new do
95
- wrapped_response = ::NewRelic::Agent::HTTPClients::TyphoeusHTTPResponse.new(request.response)
96
- segment.read_response_headers wrapped_response
106
+ wrapped_response = HTTPClients::TyphoeusHTTPResponse.new(request.response)
107
+
108
+ segment.process_response_headers wrapped_response
109
+
110
+ if request.response.code == 0
111
+ segment.notice_error NoticibleError.new NOTICIBLE_ERROR_CLASS, response_message(request.response)
112
+ end
113
+
97
114
  segment.finish if segment
98
115
  end
99
116
  request.on_complete.unshift(callback)