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.
- checksums.yaml +4 -4
- data/.travis.yml +16 -16
- data/CHANGELOG.md +64 -0
- data/lib/new_relic/agent.rb +6 -5
- data/lib/new_relic/agent/agent.rb +43 -36
- data/lib/new_relic/agent/attributes.rb +2 -4
- data/lib/new_relic/agent/configuration/default_source.rb +23 -22
- data/lib/new_relic/agent/configuration/server_source.rb +1 -1
- data/lib/new_relic/agent/configuration/yaml_source.rb +1 -1
- data/lib/new_relic/agent/database.rb +1 -2
- data/lib/new_relic/agent/distributed_tracing.rb +155 -6
- data/lib/new_relic/agent/{cross_app_payload.rb → distributed_tracing/cross_app_payload.rb} +0 -0
- data/lib/new_relic/agent/{cross_app_tracing.rb → distributed_tracing/cross_app_tracing.rb} +60 -45
- data/lib/new_relic/agent/distributed_tracing/distributed_trace_intrinsics.rb +80 -0
- data/lib/new_relic/agent/distributed_tracing/distributed_trace_metrics.rb +75 -0
- data/lib/new_relic/agent/{distributed_trace_payload.rb → distributed_tracing/distributed_trace_payload.rb} +19 -28
- data/lib/new_relic/agent/distributed_tracing/distributed_trace_transport_type.rb +39 -0
- data/lib/new_relic/agent/distributed_tracing/trace_context.rb +246 -0
- data/lib/new_relic/agent/{trace_context_payload.rb → distributed_tracing/trace_context_payload.rb} +3 -11
- data/lib/new_relic/agent/error_collector.rb +3 -5
- data/lib/new_relic/agent/error_event_aggregator.rb +3 -1
- data/lib/new_relic/agent/external.rb +7 -7
- data/lib/new_relic/agent/instrumentation/action_cable_subscriber.rb +1 -2
- data/lib/new_relic/agent/instrumentation/bunny.rb +1 -1
- data/lib/new_relic/agent/instrumentation/curb.rb +1 -1
- data/lib/new_relic/agent/instrumentation/excon.rb +1 -1
- data/lib/new_relic/agent/instrumentation/grape.rb +5 -10
- data/lib/new_relic/agent/instrumentation/http.rb +1 -1
- data/lib/new_relic/agent/instrumentation/httpclient.rb +1 -1
- data/lib/new_relic/agent/instrumentation/net.rb +1 -1
- data/lib/new_relic/agent/instrumentation/resque.rb +3 -0
- data/lib/new_relic/agent/instrumentation/typhoeus.rb +1 -1
- data/lib/new_relic/agent/logging.rb +13 -3
- data/lib/new_relic/agent/messaging.rb +5 -73
- data/lib/new_relic/agent/method_tracer.rb +3 -2
- data/lib/new_relic/agent/method_tracer_helpers.rb +1 -1
- data/lib/new_relic/agent/monitors.rb +27 -0
- data/lib/new_relic/agent/monitors/cross_app_monitor.rb +110 -0
- data/lib/new_relic/agent/monitors/distributed_tracing_monitor.rb +27 -0
- data/lib/new_relic/agent/{inbound_request_monitor.rb → monitors/inbound_request_monitor.rb} +1 -1
- data/lib/new_relic/agent/{synthetics_monitor.rb → monitors/synthetics_monitor.rb} +2 -4
- data/lib/new_relic/agent/span_event_primitive.rb +25 -29
- data/lib/new_relic/agent/sql_sampler.rb +2 -2
- data/lib/new_relic/agent/supported_versions.rb +2 -2
- data/lib/new_relic/agent/tracer.rb +3 -3
- data/lib/new_relic/agent/transaction.rb +21 -28
- data/lib/new_relic/agent/transaction/distributed_tracer.rb +171 -0
- data/lib/new_relic/agent/transaction/distributed_tracing.rb +61 -69
- data/lib/new_relic/agent/transaction/external_request_segment.rb +8 -44
- data/lib/new_relic/agent/transaction/message_broker_segment.rb +3 -11
- data/lib/new_relic/agent/transaction/trace.rb +2 -4
- data/lib/new_relic/agent/transaction/trace_context.rb +88 -79
- data/lib/new_relic/agent/transaction/trace_node.rb +2 -5
- data/lib/new_relic/agent/transaction_error_primitive.rb +2 -2
- data/lib/new_relic/agent/transaction_event_primitive.rb +26 -29
- data/lib/new_relic/coerce.rb +5 -3
- data/lib/new_relic/constants.rb +34 -0
- data/lib/new_relic/noticed_error.rb +2 -4
- data/lib/new_relic/rack/browser_monitoring.rb +4 -0
- data/lib/new_relic/supportability_helper.rb +14 -0
- data/lib/new_relic/version.rb +1 -1
- data/lib/tasks/tests.rake +6 -1
- data/newrelic_rpm.gemspec +4 -2
- data/test/agent_helper.rb +21 -1
- metadata +49 -19
- data/lib/new_relic/agent/cross_app_monitor.rb +0 -110
- data/lib/new_relic/agent/distributed_trace_intrinsics.rb +0 -90
- data/lib/new_relic/agent/distributed_trace_metrics.rb +0 -74
- data/lib/new_relic/agent/distributed_trace_monitor.rb +0 -30
- data/lib/new_relic/agent/distributed_trace_transport_type.rb +0 -43
- data/lib/new_relic/agent/trace_context.rb +0 -244
- data/lib/new_relic/agent/trace_context_request_monitor.rb +0 -42
@@ -1,43 +1,68 @@
|
|
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 'new_relic/agent/distributed_trace_intrinsics'
|
7
|
-
require 'new_relic/agent/distributed_trace_metrics'
|
6
|
+
require 'new_relic/agent/distributed_tracing/distributed_trace_payload'
|
7
|
+
require 'new_relic/agent/distributed_tracing/distributed_trace_intrinsics'
|
8
|
+
require 'new_relic/agent/distributed_tracing/distributed_trace_metrics'
|
8
9
|
|
9
10
|
module NewRelic
|
10
11
|
module Agent
|
11
12
|
class Transaction
|
12
13
|
module DistributedTracing
|
13
14
|
attr_accessor :distributed_trace_payload
|
15
|
+
attr_writer :distributed_trace_payload_created
|
16
|
+
|
17
|
+
SUPPORTABILITY_DISTRIBUTED_TRACE = "Supportability/DistributedTrace"
|
18
|
+
CREATE_PREFIX = "#{SUPPORTABILITY_DISTRIBUTED_TRACE}/CreatePayload"
|
19
|
+
ACCEPT_PREFIX = "#{SUPPORTABILITY_DISTRIBUTED_TRACE}/AcceptPayload"
|
20
|
+
IGNORE_PREFIX = "#{ACCEPT_PREFIX}/Ignored"
|
21
|
+
|
22
|
+
CREATE_SUCCESS_METRIC = "#{CREATE_PREFIX}/Success"
|
23
|
+
CREATE_EXCEPTION_METRIC = "#{CREATE_PREFIX}/Exception"
|
24
|
+
ACCEPT_SUCCESS_METRIC = "#{ACCEPT_PREFIX}/Success"
|
25
|
+
ACCEPT_EXCEPTION_METRIC = "#{ACCEPT_PREFIX}/Exception"
|
26
|
+
ACCEPT_PARSE_EXCEPTION_METRIC = "#{ACCEPT_PREFIX}/ParseException"
|
27
|
+
|
28
|
+
IGNORE_ACCEPT_AFTER_CREATE_METRIC = "#{IGNORE_PREFIX}/CreateBeforeAccept"
|
29
|
+
IGNORE_MULTIPLE_ACCEPT_METRIC = "#{IGNORE_PREFIX}/Multiple"
|
30
|
+
IGNORE_ACCEPT_NULL_METRIC = "#{IGNORE_PREFIX}/Null"
|
31
|
+
IGNORE_ACCEPT_MAJOR_VERSION_METRIC = "#{IGNORE_PREFIX}/MajorVersion"
|
32
|
+
IGNORE_ACCEPT_UNTRUSTED_ACCOUNT_METRIC = "#{IGNORE_PREFIX}/UntrustedAccount"
|
33
|
+
|
34
|
+
LBRACE = "{"
|
35
|
+
NULL_PAYLOAD = 'null'
|
36
|
+
|
37
|
+
NEWRELIC_TRACE_KEY = "HTTP_NEWRELIC"
|
38
|
+
|
39
|
+
def accept_distributed_tracing_incoming_request request
|
40
|
+
return unless Agent.config[:'distributed_tracing.enabled']
|
41
|
+
return unless payload = request[NEWRELIC_TRACE_KEY]
|
42
|
+
|
43
|
+
accept_distributed_trace_payload payload
|
44
|
+
end
|
14
45
|
|
15
|
-
|
16
|
-
|
46
|
+
def distributed_trace_payload_created?
|
47
|
+
@distributed_trace_payload_created ||= false
|
48
|
+
end
|
17
49
|
|
18
50
|
def create_distributed_trace_payload
|
19
|
-
unless Agent.config[:'distributed_tracing.enabled']
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
payload = DistributedTracePayload.for_transaction self
|
25
|
-
NewRelic::Agent.increment_metric SUPPORTABILITY_CREATE_PAYLOAD_SUCCESS
|
51
|
+
return unless Agent.config[:'distributed_tracing.enabled']
|
52
|
+
|
53
|
+
@distributed_trace_payload_created = true
|
54
|
+
payload = DistributedTracePayload.for_transaction transaction
|
55
|
+
NewRelic::Agent.increment_metric CREATE_SUCCESS_METRIC
|
26
56
|
payload
|
27
57
|
rescue => e
|
28
|
-
NewRelic::Agent.increment_metric
|
58
|
+
NewRelic::Agent.increment_metric CREATE_EXCEPTION_METRIC
|
29
59
|
NewRelic::Agent.logger.warn "Failed to create distributed trace payload", e
|
30
60
|
nil
|
31
61
|
end
|
32
62
|
|
33
|
-
SUPPORTABILITY_ACCEPT_PAYLOAD_SUCCESS = "Supportability/DistributedTrace/AcceptPayload/Success".freeze
|
34
|
-
SUPPORTABILITY_ACCEPT_PAYLOAD_EXCEPTION = "Supportability/DistributedTrace/AcceptPayload/Exception".freeze
|
35
|
-
|
36
63
|
def accept_distributed_trace_payload payload
|
37
|
-
unless Agent.config[:'distributed_tracing.enabled']
|
38
|
-
|
39
|
-
return
|
40
|
-
end
|
64
|
+
return unless Agent.config[:'distributed_tracing.enabled']
|
65
|
+
|
41
66
|
return false if check_payload_ignored(payload)
|
42
67
|
return false unless check_payload_present(payload)
|
43
68
|
return false unless payload = decode_payload(payload)
|
@@ -47,67 +72,37 @@ module NewRelic
|
|
47
72
|
|
48
73
|
assign_payload_and_sampling_params(payload)
|
49
74
|
|
50
|
-
NewRelic::Agent.increment_metric
|
75
|
+
NewRelic::Agent.increment_metric ACCEPT_SUCCESS_METRIC
|
51
76
|
true
|
52
77
|
rescue => e
|
53
|
-
NewRelic::Agent.increment_metric
|
78
|
+
NewRelic::Agent.increment_metric ACCEPT_EXCEPTION_METRIC
|
54
79
|
NewRelic::Agent.logger.warn "Failed to accept distributed trace payload", e
|
55
80
|
false
|
56
81
|
end
|
57
82
|
|
58
|
-
def distributed_trace_payload_created?
|
59
|
-
@distributed_trace_payload_created ||= false
|
60
|
-
end
|
61
|
-
|
62
|
-
attr_writer :distributed_trace_payload_created
|
63
|
-
|
64
|
-
def append_distributed_trace_info transaction_payload
|
65
|
-
return unless Agent.config[:'distributed_tracing.enabled']
|
66
|
-
DistributedTraceIntrinsics.copy_from_transaction \
|
67
|
-
self,
|
68
|
-
distributed_trace_payload,
|
69
|
-
transaction_payload
|
70
|
-
end
|
71
|
-
|
72
|
-
NR_FORMAT = "newrelic".freeze
|
73
|
-
|
74
|
-
def nr_distributed_tracing_enabled?
|
75
|
-
Agent.config[:'distributed_tracing.enabled'] && (Agent.config[:'distributed_tracing.format'] == NR_FORMAT) && Agent.instance.connected?
|
76
|
-
end
|
77
|
-
|
78
83
|
private
|
79
84
|
|
80
|
-
SUPPORTABILITY_CREATE_BEFORE_ACCEPT_PAYLOAD = "Supportability/DistributedTrace/AcceptPayload/Ignored/CreateBeforeAccept".freeze
|
81
|
-
SUPPORTABILITY_MULTIPLE_ACCEPT_PAYLOAD = "Supportability/DistributedTrace/AcceptPayload/Ignored/Multiple".freeze
|
82
|
-
SUPPORTABILITY_PAYLOAD_ACCEPT_IGNORED_NULL = "Supportability/DistributedTrace/AcceptPayload/Ignored/Null".freeze
|
83
|
-
SUPPORTABILITY_PAYLOAD_ACCEPT_IGNORED_BROWSER = "Supportability/DistributedTrace/AcceptPayload/Ignored/BrowserAgentInjected".freeze
|
84
|
-
|
85
85
|
def check_payload_ignored(payload)
|
86
86
|
if distributed_trace_payload
|
87
|
-
NewRelic::Agent.increment_metric
|
87
|
+
NewRelic::Agent.increment_metric IGNORE_MULTIPLE_ACCEPT_METRIC
|
88
88
|
return true
|
89
89
|
elsif distributed_trace_payload_created?
|
90
|
-
NewRelic::Agent.increment_metric
|
90
|
+
NewRelic::Agent.increment_metric IGNORE_ACCEPT_AFTER_CREATE_METRIC
|
91
91
|
return true
|
92
92
|
end
|
93
93
|
false
|
94
94
|
end
|
95
95
|
|
96
|
-
NULL_PAYLOAD = 'null'.freeze
|
97
|
-
|
98
96
|
def check_payload_present(payload)
|
99
97
|
# We might be passed a Ruby `nil` object _or_ the JSON "null"
|
100
98
|
if payload.nil? || payload == NULL_PAYLOAD
|
101
|
-
NewRelic::Agent.increment_metric
|
99
|
+
NewRelic::Agent.increment_metric IGNORE_ACCEPT_NULL_METRIC
|
102
100
|
return nil
|
103
101
|
end
|
104
102
|
|
105
103
|
payload
|
106
104
|
end
|
107
105
|
|
108
|
-
SUPPORTABILITY_PAYLOAD_ACCEPT_IGNORED_PARSE_EXCEPTION = "Supportability/DistributedTrace/AcceptPayload/ParseException".freeze
|
109
|
-
LBRACE = "{".freeze
|
110
|
-
|
111
106
|
def decode_payload(payload)
|
112
107
|
decoded = if payload.start_with? LBRACE
|
113
108
|
DistributedTracePayload.from_json payload
|
@@ -119,7 +114,7 @@ module NewRelic
|
|
119
114
|
|
120
115
|
decoded
|
121
116
|
rescue => e
|
122
|
-
NewRelic::Agent.increment_metric
|
117
|
+
NewRelic::Agent.increment_metric ACCEPT_PARSE_EXCEPTION_METRIC
|
123
118
|
NewRelic::Agent.logger.warn "Error parsing distributed trace payload", e
|
124
119
|
nil
|
125
120
|
end
|
@@ -136,42 +131,39 @@ module NewRelic
|
|
136
131
|
|
137
132
|
true
|
138
133
|
else
|
139
|
-
NewRelic::Agent.increment_metric
|
134
|
+
NewRelic::Agent.increment_metric ACCEPT_PARSE_EXCEPTION_METRIC
|
140
135
|
false
|
141
136
|
end
|
142
137
|
end
|
143
138
|
|
144
|
-
SUPPORTABILITY_PAYLOAD_ACCEPT_IGNORED_MAJOR_VERSION = "Supportability/DistributedTrace/AcceptPayload/Ignored/MajorVersion".freeze
|
145
|
-
|
146
139
|
def check_valid_version(payload)
|
147
140
|
if DistributedTracePayload.major_version_matches?(payload)
|
148
141
|
true
|
149
142
|
else
|
150
|
-
NewRelic::Agent.increment_metric
|
143
|
+
NewRelic::Agent.increment_metric IGNORE_ACCEPT_MAJOR_VERSION_METRIC
|
151
144
|
false
|
152
145
|
end
|
153
146
|
end
|
154
147
|
|
155
|
-
SUPPORTABILITY_PAYLOAD_ACCEPT_UNTRUSTED_ACCOUNT = "Supportability/DistributedTrace/AcceptPayload/Ignored/UntrustedAccount".freeze
|
156
|
-
|
157
148
|
def check_trusted_account(payload)
|
158
149
|
compare_key = payload.trusted_account_key || payload.parent_account_id
|
159
150
|
unless compare_key == NewRelic::Agent.config[:trusted_account_key]
|
160
|
-
NewRelic::Agent.increment_metric
|
151
|
+
NewRelic::Agent.increment_metric IGNORE_ACCEPT_UNTRUSTED_ACCOUNT_METRIC
|
161
152
|
return false
|
162
153
|
end
|
163
154
|
true
|
164
155
|
end
|
165
156
|
|
166
157
|
def assign_payload_and_sampling_params(payload)
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
158
|
+
@distributed_trace_payload = payload
|
159
|
+
return if transaction.distributed_tracer.trace_context_header_data
|
160
|
+
transaction.trace_id = payload.trace_id
|
161
|
+
transaction.distributed_tracer.parent_transaction_id = payload.transaction_id
|
162
|
+
transaction.parent_span_id = payload.id
|
171
163
|
|
172
164
|
unless payload.sampled.nil?
|
173
|
-
|
174
|
-
|
165
|
+
transaction.sampled = payload.sampled
|
166
|
+
transaction.priority = payload.priority if payload.priority
|
175
167
|
end
|
176
168
|
end
|
177
169
|
end
|
@@ -14,10 +14,12 @@ module NewRelic
|
|
14
14
|
#
|
15
15
|
# @api public
|
16
16
|
class ExternalRequestSegment < Segment
|
17
|
-
attr_reader :library, :uri, :procedure
|
18
|
-
|
19
17
|
NR_SYNTHETICS_HEADER = 'X-NewRelic-Synthetics'.freeze
|
18
|
+
EXTERNAL_TRANSACTION_PREFIX = 'ExternalTransaction/'.freeze
|
19
|
+
SLASH = '/'.freeze
|
20
|
+
APP_DATA_KEY = 'NewRelicAppData'.freeze
|
20
21
|
|
22
|
+
attr_reader :library, :uri, :procedure
|
21
23
|
|
22
24
|
def initialize library, uri, procedure, start_time = nil # :nodoc:
|
23
25
|
@library = library
|
@@ -52,7 +54,7 @@ module NewRelic
|
|
52
54
|
|
53
55
|
return unless record_metrics?
|
54
56
|
|
55
|
-
|
57
|
+
transaction.distributed_tracer.insert_headers request
|
56
58
|
rescue => e
|
57
59
|
NewRelic::Agent.logger.error "Error in add_request_headers", e
|
58
60
|
end
|
@@ -98,10 +100,6 @@ module NewRelic
|
|
98
100
|
@app_data && @app_data[1]
|
99
101
|
end
|
100
102
|
|
101
|
-
EXTERNAL_TRANSACTION_PREFIX = 'ExternalTransaction/'.freeze
|
102
|
-
SLASH = '/'.freeze
|
103
|
-
APP_DATA_KEY = 'NewRelicAppData'.freeze
|
104
|
-
|
105
103
|
# Obtain an obfuscated +String+ suitable for delivery across public networks that identifies this application
|
106
104
|
# and transaction to another application which is also running a New Relic agent. This +String+ can be processed
|
107
105
|
# by +process_request_metadata+ on the receiving application.
|
@@ -123,14 +121,14 @@ module NewRelic
|
|
123
121
|
NewRelicTransaction: [
|
124
122
|
transaction.guid,
|
125
123
|
false,
|
126
|
-
transaction.cat_trip_id,
|
127
|
-
transaction.cat_path_hash
|
124
|
+
transaction.distributed_tracer.cat_trip_id,
|
125
|
+
transaction.distributed_tracer.cat_path_hash
|
128
126
|
]
|
129
127
|
}
|
130
128
|
|
131
129
|
# flag cross app in the state so transaction knows to add bits to paylaod
|
132
130
|
#
|
133
|
-
transaction.is_cross_app_caller = true
|
131
|
+
transaction.distributed_tracer.is_cross_app_caller = true
|
134
132
|
|
135
133
|
# add Synthetics header if we have it
|
136
134
|
#
|
@@ -199,39 +197,6 @@ module NewRelic
|
|
199
197
|
end
|
200
198
|
end
|
201
199
|
|
202
|
-
def insert_context_propagation_headers request
|
203
|
-
return unless transaction
|
204
|
-
|
205
|
-
if transaction.trace_context_enabled?
|
206
|
-
insert_trace_context_headers request
|
207
|
-
elsif transaction.nr_distributed_tracing_enabled?
|
208
|
-
insert_distributed_trace_header request
|
209
|
-
elsif CrossAppTracing.cross_app_enabled?
|
210
|
-
insert_cross_app_header request
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
|
215
|
-
def insert_cross_app_header request
|
216
|
-
transaction.is_cross_app_caller = true
|
217
|
-
txn_guid = transaction.guid
|
218
|
-
trip_id = transaction && transaction.cat_trip_id
|
219
|
-
path_hash = transaction && transaction.cat_path_hash
|
220
|
-
|
221
|
-
CrossAppTracing.insert_request_headers request, txn_guid, trip_id, path_hash
|
222
|
-
end
|
223
|
-
|
224
|
-
NEWRELIC_TRACE_HEADER = "newrelic".freeze
|
225
|
-
|
226
|
-
def insert_distributed_trace_header request
|
227
|
-
payload = transaction.create_distributed_trace_payload
|
228
|
-
request[NEWRELIC_TRACE_HEADER] = payload.http_safe if payload
|
229
|
-
end
|
230
|
-
|
231
|
-
def insert_trace_context_headers request
|
232
|
-
transaction.insert_trace_context carrier: request
|
233
|
-
end
|
234
|
-
|
235
200
|
EXTERNAL_ALL = "External/all".freeze
|
236
201
|
|
237
202
|
def add_unscoped_metrics
|
@@ -271,7 +236,6 @@ module NewRelic
|
|
271
236
|
def record_span_event
|
272
237
|
aggregator = ::NewRelic::Agent.agent.span_event_aggregator
|
273
238
|
priority = transaction.priority
|
274
|
-
|
275
239
|
aggregator.record(priority: priority) do
|
276
240
|
SpanEventPrimitive.for_external_request_segment(self)
|
277
241
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
|
4
4
|
|
5
5
|
require 'new_relic/agent/transaction/segment'
|
6
|
-
require 'new_relic/agent/cross_app_tracing'
|
6
|
+
require 'new_relic/agent/distributed_tracing/cross_app_tracing'
|
7
7
|
|
8
8
|
module NewRelic
|
9
9
|
module Agent
|
@@ -89,18 +89,10 @@ module NewRelic
|
|
89
89
|
@name
|
90
90
|
end
|
91
91
|
|
92
|
-
NEWRELIC_TRACE_KEY = "newrelic".freeze
|
93
|
-
|
94
|
-
def insert_distributed_trace_header
|
95
|
-
return unless Agent.config[:'distributed_tracing.enabled']
|
96
|
-
payload = transaction.create_distributed_trace_payload
|
97
|
-
headers[NEWRELIC_TRACE_KEY] = payload.http_safe if payload
|
98
|
-
end
|
99
|
-
|
100
92
|
def transaction_assigned
|
101
93
|
if headers && transaction && action == :produce && record_metrics?
|
102
|
-
insert_distributed_trace_header
|
103
|
-
transaction.
|
94
|
+
transaction.distributed_tracer.insert_distributed_trace_header headers
|
95
|
+
transaction.distributed_tracer.insert_cat_headers headers
|
104
96
|
end
|
105
97
|
rescue => e
|
106
98
|
NewRelic::Agent.logger.error "Error during message header processing", e
|
@@ -121,13 +121,11 @@ module NewRelic
|
|
121
121
|
}
|
122
122
|
end
|
123
123
|
|
124
|
-
EMPTY_HASH = {}.freeze
|
125
|
-
|
126
124
|
def trace_tree attributes_hash
|
127
125
|
[
|
128
126
|
NewRelic::Coerce.float(self.start_time),
|
129
|
-
EMPTY_HASH,
|
130
|
-
EMPTY_HASH,
|
127
|
+
NewRelic::EMPTY_HASH,
|
128
|
+
NewRelic::EMPTY_HASH,
|
131
129
|
self.root_node.to_array,
|
132
130
|
attributes_hash
|
133
131
|
]
|
@@ -1,48 +1,74 @@
|
|
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
|
-
|
5
|
-
require 'new_relic/agent/distributed_trace_payload'
|
6
|
-
require 'new_relic/agent/distributed_trace_intrinsics'
|
7
|
-
require 'new_relic/agent/distributed_trace_metrics'
|
4
|
+
# frozen_string_literal: true
|
8
5
|
|
9
6
|
module NewRelic
|
10
7
|
module Agent
|
11
8
|
class Transaction
|
12
|
-
attr_accessor :trace_context_header_data
|
13
|
-
attr_reader :trace_state_payload
|
14
|
-
|
15
9
|
module TraceContext
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
10
|
+
include NewRelic::Coerce
|
11
|
+
|
12
|
+
module AccountHelpers
|
13
|
+
extend self
|
14
|
+
|
15
|
+
def trace_state_entry_key
|
16
|
+
@trace_state_entry_key ||= if Agent.config[:trusted_account_key]
|
17
|
+
"#{Agent.config[:trusted_account_key]}@nr".freeze
|
18
|
+
elsif Agent.config[:account_id]
|
19
|
+
"#{Agent.config[:account_id]}@nr".freeze
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
SUPPORTABILITY_PREFIX = "Supportability/TraceContext"
|
25
|
+
CREATE_PREFIX = "#{SUPPORTABILITY_PREFIX}/Create"
|
26
|
+
ACCEPT_PREFIX = "#{SUPPORTABILITY_PREFIX}/Accept"
|
27
|
+
TRACESTATE_PREFIX = "#{SUPPORTABILITY_PREFIX}/TraceState"
|
28
|
+
|
29
|
+
CREATE_SUCCESS_METRIC = "#{CREATE_PREFIX}/Success"
|
30
|
+
CREATE_EXCEPTION_METRIC = "#{CREATE_PREFIX}/Exception"
|
31
|
+
|
32
|
+
ACCEPT_SUCCESS_METRIC = "#{ACCEPT_PREFIX}/Success"
|
33
|
+
ACCEPT_EXCEPTION_METRIC = "#{ACCEPT_PREFIX}/Exception"
|
34
|
+
IGNORE_MULTIPLE_ACCEPT_METRIC = "#{ACCEPT_PREFIX}/Ignored/Multiple"
|
35
|
+
IGNORE_ACCEPT_AFTER_CREATE_METRIC = "#{ACCEPT_PREFIX}/Ignored/CreateBeforeAccept"
|
36
|
+
|
37
|
+
NO_NR_ENTRY_TRACESTATE_METRIC = "#{TRACESTATE_PREFIX}/NoNrEntry"
|
38
|
+
INVALID_TRACESTATE_PAYLOAD_METRIC = "#{TRACESTATE_PREFIX}/InvalidNrEntry"
|
39
|
+
|
40
|
+
attr_accessor :trace_context_header_data
|
41
|
+
attr_reader :trace_state_payload
|
42
|
+
|
43
|
+
def trace_parent_header_present? request
|
44
|
+
request[NewRelic::HTTP_TRACEPARENT_KEY]
|
45
|
+
end
|
46
|
+
|
47
|
+
def accept_trace_context_incoming_request request
|
48
|
+
header_data = NewRelic::Agent::DistributedTracing::TraceContext.parse(
|
49
|
+
format: NewRelic::FORMAT_RACK,
|
50
|
+
carrier: request,
|
51
|
+
trace_state_entry_key: AccountHelpers.trace_state_entry_key,
|
52
|
+
)
|
53
|
+
return if header_data.nil?
|
54
|
+
|
55
|
+
accept_trace_context header_data
|
56
|
+
end
|
57
|
+
private :accept_trace_context_incoming_request
|
58
|
+
|
59
|
+
def insert_trace_context_header header, format=NewRelic::FORMAT_NON_RACK
|
60
|
+
return unless Agent.config[:'distributed_tracing.enabled']
|
61
|
+
|
62
|
+
NewRelic::Agent::DistributedTracing::TraceContext.insert \
|
39
63
|
format: format,
|
40
|
-
carrier:
|
41
|
-
trace_id: trace_id,
|
42
|
-
parent_id: current_segment.guid,
|
43
|
-
trace_flags: sampled? ? 0x1 : 0x0,
|
64
|
+
carrier: header,
|
65
|
+
trace_id: transaction.trace_id.rjust(32, '0').downcase,
|
66
|
+
parent_id: transaction.current_segment.guid,
|
67
|
+
trace_flags: transaction.sampled? ? 0x1 : 0x0,
|
44
68
|
trace_state: create_trace_state
|
69
|
+
|
45
70
|
@trace_context_inserted = true
|
71
|
+
|
46
72
|
NewRelic::Agent.increment_metric CREATE_SUCCESS_METRIC
|
47
73
|
true
|
48
74
|
rescue Exception => e
|
@@ -52,37 +78,37 @@ module NewRelic
|
|
52
78
|
end
|
53
79
|
|
54
80
|
def create_trace_state
|
55
|
-
entry_key =
|
81
|
+
entry_key = AccountHelpers.trace_state_entry_key.dup
|
56
82
|
payload = create_trace_state_payload
|
57
83
|
|
58
84
|
if payload
|
59
|
-
entry = NewRelic::Agent::TraceContext.create_trace_state_entry \
|
85
|
+
entry = NewRelic::Agent::DistributedTracing::TraceContext.create_trace_state_entry \
|
60
86
|
entry_key,
|
61
87
|
payload.to_s
|
62
88
|
else
|
63
|
-
entry =
|
89
|
+
entry = NewRelic::EMPTY_STR
|
64
90
|
end
|
65
91
|
|
66
92
|
trace_context_header_data ? trace_context_header_data.trace_state(entry) : entry
|
67
93
|
end
|
68
94
|
|
69
95
|
def create_trace_state_payload
|
70
|
-
unless
|
96
|
+
unless Agent.config[:'distributed_tracing.enabled']
|
71
97
|
NewRelic::Agent.logger.warn "Not configured to create WC3 trace context payload"
|
72
98
|
return
|
73
99
|
end
|
74
100
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
101
|
+
|
102
|
+
span_guid = Agent.config[:'span_events.enabled'] ? transaction.current_segment.guid : nil
|
103
|
+
transaction_guid = Agent.config[:'analytics_events.enabled'] ? transaction.guid : nil
|
104
|
+
|
105
|
+
TraceContextPayload.create \
|
106
|
+
parent_account_id: Agent.config[:account_id],
|
107
|
+
parent_app_id: Agent.config[:primary_application_id],
|
108
|
+
transaction_id: transaction_guid,
|
109
|
+
sampled: transaction.sampled?,
|
110
|
+
priority: float!(transaction.priority, NewRelic::PRIORITY_PRECISION),
|
111
|
+
id: span_guid
|
86
112
|
end
|
87
113
|
|
88
114
|
def assign_trace_state_payload
|
@@ -94,28 +120,24 @@ module NewRelic
|
|
94
120
|
unless payload.valid?
|
95
121
|
NewRelic::Agent.increment_metric INVALID_TRACESTATE_PAYLOAD_METRIC
|
96
122
|
return false
|
97
|
-
end
|
123
|
+
end
|
98
124
|
@trace_state_payload = payload
|
99
125
|
end
|
100
126
|
|
101
|
-
def accept_trace_context
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
@trace_context_header_data = trace_context_header_data
|
109
|
-
@trace_id = @trace_context_header_data.trace_id
|
110
|
-
@parent_span_id = @trace_context_header_data.parent_id
|
127
|
+
def accept_trace_context header_data
|
128
|
+
return if ignore_trace_context?
|
129
|
+
|
130
|
+
@trace_context_header_data = header_data
|
131
|
+
transaction.trace_id = header_data.trace_id
|
132
|
+
transaction.parent_span_id = header_data.parent_id
|
111
133
|
|
112
134
|
return false unless payload = assign_trace_state_payload
|
113
135
|
|
114
|
-
|
136
|
+
transaction.distributed_tracer.parent_transaction_id = payload.transaction_id
|
115
137
|
|
116
138
|
unless payload.sampled.nil?
|
117
|
-
|
118
|
-
|
139
|
+
transaction.sampled = payload.sampled
|
140
|
+
transaction.priority = payload.priority if payload.priority
|
119
141
|
end
|
120
142
|
NewRelic::Agent.increment_metric ACCEPT_SUCCESS_METRIC
|
121
143
|
true
|
@@ -125,14 +147,6 @@ module NewRelic
|
|
125
147
|
false
|
126
148
|
end
|
127
149
|
|
128
|
-
def append_trace_context_info transaction_payload
|
129
|
-
return unless trace_context_enabled?
|
130
|
-
DistributedTraceIntrinsics.copy_from_transaction \
|
131
|
-
self,
|
132
|
-
trace_state_payload,
|
133
|
-
transaction_payload
|
134
|
-
end
|
135
|
-
|
136
150
|
def ignore_trace_context?
|
137
151
|
if trace_context_header_data
|
138
152
|
NewRelic::Agent.increment_metric IGNORE_MULTIPLE_ACCEPT_METRIC
|
@@ -143,16 +157,11 @@ module NewRelic
|
|
143
157
|
end
|
144
158
|
false
|
145
159
|
end
|
146
|
-
end
|
147
|
-
|
148
|
-
def trace_context_inserted?
|
149
|
-
@trace_context_inserted ||= false
|
150
|
-
end
|
151
160
|
|
152
|
-
|
161
|
+
def trace_context_inserted?
|
162
|
+
@trace_context_inserted ||= false
|
163
|
+
end
|
153
164
|
|
154
|
-
def trace_context_enabled?
|
155
|
-
Agent.config[:'distributed_tracing.enabled'] && (Agent.config[:'distributed_tracing.format'] == W3C_FORMAT) && Agent.instance.connected?
|
156
165
|
end
|
157
166
|
end
|
158
167
|
end
|