newrelic_rpm 6.8.0.360 → 6.9.0.363

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +16 -16
  3. data/CHANGELOG.md +64 -0
  4. data/lib/new_relic/agent.rb +6 -5
  5. data/lib/new_relic/agent/agent.rb +43 -36
  6. data/lib/new_relic/agent/attributes.rb +2 -4
  7. data/lib/new_relic/agent/configuration/default_source.rb +23 -22
  8. data/lib/new_relic/agent/configuration/server_source.rb +1 -1
  9. data/lib/new_relic/agent/configuration/yaml_source.rb +1 -1
  10. data/lib/new_relic/agent/database.rb +1 -2
  11. data/lib/new_relic/agent/distributed_tracing.rb +155 -6
  12. data/lib/new_relic/agent/{cross_app_payload.rb → distributed_tracing/cross_app_payload.rb} +0 -0
  13. data/lib/new_relic/agent/{cross_app_tracing.rb → distributed_tracing/cross_app_tracing.rb} +60 -45
  14. data/lib/new_relic/agent/distributed_tracing/distributed_trace_intrinsics.rb +80 -0
  15. data/lib/new_relic/agent/distributed_tracing/distributed_trace_metrics.rb +75 -0
  16. data/lib/new_relic/agent/{distributed_trace_payload.rb → distributed_tracing/distributed_trace_payload.rb} +19 -28
  17. data/lib/new_relic/agent/distributed_tracing/distributed_trace_transport_type.rb +39 -0
  18. data/lib/new_relic/agent/distributed_tracing/trace_context.rb +246 -0
  19. data/lib/new_relic/agent/{trace_context_payload.rb → distributed_tracing/trace_context_payload.rb} +3 -11
  20. data/lib/new_relic/agent/error_collector.rb +3 -5
  21. data/lib/new_relic/agent/error_event_aggregator.rb +3 -1
  22. data/lib/new_relic/agent/external.rb +7 -7
  23. data/lib/new_relic/agent/instrumentation/action_cable_subscriber.rb +1 -2
  24. data/lib/new_relic/agent/instrumentation/bunny.rb +1 -1
  25. data/lib/new_relic/agent/instrumentation/curb.rb +1 -1
  26. data/lib/new_relic/agent/instrumentation/excon.rb +1 -1
  27. data/lib/new_relic/agent/instrumentation/grape.rb +5 -10
  28. data/lib/new_relic/agent/instrumentation/http.rb +1 -1
  29. data/lib/new_relic/agent/instrumentation/httpclient.rb +1 -1
  30. data/lib/new_relic/agent/instrumentation/net.rb +1 -1
  31. data/lib/new_relic/agent/instrumentation/resque.rb +3 -0
  32. data/lib/new_relic/agent/instrumentation/typhoeus.rb +1 -1
  33. data/lib/new_relic/agent/logging.rb +13 -3
  34. data/lib/new_relic/agent/messaging.rb +5 -73
  35. data/lib/new_relic/agent/method_tracer.rb +3 -2
  36. data/lib/new_relic/agent/method_tracer_helpers.rb +1 -1
  37. data/lib/new_relic/agent/monitors.rb +27 -0
  38. data/lib/new_relic/agent/monitors/cross_app_monitor.rb +110 -0
  39. data/lib/new_relic/agent/monitors/distributed_tracing_monitor.rb +27 -0
  40. data/lib/new_relic/agent/{inbound_request_monitor.rb → monitors/inbound_request_monitor.rb} +1 -1
  41. data/lib/new_relic/agent/{synthetics_monitor.rb → monitors/synthetics_monitor.rb} +2 -4
  42. data/lib/new_relic/agent/span_event_primitive.rb +25 -29
  43. data/lib/new_relic/agent/sql_sampler.rb +2 -2
  44. data/lib/new_relic/agent/supported_versions.rb +2 -2
  45. data/lib/new_relic/agent/tracer.rb +3 -3
  46. data/lib/new_relic/agent/transaction.rb +21 -28
  47. data/lib/new_relic/agent/transaction/distributed_tracer.rb +171 -0
  48. data/lib/new_relic/agent/transaction/distributed_tracing.rb +61 -69
  49. data/lib/new_relic/agent/transaction/external_request_segment.rb +8 -44
  50. data/lib/new_relic/agent/transaction/message_broker_segment.rb +3 -11
  51. data/lib/new_relic/agent/transaction/trace.rb +2 -4
  52. data/lib/new_relic/agent/transaction/trace_context.rb +88 -79
  53. data/lib/new_relic/agent/transaction/trace_node.rb +2 -5
  54. data/lib/new_relic/agent/transaction_error_primitive.rb +2 -2
  55. data/lib/new_relic/agent/transaction_event_primitive.rb +26 -29
  56. data/lib/new_relic/coerce.rb +5 -3
  57. data/lib/new_relic/constants.rb +34 -0
  58. data/lib/new_relic/noticed_error.rb +2 -4
  59. data/lib/new_relic/rack/browser_monitoring.rb +4 -0
  60. data/lib/new_relic/supportability_helper.rb +14 -0
  61. data/lib/new_relic/version.rb +1 -1
  62. data/lib/tasks/tests.rake +6 -1
  63. data/newrelic_rpm.gemspec +4 -2
  64. data/test/agent_helper.rb +21 -1
  65. metadata +49 -19
  66. data/lib/new_relic/agent/cross_app_monitor.rb +0 -110
  67. data/lib/new_relic/agent/distributed_trace_intrinsics.rb +0 -90
  68. data/lib/new_relic/agent/distributed_trace_metrics.rb +0 -74
  69. data/lib/new_relic/agent/distributed_trace_monitor.rb +0 -30
  70. data/lib/new_relic/agent/distributed_trace_transport_type.rb +0 -43
  71. data/lib/new_relic/agent/trace_context.rb +0 -244
  72. data/lib/new_relic/agent/trace_context_request_monitor.rb +0 -42
