newrelic_rpm 6.6.0.358 → 6.11.0.365

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.travis.yml +81 -5
  4. data/CHANGELOG.md +262 -0
  5. data/Gemfile +6 -2
  6. data/Guardfile +18 -1
  7. data/LICENSE +1 -1
  8. data/Rakefile +2 -0
  9. data/lib/new_relic/agent.rb +89 -7
  10. data/lib/new_relic/agent/agent.rb +115 -58
  11. data/lib/new_relic/agent/agent_logger.rb +4 -0
  12. data/lib/new_relic/agent/attribute_filter.rb +7 -7
  13. data/lib/new_relic/agent/attributes.rb +150 -0
  14. data/lib/new_relic/agent/autostart.rb +19 -14
  15. data/lib/new_relic/agent/configuration/default_source.rb +154 -9
  16. data/lib/new_relic/agent/configuration/event_harvest_config.rb +11 -5
  17. data/lib/new_relic/agent/configuration/manager.rb +0 -8
  18. data/lib/new_relic/agent/configuration/server_source.rb +3 -2
  19. data/lib/new_relic/agent/configuration/yaml_source.rb +11 -6
  20. data/lib/new_relic/agent/connect/request_builder.rb +5 -13
  21. data/lib/new_relic/agent/database.rb +1 -2
  22. data/lib/new_relic/agent/database/obfuscation_helpers.rb +1 -1
  23. data/lib/new_relic/agent/datastores/mongo.rb +1 -1
  24. data/lib/new_relic/agent/datastores/mongo/event_formatter.rb +2 -2
  25. data/lib/new_relic/agent/datastores/mongo/obfuscator.rb +8 -8
  26. data/lib/new_relic/agent/distributed_tracing.rb +155 -6
  27. data/lib/new_relic/agent/{cross_app_payload.rb → distributed_tracing/cross_app_payload.rb} +2 -1
  28. data/lib/new_relic/agent/{cross_app_tracing.rb → distributed_tracing/cross_app_tracing.rb} +60 -45
  29. data/lib/new_relic/agent/distributed_tracing/distributed_trace_intrinsics.rb +80 -0
  30. data/lib/new_relic/agent/distributed_tracing/distributed_trace_metrics.rb +75 -0
  31. data/lib/new_relic/agent/{distributed_trace_payload.rb → distributed_tracing/distributed_trace_payload.rb} +24 -101
  32. data/lib/new_relic/agent/distributed_tracing/distributed_trace_transport_type.rb +39 -0
  33. data/lib/new_relic/agent/distributed_tracing/trace_context.rb +246 -0
  34. data/lib/new_relic/agent/distributed_tracing/trace_context_payload.rb +126 -0
  35. data/lib/new_relic/agent/error_collector.rb +33 -16
  36. data/lib/new_relic/agent/error_event_aggregator.rb +7 -5
  37. data/lib/new_relic/agent/external.rb +7 -7
  38. data/lib/new_relic/agent/guid_generator.rb +28 -0
  39. data/lib/new_relic/agent/hostname.rb +7 -1
  40. data/lib/new_relic/agent/http_clients/abstract.rb +82 -0
  41. data/lib/new_relic/agent/http_clients/curb_wrappers.rb +24 -19
  42. data/lib/new_relic/agent/http_clients/excon_wrappers.rb +28 -13
  43. data/lib/new_relic/agent/http_clients/http_rb_wrappers.rb +17 -21
  44. data/lib/new_relic/agent/http_clients/httpclient_wrappers.rb +10 -11
  45. data/lib/new_relic/agent/http_clients/net_http_wrappers.rb +16 -4
  46. data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +4 -6
  47. data/lib/new_relic/agent/http_clients/uri_util.rb +3 -2
  48. data/lib/new_relic/agent/instrumentation/action_cable_subscriber.rb +5 -7
  49. data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +4 -0
  50. data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +11 -2
  51. data/lib/new_relic/agent/instrumentation/active_record.rb +4 -2
  52. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +7 -2
  53. data/lib/new_relic/agent/instrumentation/active_storage_subscriber.rb +8 -4
  54. data/lib/new_relic/agent/instrumentation/bunny.rb +45 -28
  55. data/lib/new_relic/agent/instrumentation/curb.rb +59 -18
  56. data/lib/new_relic/agent/instrumentation/data_mapper.rb +3 -1
  57. data/lib/new_relic/agent/instrumentation/excon.rb +1 -1
  58. data/lib/new_relic/agent/instrumentation/excon/connection.rb +6 -3
  59. data/lib/new_relic/agent/instrumentation/excon/middleware.rb +2 -1
  60. data/lib/new_relic/agent/instrumentation/grape.rb +5 -10
  61. data/lib/new_relic/agent/instrumentation/http.rb +6 -3
  62. data/lib/new_relic/agent/instrumentation/httpclient.rb +5 -3
  63. data/lib/new_relic/agent/instrumentation/memcache.rb +3 -1
  64. data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +6 -2
  65. data/lib/new_relic/agent/instrumentation/mongo.rb +9 -3
  66. data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +13 -0
  67. data/lib/new_relic/agent/instrumentation/net.rb +6 -3
  68. data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +25 -1
  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 +47 -23
  72. data/lib/new_relic/agent/instrumentation/typhoeus.rb +23 -6
  73. data/lib/new_relic/agent/logging.rb +139 -0
  74. data/lib/new_relic/agent/messaging.rb +5 -73
  75. data/lib/new_relic/agent/method_tracer.rb +18 -6
  76. data/lib/new_relic/agent/method_tracer_helpers.rb +2 -2
  77. data/lib/new_relic/agent/monitors.rb +27 -0
  78. data/lib/new_relic/agent/monitors/cross_app_monitor.rb +110 -0
  79. data/lib/new_relic/agent/monitors/distributed_tracing_monitor.rb +27 -0
  80. data/lib/new_relic/agent/{inbound_request_monitor.rb → monitors/inbound_request_monitor.rb} +1 -1
  81. data/lib/new_relic/agent/{synthetics_monitor.rb → monitors/synthetics_monitor.rb} +2 -4
  82. data/lib/new_relic/agent/new_relic_service.rb +7 -6
  83. data/lib/new_relic/agent/noticible_error.rb +22 -0
  84. data/lib/new_relic/agent/span_event_aggregator.rb +1 -0
  85. data/lib/new_relic/agent/span_event_primitive.rb +86 -53
  86. data/lib/new_relic/agent/sql_sampler.rb +3 -3
  87. data/lib/new_relic/agent/supported_versions.rb +2 -2
  88. data/lib/new_relic/agent/system_info.rb +12 -3
  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/cli/commands/deployments.rb +1 -1
  103. data/lib/new_relic/cli/commands/install.rb +3 -2
  104. data/lib/new_relic/coerce.rb +31 -6
  105. data/lib/new_relic/constants.rb +38 -0
  106. data/lib/new_relic/control/instance_methods.rb +10 -1
  107. data/lib/new_relic/dependency_detection.rb +4 -4
  108. data/lib/new_relic/environment_report.rb +5 -1
  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 +19 -8
  116. data/test/agent_helper.rb +323 -71
  117. metadata +100 -33
  118. data/lib/new_relic/agent/cross_app_monitor.rb +0 -110
  119. data/lib/new_relic/agent/distributed_trace_monitor.rb +0 -40
  120. data/lib/new_relic/agent/http_clients/abstract_request.rb +0 -31
  121. data/lib/new_relic/agent/transaction/attributes.rb +0 -154
  122. data/lib/tasks/versions.html.erb +0 -28
  123. data/lib/tasks/versions.postface.html +0 -8
  124. data/lib/tasks/versions.preface.html +0 -9
  125. data/lib/tasks/versions.rake +0 -65
  126. 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