@@ -70,7 +70,7 @@ module NewRelic
70
70
 
71
71
  def fix_transaction_threshold(merged_settings)
72
72
  # when value is "apdex_f" remove the config and defer to default
73
- if merged_settings['transaction_tracer.transaction_threshold'] =~ /apdex_f/i
73
+ if merged_settings['transaction_tracer.transaction_threshold'].to_s =~ /apdex_f/i
74
74
  merged_settings.delete('transaction_tracer.transaction_threshold')
75
75
  end
76
76
  end
@@ -112,7 +112,7 @@ module NewRelic
112
112
 
113
113
  def substitute_transaction_threshold(config)
114
114
  if config['transaction_tracer'] &&
115
- config['transaction_tracer']['transaction_threshold'] =~ /apdex_f/i
115
+ config['transaction_tracer']['transaction_threshold'].to_s =~ /apdex_f/i
116
116
  # when value is "apdex_f" remove the config and defer to default
117
117
  config['transaction_tracer'].delete('transaction_threshold')
118
118
  end
@@ -133,10 +133,9 @@ module NewRelic
133
133
  ]
134
134
 
135
135
  SQL_COMMENT_REGEX = Regexp.new('/\*.*?\*/', Regexp::MULTILINE).freeze
136
- EMPTY_STRING = ''.freeze
137
136
 
138
137
  def parse_operation_from_query(sql)
139
- sql = Helper.correctly_encoded(sql).gsub(SQL_COMMENT_REGEX, EMPTY_STRING)
138
+ sql = Helper.correctly_encoded(sql).gsub(SQL_COMMENT_REGEX, NewRelic::EMPTY_STR)
140
139
  if sql =~ /(\w+)/
141
140
  op = $1.downcase
142
141
  return op if KNOWN_OPERATIONS.include?(op)
@@ -1,8 +1,15 @@
1
1
  # encoding: utf-8
2
2
  # This file is distributed under New Relic's license terms.
3
3
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
+ # frozen_string_literal: true
4
5
 
5
- require 'new_relic/agent/distributed_trace_payload'
6
+ require_relative 'distributed_tracing/cross_app_payload'
7
+ require_relative 'distributed_tracing/cross_app_tracing'
8
+
9
+ require_relative 'distributed_tracing/distributed_trace_transport_type'
10
+ require_relative 'distributed_tracing/distributed_trace_payload'
11
+
12
+ require_relative 'distributed_tracing/trace_context'
6
13
 
7
14
  module NewRelic
8
15
  module Agent
@@ -14,8 +21,9 @@ module NewRelic
14
21
  #
15
22
  # @api public
16
23
  module DistributedTracing
24
+ extend NewRelic::SupportabilityHelper
17
25
  extend self
18
-
26
+
19
27
  # Create a payload object containing the current transaction's
20
28
  # tracing properties (e.g., duration, priority). You can use
21
29
  # this object to generate headers to inject into a network
@@ -27,10 +35,19 @@ module NewRelic
27
35
  # could not create the payload
28
36
  #
29
37
  # @api public
38
+ #
39
+ # @deprecated See {#create_distributed_trace_headers} instead.
40
+ #
30
41
  def create_distributed_trace_payload
31
- if transaction = Transaction.tl_current
32
- transaction.create_distributed_trace_payload
42
+ Deprecator.deprecate :create_distributed_trace_payload, :create_distributed_trace_headers
43
+
44
+ unless Agent.config[:'distributed_tracing.enabled']
45
+ NewRelic::Agent.logger.warn "Not configured to create New Relic distributed trace payload"
46
+ return nil
33
47
  end
48
+
49
+ return unless transaction = Transaction.tl_current
50
+ transaction.distributed_tracer.create_distributed_trace_payload
34
51
  rescue => e
35
52
  NewRelic::Agent.logger.error 'error during create_distributed_trace_payload', e
36
53
  nil
@@ -53,15 +70,147 @@ module NewRelic
53
70
  # @return nil
54
71
  #
55
72
  # @api public
73
+ #
74
+ # @deprecated See {#accept_distributed_trace_headers} instead
75
+ #
56
76
  def accept_distributed_trace_payload payload
57
- if transaction = Transaction.tl_current
58
- transaction.accept_distributed_trace_payload(payload)
77
+ Deprecator.deprecate :accept_distributed_trace_payload, :accept_distributed_trace_headers
78
+
79
+ unless Agent.config[:'distributed_tracing.enabled']
80
+ NewRelic::Agent.logger.warn "Not configured to accept New Relic distributed trace payload"
81
+ return nil
59
82
  end
83
+
84
+ return unless transaction = Transaction.tl_current
85
+ transaction.distributed_tracer.accept_distributed_trace_payload(payload)
60
86
  nil
61
87
  rescue => e
62
88
  NewRelic::Agent.logger.error 'error during accept_distributed_trace_payload', e
63
89
  nil
64
90
  end