@@ -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
 
@@ -14,32 +13,48 @@ DependencyDetection.defer do
14
13
  end
15
14
 
16
15
  executes do
17
- class NewRelic::SidekiqInstrumentation
18
- include NewRelic::Agent::Instrumentation::ControllerInstrumentation
16
+ module NewRelic::SidekiqInstrumentation
17
+ class Server
18
+ include NewRelic::Agent::Instrumentation::ControllerInstrumentation
19
19
 
20
- # Client middleware has additional parameters, and our tests use the
21
- # middleware client-side to work inline.
22
- def call(worker, msg, queue, *_)
23
- trace_args = if worker.respond_to?(:newrelic_trace_args)
24
- worker.newrelic_trace_args(msg, queue)
25
- else
26
- self.class.default_trace_args(msg)
27
- end
20
+ # Client middleware has additional parameters, and our tests use the
21
+ # middleware client-side to work inline.
22
+ def call(worker, msg, queue, *_)
23
+ trace_args = if worker.respond_to?(:newrelic_trace_args)
24
+ worker.newrelic_trace_args(msg, queue)
25
+ else
26
+ self.class.default_trace_args(msg)
27
+ end
28
+ trace_headers = msg.delete(NewRelic::NEWRELIC_KEY)
29
+
30
+ perform_action_with_newrelic_trace(trace_args) do
31
+ NewRelic::Agent::Transaction.merge_untrusted_agent_attributes(msg['args'], :'job.sidekiq.args',
32
+ NewRelic::Agent::AttributeFilter::DST_NONE)
28
33
 