91
+
92
+
93
+ # Adds the Distributed Trace headers so that the downstream service can participate in a
94
+ # distributed trace. This method should be called every time an outbound call is made
95
+ # since the header payload contains a timestamp.
96
+ #
97
+ # Distributed Tracing must be enabled to use this method.
98
+ #
99
+ # +insert_distributed_trace_headers+ always inserts W3C trace context headers and inserts
100
+ # New Relic distributed tracing header by default. New Relic headers may be suppressed by
101
+ # setting +exclude_new_relic_header+ to +true+ in your configuration file.
102
+ #
103
+ # @param headers [Hash] Is a Hash to which the distributed trace headers
104
+ # will be inserted.
105
+ #
106
+ # @return {Transaction} The transaction the headers were inserted from,
107
+ # or +nil+ if headers were not inserted.
108
+ #
109
+ # @api public
110
+ #
111
+ def insert_distributed_trace_headers headers={}
112
+ record_api_supportability_metric(:insert_distributed_trace_headers)
113
+
114
+ unless Agent.config[:'distributed_tracing.enabled']
115
+ NewRelic::Agent.logger.warn "Not configured to insert distributed trace headers"
116
+ return nil
117
+ end
118
+
119
+ return unless valid_api_argument_class? headers, "headers", Hash
120
+
121
+ return unless transaction = Transaction.tl_current
122
+
123
+ transaction.distributed_tracer.insert_headers headers
124
+ transaction
125
+ rescue => e
126
+ NewRelic::Agent.logger.error 'error during insert_distributed_trace_headers', e
127
+ nil
128
+ end
129
+
130
+ # Accepts distributed tracing headers from any source that has been packaged
131
+ # as a Ruby Hash, thereby allowing the user to manually inject distributed
132
+ # tracing headers. It is optimized to process +HTTP_TRACEPARENT+, +HTTP_TRACESTATE+,
133
+ # and +HTTP_NEWRELIC+ as the given Hash keys. which is the most common scenario
134
+ # from Rack middleware in most Ruby applications. However, the Hash keys are
135
+ # case-insensitive and the "HTTP_" prefixes may also be omitted.
136
+ #
137
+ # Calling this method is not necessary in a typical HTTP trace as
138
+ # distributed tracing is already handled by the agent.
139
+ #
140
+ # When used, invoke this method as early as possible in a transaction's life-cycle
141
+ # as calling after the headers are already created will have no effect.
142
+ #
143
+ # This method accepts both W3C trace context and New Relic distributed tracing headers.
144
+ # When both are present, only the W3C headers are utilized. When W3C trace context
145
+ # headers are present, New Relic headers are ignored regardless if W3C trace context
146
+ # headers are valid and parsable.
147
+ #
148
+ # @param headers [Hash] Incoming distributed trace headers as a Ruby
149
+ # Hash object. Hash keys are expected to be one of
150
+ # +TRACEPARENT+, +TRACESTATE+, +NEWRELIC+ and are
151
+ # case-insensitive, with or without "HTTP_" prefixes.
152
+ #
153
+ # either as a JSON string or as a
154
+ # header-friendly string returned from
155
+ # {DistributedTracePayload#http_safe}
156
+ #
157
+ # @param transport_Type [String] May be one of: +HTTP+, +HTTPS+, +Kafka+, +JMS+,
158
+ # +IronMQ+, +AMQP+, +Queue+, +Other+. Values are
159
+ # case sensitive. All other values result in +Unknown+
160
+ #
161
+ # @return {Transaction} if successful, +nil+ otherwise
162
+ #
163
+ # @api public
164
+ #
165
+ def accept_distributed_trace_headers headers, transport_type = NewRelic::HTTP
166
+ record_api_supportability_metric(:accept_distributed_trace_headers)
167
+
168
+ unless Agent.config[:'distributed_tracing.enabled']
169
+ NewRelic::Agent.logger.warn "Not configured to accept distributed trace headers"
170
+ return nil
171
+ end
172
+
173
+ return unless valid_api_argument_class? headers, "headers", Hash
174
+ return unless valid_api_argument_class? transport_type, "transport_type", String
175
+
176
+ return unless transaction = Transaction.tl_current
177
+
178
+ # assume we have Rack conforming keys when transport_type is HTTP(S)
179
+ # otherwise, fish for key/value pairs regardless of prefix and case-sensitivity.
180
+ hdr = if transport_type.start_with? NewRelic::HTTP
181
+ headers
182
+ else
183
+ # start with the most common case first
184
+ hdr = {
185
+ NewRelic::HTTP_TRACEPARENT_KEY => headers[NewRelic::TRACEPARENT_KEY],
186
+ NewRelic::HTTP_TRACESTATE_KEY => headers[NewRelic::TRACESTATE_KEY],
187
+ NewRelic::HTTP_NEWRELIC_KEY => headers[NewRelic::NEWRELIC_KEY]
188
+ }
189
+
190
+ # when not found, search for any casing for trace context headers, ignoring potential prefixes
191
+ hdr[NewRelic::HTTP_TRACEPARENT_KEY] ||= variant_key_value headers, NewRelic::TRACEPARENT_KEY
192
+ hdr[NewRelic::HTTP_TRACESTATE_KEY] ||= variant_key_value headers, NewRelic::TRACESTATE_KEY
193
+ hdr[NewRelic::HTTP_NEWRELIC_KEY] ||= variant_key_value headers, NewRelic::CANDIDATE_NEWRELIC_KEYS
194
+ hdr
195
+ end
196
+
197
+ transaction.distributed_tracer.accept_incoming_request hdr, transport_type
198
+ transaction
199
+ rescue => e
200
+ NewRelic::Agent.logger.error 'error during accept_distributed_trace_headers', e
201
+ nil
202
+ end
203
+
204
+ private
205
+
206
+ def has_variant_key? key, variants
207
+ key.to_s.downcase.end_with?(*Array(variants))
208
+ end
209
+
210
+ def variant_key_value headers, variants
211
+ (headers.detect{|k, v| has_variant_key?(k, variants)} || NewRelic::EMPTY_ARRAY)[1]
212
+ end
213
+
65
214
  end
66
215
  end
67
216
  end
@@ -2,6 +2,7 @@
2
2
  # encoding: utf-8
3
3
  # This file is distributed under New Relic's license terms.
4
4
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
5
+ # frozen_string_literal: true
5
6
 
6
7
  require 'json'
7
8
 
@@ -9,23 +10,22 @@ module NewRelic
9
10
  module Agent
10
11
  module CrossAppTracing
11
12
  # The cross app response header for "outgoing" calls
12
- NR_APPDATA_HEADER = 'X-NewRelic-App-Data'.freeze
13
+ NR_APPDATA_HEADER = 'X-NewRelic-App-Data'
13
14
 
14
15
  # The cross app id header for "outgoing" calls
15
- NR_ID_HEADER = 'X-NewRelic-ID'.freeze
16
+ NR_ID_HEADER = 'X-NewRelic-ID'
16
17
 
17
18
  # The cross app transaction header for "outgoing" calls
18
- NR_TXN_HEADER = 'X-NewRelic-Transaction'.freeze
19
+ NR_TXN_HEADER = 'X-NewRelic-Transaction'
19
20
 
20
- NR_MESSAGE_BROKER_ID_HEADER = 'NewRelicID'.freeze
21
- NR_MESSAGE_BROKER_TXN_HEADER = 'NewRelicTransaction'.freeze
22
- NR_MESSAGE_BROKER_SYNTHETICS_HEADER = 'NewRelicSynthetics'.freeze
21
+ NR_MESSAGE_BROKER_ID_HEADER = 'NewRelicID'
22
+ NR_MESSAGE_BROKER_TXN_HEADER = 'NewRelicTransaction'
23
+ NR_MESSAGE_BROKER_SYNTHETICS_HEADER = 'NewRelicSynthetics'
23
24
 
24
25
  attr_accessor :is_cross_app_caller, :cross_app_payload, :cat_path_hashes
25
26
 
26
27
  def is_cross_app_caller?
27
- @is_cross_app_caller = false unless defined? @is_cross_app_caller
28
- @is_cross_app_caller
28
+ @is_cross_app_caller ||= false
29
29
  end
30
30
 
31
31
  def is_cross_app_callee?
@@ -37,28 +37,61 @@ module NewRelic
37
37
  end
38
38
 
39
39
  def cat_trip_id
40
- cross_app_payload && cross_app_payload.referring_trip_id || guid
40
+ cross_app_payload && cross_app_payload.referring_trip_id || transaction.guid
41
+ end
42
+
43
+ def cross_app_monitor
44
+ NewRelic::Agent.instance.monitors.cross_app_monitor
41
45
  end
42
46
 
43
47
  def cat_path_hash
44
48
  referring_path_hash = cat_referring_path_hash || '0'
45
49
  seed = referring_path_hash.to_i(16)
46
- result = NewRelic::Agent.instance.cross_app_monitor.path_hash(best_name, seed)
50
+ result = cross_app_monitor.path_hash(transaction.best_name, seed)
47
51
  record_cat_path_hash(result)
48
52
  result
49
53
  end
50
54
 
55
+ def insert_cross_app_header request
56
+ return unless CrossAppTracing.cross_app_enabled?
57
+ @is_cross_app_caller = true
58
+ txn_guid = transaction.guid
59
+ trip_id = cat_trip_id
60
+ path_hash = cat_path_hash
61
+
62
+ insert_request_headers request, txn_guid, trip_id, path_hash
63
+ end
64
+
51
65
  def add_message_cat_headers headers
52
- self.is_cross_app_caller = true
53
- CrossAppTracing.insert_message_headers headers,
54
- guid,
55
- cat_trip_id,
56
- cat_path_hash,
57
- raw_synthetics_header
66
+ return unless CrossAppTracing.cross_app_enabled?
67
+ @is_cross_app_caller = true
68
+ insert_message_headers headers,
69
+ transaction.guid,
70
+ cat_trip_id,
71
+ cat_path_hash,
72
+ transaction.raw_synthetics_header
73
+ end
74
+
75
+ def record_cross_app_metrics
76
+ if (id = cross_app_payload && cross_app_payload.id)
77
+ app_time_in_seconds = [Time.now.to_f - transaction.start_time.to_f, 0.0].max
78
+ NewRelic::Agent.record_metric "ClientApplication/#{id}/all", app_time_in_seconds
79
+ end
80
+ end
81
+
82
+ def assign_cross_app_intrinsics
83
+ transaction.attributes.add_intrinsic_attribute(:trip_id, cat_trip_id)
84
+ transaction.attributes.add_intrinsic_attribute(:path_hash, cat_path_hash)
58
85
  end
59
86
 
60
87
  private
61
88
 