29
- perform_action_with_newrelic_trace(trace_args) do
30
- NewRelic::Agent::Transaction.merge_untrusted_agent_attributes(msg['args'], :'job.sidekiq.args',
31
- NewRelic::Agent::AttributeFilter::DST_NONE)
34
+ ::NewRelic::Agent::DistributedTracing::accept_distributed_trace_headers(trace_headers, "Other")
35
+ yield
36
+ end
37
+ end
32
38
 
33
- yield
39
+ def self.default_trace_args(msg)
40
+ {
41
+ :name => 'perform',
42
+ :class_name => msg['class'],
43
+ :category => 'OtherTransaction/SidekiqJob'
44
+ }
34
45
  end
35
46
  end
47
+ class Client
48
+ def call(_worker_class, job, *_)
49
+ job[NewRelic::NEWRELIC_KEY] = distributed_tracing_headers
50
+ yield
51
+ end
36
52
 
37
- def self.default_trace_args(msg)
38
- {
39
- :name => 'perform',
40
- :class_name => msg['class'],
41
- :category => 'OtherTransaction/SidekiqJob'
42
- }
53
+ def distributed_tracing_headers
54
+ headers = {}
55
+ ::NewRelic::Agent::DistributedTracing.insert_distributed_trace_headers(headers)
56
+ headers
57
+ end
43
58
  end
44
59
  end
45
60
 
@@ -53,13 +68,22 @@ DependencyDetection.defer do
53
68
  }
54
69
  rescue => e
55
70
  NewRelic::Agent.logger.error("Failure during deserializing YAML for Sidekiq::Extensions::DelayedClass", e)
56
- NewRelic::SidekiqInstrumentation.default_trace_args(msg)
71
+ NewRelic::SidekiqInstrumentation::Server.default_trace_args(msg)
57
72
  end
58
73
  end
59
74
 
75
+ Sidekiq.configure_client do |config|
76
+ config.client_middleware do |chain|
77
+ chain.add NewRelic::SidekiqInstrumentation::Client
78
+ end
79
+ end
80
+
60
81
  Sidekiq.configure_server do |config|
82
+ config.client_middleware do |chain|
83
+ chain.add NewRelic::SidekiqInstrumentation::Client
84
+ end
61
85
  config.server_middleware do |chain|
62
- chain.add NewRelic::SidekiqInstrumentation
86
+ chain.add NewRelic::SidekiqInstrumentation::Server
63
87
  end
64
88
 
65
89
  if config.respond_to?(:error_handlers)