89
+ def insert_message_headers headers, txn_guid, trip_id, path_hash, synthetics_header
90
+ headers[NR_MESSAGE_BROKER_ID_HEADER] = obfuscator.obfuscate(Agent.config[:cross_process_id])
91
+ headers[NR_MESSAGE_BROKER_TXN_HEADER] = obfuscator.obfuscate(::JSON.dump([txn_guid, false, trip_id, path_hash]))
92
+ headers[NR_MESSAGE_BROKER_SYNTHETICS_HEADER] = synthetics_header if synthetics_header
93
+ end
94
+
62
95
  def record_cat_path_hash(hash)
63
96
  @cat_path_hashes ||= []
64
97
  if @cat_path_hashes.size < 10 && !@cat_path_hashes.include?(hash)
@@ -75,8 +108,8 @@ module NewRelic
75
108
  payload[:referring_transaction_guid] = referring_guid
76
109
  end
77
110
 
78
- return unless include_guid?
79
- payload[:guid] = guid
111
+ return unless transaction.include_guid?
112
+ payload[:guid] = transaction.guid
80
113
 
81
114
  return unless is_cross_app?
82
115
  trip_id = cat_trip_id
@@ -96,18 +129,6 @@ module NewRelic
96
129
  end
97
130
  end
98
131
 
99
- def assign_cross_app_intrinsics
100
- attributes.add_intrinsic_attribute(:trip_id, cat_trip_id)
101
- attributes.add_intrinsic_attribute(:path_hash, cat_path_hash)
102
- end
103
-
104
- def record_cross_app_metrics
105
- if (id = cross_app_payload && cross_app_payload.id)
106
- app_time_in_seconds = [Time.now.to_f - @start_time.to_f, 0.0].max
107
- NewRelic::Agent.record_metric "ClientApplication/#{id}/all", app_time_in_seconds
108
- end
109
- end
110
-
111
132
  ###############
112
133
  module_function
113
134
  ###############
@@ -119,7 +140,7 @@ module NewRelic
119
140
  end
120
141
 
121
142
  def valid_cross_process_id?
122
- if NewRelic::Agent.config[:cross_process_id] && NewRelic::Agent.config[:cross_process_id].length > 0
143
+ if Agent.config[:cross_process_id] && Agent.config[:cross_process_id].length > 0
123
144
  true
124
145
  else
125
146
  NewRelic::Agent.logger.debug "No cross_process_id configured"
@@ -128,7 +149,7 @@ module NewRelic
128
149
  end
129
150
 
130
151
  def valid_encoding_key?
131
- if NewRelic::Agent.config[:encoding_key] && NewRelic::Agent.config[:encoding_key].length > 0
152
+ if Agent.config[:encoding_key] && Agent.config[:encoding_key].length > 0
132
153
  true
133
154
  else
134
155
  NewRelic::Agent.logger.debug "No encoding_key set"
@@ -143,7 +164,7 @@ module NewRelic
143
164
  end
144
165
 
145
166
  def obfuscator
146
- @obfuscator ||= NewRelic::Agent::Obfuscator.new(NewRelic::Agent.config[:encoding_key])
167
+ @obfuscator ||= NewRelic::Agent::Obfuscator.new(Agent.config[:encoding_key])
147
168
  end
148
169
 
149
170
  def insert_request_headers request, txn_guid, trip_id, path_hash
@@ -188,12 +209,6 @@ module NewRelic
188
209
  !!(xp_id =~ /\A\d+#\d+\z/)
189
210
  end
190
211
 
191
- def insert_message_headers headers, txn_guid, trip_id, path_hash, synthetics_header
192
- headers[NR_MESSAGE_BROKER_ID_HEADER] = obfuscator.obfuscate(NewRelic::Agent.config[:cross_process_id])
193
- headers[NR_MESSAGE_BROKER_TXN_HEADER] = obfuscator.obfuscate(::JSON.dump([txn_guid, false, trip_id, path_hash]))
194
- headers[NR_MESSAGE_BROKER_SYNTHETICS_HEADER] = synthetics_header if synthetics_header
195
- end
196
-
197
212
  def message_has_crossapp_request_header? headers
198
213
  !!headers[NR_MESSAGE_BROKER_ID_HEADER]
199
214
  end
@@ -217,15 +232,15 @@ module NewRelic
217
232
  def assign_intrinsic_transaction_attributes state
218
233
  # We expect to get the before call to set the id (if we have it) before
219
234
  # this, and then write our custom parameter when the transaction starts
220
- return unless (transaction = state.current_transaction)
221
- return unless (cross_app_payload = transaction.cross_app_payload)
235
+ return unless (txn = state.current_transaction)
236
+ return unless (payload = txn.distributed_tracer.cross_app_payload)
222
237
 
223
- if (cross_app_id = cross_app_payload.id)
224
- transaction.attributes.add_intrinsic_attribute(:client_cross_process_id, cross_app_id)
238
+ if (cross_app_id = payload.id)
239
+ txn.attributes.add_intrinsic_attribute(:client_cross_process_id, cross_app_id)
225
240
  end
226
241
 
227
- if (referring_guid = cross_app_payload.referring_guid)
228
- transaction.attributes.add_intrinsic_attribute(:referring_transaction_guid, referring_guid)
242
+ if (referring_guid = payload.referring_guid)
243
+ txn.attributes.add_intrinsic_attribute(:referring_transaction_guid, referring_guid)
229
244
  end
230
245
  end
231
246
  end
@@ -0,0 +1,80 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
+ # frozen_string_literal: true
5
+
6
+ module NewRelic
7
+ module Agent
8
+ module DistributedTraceIntrinsics
9
+ extend self
10
+
11
+ # Intrinsic Keys
12
+ INTRINSIC_KEYS = [
13
+ PARENT_TYPE_KEY = "parent.type",
14
+ PARENT_APP_KEY = "parent.app",
15
+ PARENT_ACCOUNT_ID_KEY = "parent.account",
16
+ PARENT_TRANSPORT_TYPE_KEY = "parent.transportType",
17
+ PARENT_TRANSPORT_DURATION_KEY = "parent.transportDuration",
18
+ GUID_KEY = "guid",
19
+ TRACE_ID_KEY = "traceId",
20
+ PARENT_TRANSACTION_ID_KEY = "parentId",
21
+ PARENT_SPAN_ID_KEY = "parentSpanId",
22
+ SAMPLED_KEY = "sampled",
23
+ ].freeze
24
+
25
+ # This method extracts intrinsics from the transaction_payload and
26
+ # inserts them into the specified destination.
27
+ def copy_to_hash transaction_payload, destination
28
+ return unless enabled?
29
+ INTRINSIC_KEYS.each do |key|
30
+ value = transaction_payload[key]
31
+ destination[key] = value unless value.nil?
32
+ end
33
+ end
34
+
35
+ # This method extracts intrinsics from the transaction_payload and
36
+ # inserts them as intrinsics in the specified transaction_attributes
37
+ def copy_to_attributes transaction_payload, destination
38
+ return unless enabled?
39
+ INTRINSIC_KEYS.each do |key|
40
+ next unless transaction_payload.key? key
41
+ destination.add_intrinsic_attribute key, transaction_payload[key]
42
+ end
43
+ end
44
+
45
+ # This method takes all distributed tracing intrinsics from the transaction
46
+ # and the trace_payload, and populates them into the destination
47
+ def copy_from_transaction transaction, trace_payload, destination
48
+ transport_type = transaction.distributed_tracer.caller_transport_type
49
+ destination[PARENT_TRANSPORT_TYPE_KEY] = DistributedTraceTransportType.from transport_type
50
+
51
+ destination[GUID_KEY] = transaction.guid
52
+ destination[SAMPLED_KEY] = transaction.sampled?
53
+ destination[TRACE_ID_KEY] = transaction.trace_id
54
+
55
+ if transaction.parent_span_id
56
+ destination[PARENT_SPAN_ID_KEY] = transaction.parent_span_id
57
+ end
58
+
59
+ if trace_payload
60
+ destination[PARENT_TYPE_KEY] = trace_payload.parent_type
61
+ destination[PARENT_APP_KEY] = trace_payload.parent_app_id
62
+ destination[PARENT_ACCOUNT_ID_KEY] = trace_payload.parent_account_id
63
+
64
+ destination[PARENT_TRANSPORT_DURATION_KEY] = transaction.calculate_transport_duration trace_payload
65
+
66
+ if parent_transaction_id = transaction.distributed_tracer.parent_transaction_id
67
+ destination[PARENT_TRANSACTION_ID_KEY] = parent_transaction_id
68
+ end
69
+ end
70
+ end
71
+
72
+ private
73
+
74
+ def enabled?
75
+ return Agent.config[:'distributed_tracing.enabled']
76
+ end
77
+
78
+ end
79
+ end
80
+ end