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.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.travis.yml +81 -5
- data/CHANGELOG.md +262 -0
- data/Gemfile +6 -2
- data/Guardfile +18 -1
- data/LICENSE +1 -1
- data/Rakefile +2 -0
- data/lib/new_relic/agent.rb +89 -7
- data/lib/new_relic/agent/agent.rb +115 -58
- data/lib/new_relic/agent/agent_logger.rb +4 -0
- data/lib/new_relic/agent/attribute_filter.rb +7 -7
- data/lib/new_relic/agent/attributes.rb +150 -0
- data/lib/new_relic/agent/autostart.rb +19 -14
- data/lib/new_relic/agent/configuration/default_source.rb +154 -9
- data/lib/new_relic/agent/configuration/event_harvest_config.rb +11 -5
- data/lib/new_relic/agent/configuration/manager.rb +0 -8
- data/lib/new_relic/agent/configuration/server_source.rb +3 -2
- data/lib/new_relic/agent/configuration/yaml_source.rb +11 -6
- data/lib/new_relic/agent/connect/request_builder.rb +5 -13
- data/lib/new_relic/agent/database.rb +1 -2
- data/lib/new_relic/agent/database/obfuscation_helpers.rb +1 -1
- data/lib/new_relic/agent/datastores/mongo.rb +1 -1
- data/lib/new_relic/agent/datastores/mongo/event_formatter.rb +2 -2
- data/lib/new_relic/agent/datastores/mongo/obfuscator.rb +8 -8
- 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} +2 -1
- 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} +24 -101
- 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/distributed_tracing/trace_context_payload.rb +126 -0
- data/lib/new_relic/agent/error_collector.rb +33 -16
- data/lib/new_relic/agent/error_event_aggregator.rb +7 -5
- data/lib/new_relic/agent/external.rb +7 -7
- data/lib/new_relic/agent/guid_generator.rb +28 -0
- data/lib/new_relic/agent/hostname.rb +7 -1
- data/lib/new_relic/agent/http_clients/abstract.rb +82 -0
- data/lib/new_relic/agent/http_clients/curb_wrappers.rb +24 -19
- data/lib/new_relic/agent/http_clients/excon_wrappers.rb +28 -13
- data/lib/new_relic/agent/http_clients/http_rb_wrappers.rb +17 -21
- data/lib/new_relic/agent/http_clients/httpclient_wrappers.rb +10 -11
- data/lib/new_relic/agent/http_clients/net_http_wrappers.rb +16 -4
- data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +4 -6
- data/lib/new_relic/agent/http_clients/uri_util.rb +3 -2
- data/lib/new_relic/agent/instrumentation/action_cable_subscriber.rb +5 -7
- data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +4 -0
- data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +11 -2
- data/lib/new_relic/agent/instrumentation/active_record.rb +4 -2
- data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +7 -2
- data/lib/new_relic/agent/instrumentation/active_storage_subscriber.rb +8 -4
- data/lib/new_relic/agent/instrumentation/bunny.rb +45 -28
- data/lib/new_relic/agent/instrumentation/curb.rb +59 -18
- data/lib/new_relic/agent/instrumentation/data_mapper.rb +3 -1
- data/lib/new_relic/agent/instrumentation/excon.rb +1 -1
- data/lib/new_relic/agent/instrumentation/excon/connection.rb +6 -3
- data/lib/new_relic/agent/instrumentation/excon/middleware.rb +2 -1
- data/lib/new_relic/agent/instrumentation/grape.rb +5 -10
- data/lib/new_relic/agent/instrumentation/http.rb +6 -3
- data/lib/new_relic/agent/instrumentation/httpclient.rb +5 -3
- data/lib/new_relic/agent/instrumentation/memcache.rb +3 -1
- data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +6 -2
- data/lib/new_relic/agent/instrumentation/mongo.rb +9 -3
- data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +13 -0
- data/lib/new_relic/agent/instrumentation/net.rb +6 -3
- data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +25 -1
- data/lib/new_relic/agent/instrumentation/redis.rb +9 -3
- data/lib/new_relic/agent/instrumentation/resque.rb +3 -0
- data/lib/new_relic/agent/instrumentation/sidekiq.rb +47 -23
- data/lib/new_relic/agent/instrumentation/typhoeus.rb +23 -6
- data/lib/new_relic/agent/logging.rb +139 -0
- data/lib/new_relic/agent/messaging.rb +5 -73
- data/lib/new_relic/agent/method_tracer.rb +18 -6
- data/lib/new_relic/agent/method_tracer_helpers.rb +2 -2
- 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/new_relic_service.rb +7 -6
- data/lib/new_relic/agent/noticible_error.rb +22 -0
- data/lib/new_relic/agent/span_event_aggregator.rb +1 -0
- data/lib/new_relic/agent/span_event_primitive.rb +86 -53
- data/lib/new_relic/agent/sql_sampler.rb +3 -3
- data/lib/new_relic/agent/supported_versions.rb +2 -2
- data/lib/new_relic/agent/system_info.rb +12 -3
- data/lib/new_relic/agent/tracer.rb +65 -18
- data/lib/new_relic/agent/transaction.rb +84 -79
- data/lib/new_relic/agent/transaction/abstract_segment.rb +28 -2
- data/lib/new_relic/agent/transaction/distributed_tracer.rb +171 -0
- data/lib/new_relic/agent/transaction/distributed_tracing.rb +57 -146
- data/lib/new_relic/agent/transaction/external_request_segment.rb +29 -36
- data/lib/new_relic/agent/transaction/message_broker_segment.rb +3 -11
- data/lib/new_relic/agent/transaction/segment.rb +7 -1
- data/lib/new_relic/agent/transaction/trace.rb +2 -4
- data/lib/new_relic/agent/transaction/trace_context.rb +168 -0
- data/lib/new_relic/agent/transaction/trace_node.rb +10 -8
- data/lib/new_relic/agent/transaction_error_primitive.rb +10 -15
- data/lib/new_relic/agent/transaction_event_primitive.rb +28 -39
- data/lib/new_relic/cli/commands/deployments.rb +1 -1
- data/lib/new_relic/cli/commands/install.rb +3 -2
- data/lib/new_relic/coerce.rb +31 -6
- data/lib/new_relic/constants.rb +38 -0
- data/lib/new_relic/control/instance_methods.rb +10 -1
- data/lib/new_relic/dependency_detection.rb +4 -4
- data/lib/new_relic/environment_report.rb +5 -1
- data/lib/new_relic/noticed_error.rb +38 -17
- data/lib/new_relic/rack/browser_monitoring.rb +5 -0
- data/lib/new_relic/supportability_helper.rb +14 -0
- data/lib/new_relic/version.rb +1 -1
- data/lib/tasks/multiverse.rb +25 -0
- data/lib/tasks/tests.rake +6 -1
- data/newrelic_rpm.gemspec +19 -8
- data/test/agent_helper.rb +323 -71
- metadata +100 -33
- data/lib/new_relic/agent/cross_app_monitor.rb +0 -110
- data/lib/new_relic/agent/distributed_trace_monitor.rb +0 -40
- data/lib/new_relic/agent/http_clients/abstract_request.rb +0 -31
- data/lib/new_relic/agent/transaction/attributes.rb +0 -154
- data/lib/tasks/versions.html.erb +0 -28
- data/lib/tasks/versions.postface.html +0 -8
- data/lib/tasks/versions.preface.html +0 -9
- data/lib/tasks/versions.rake +0 -65
- data/lib/tasks/versions.txt.erb +0 -14
@@ -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'
|
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'
|
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'
|
19
|
+
NR_TXN_HEADER = 'X-NewRelic-Transaction'
|
19
20
|
|
20
|
-
NR_MESSAGE_BROKER_ID_HEADER = 'NewRelicID'
|
21
|
-
NR_MESSAGE_BROKER_TXN_HEADER = 'NewRelicTransaction'
|
22
|
-
NR_MESSAGE_BROKER_SYNTHETICS_HEADER = 'NewRelicSynthetics'
|
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
|
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 =
|
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
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
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
|
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
|
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(
|
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 (
|
221
|
-
return unless (
|
235
|
+
return unless (txn = state.current_transaction)
|
236
|
+
return unless (payload = txn.distributed_tracer.cross_app_payload)
|
222
237
|
|
223
|
-
if (cross_app_id =
|
224
|
-
|
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 =
|
228
|
-
|
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
|
@@ -0,0 +1,75 @@
|
|
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 DistributedTraceMetrics
|
9
|
+
extend self
|
10
|
+
|
11
|
+
ALL_SUFFIX = "all"
|
12
|
+
ALL_WEB_SUFFIX = "allWeb"
|
13
|
+
ALL_OTHER_SUFFIX = "allOther"
|
14
|
+
|
15
|
+
UNKNOWN_CALLER_PREFIX = "%s/Unknown/Unknown/Unknown/%s"
|
16
|
+
|
17
|
+
def transaction_type_suffix
|
18
|
+
if Transaction.recording_web_transaction?
|
19
|
+
ALL_WEB_SUFFIX
|
20
|
+
else
|
21
|
+
ALL_OTHER_SUFFIX
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def record_metrics_for_transaction transaction
|
26
|
+
return unless Agent.config[:'distributed_tracing.enabled']
|
27
|
+
dt = transaction.distributed_tracer
|
28
|
+
payload = dt.distributed_trace_payload || dt.trace_state_payload
|
29
|
+
|
30
|
+
record_caller_by_duration_metrics transaction, payload
|
31
|
+
record_transport_duration_metrics transaction, payload
|
32
|
+
record_errors_by_caller_metrics transaction, payload
|
33
|
+
end
|
34
|
+
|
35
|
+
def prefix_for_metric name, transaction, payload
|
36
|
+
if payload
|
37
|
+
"#{name}/" \
|
38
|
+
"#{payload.parent_type}/" \
|
39
|
+
"#{payload.parent_account_id}/" \
|
40
|
+
"#{payload.parent_app_id}/" \
|
41
|
+
"#{transaction.distributed_tracer.caller_transport_type}"
|
42
|
+
else
|
43
|
+
UNKNOWN_CALLER_PREFIX % [name, transaction.distributed_tracer.caller_transport_type]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def record_caller_by_duration_metrics transaction, payload
|
48
|
+
prefix = prefix_for_metric "DurationByCaller", transaction, payload
|
49
|
+
record_unscoped_metric transaction, prefix, transaction.duration
|
50
|
+
end
|
51
|
+
|
52
|
+
def record_transport_duration_metrics transaction, payload
|
53
|
+
return unless payload
|
54
|
+
|
55
|
+
prefix = prefix_for_metric "TransportDuration", transaction, payload
|
56
|
+
duration = transaction.calculate_transport_duration payload
|
57
|
+
record_unscoped_metric transaction, prefix, duration
|
58
|
+
end
|
59
|
+
|
60
|
+
def record_errors_by_caller_metrics transaction, payload
|
61
|
+
return unless transaction.exceptions.size > 0
|
62
|
+
|
63
|
+
prefix = prefix_for_metric "ErrorsByCaller", transaction, payload
|
64
|
+
record_unscoped_metric transaction, prefix, 1
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def record_unscoped_metric transaction, prefix, duration
|
70
|
+
transaction.metrics.record_unscoped "#{prefix}/#{ALL_SUFFIX}", duration
|
71
|
+
transaction.metrics.record_unscoped "#{prefix}/#{transaction_type_suffix}", duration
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -1,9 +1,10 @@
|
|
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
|
5
|
+
|
4
6
|
require 'json'
|
5
7
|
require 'base64'
|
6
|
-
require 'set'
|
7
8
|
|
8
9
|
module NewRelic
|
9
10
|
module Agent
|
@@ -14,52 +15,25 @@ module NewRelic
|
|
14
15
|
#
|
15
16
|
# @api public
|
16
17
|
class DistributedTracePayload
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
extend Coerce
|
19
|
+
|
20
|
+
VERSION = [0, 1].freeze
|
21
|
+
PARENT_TYPE = "App"
|
22
|
+
POUND = '#'
|
20
23
|
|
21
24
|
# Key names for serialization
|
22
|
-
VERSION_KEY
|
23
|
-
DATA_KEY
|
24
|
-
PARENT_TYPE_KEY
|
25
|
-
PARENT_ACCOUNT_ID_KEY
|
26
|
-
PARENT_APP_KEY
|
27
|
-
TRUSTED_ACCOUNT_KEY
|
28
|
-
ID_KEY
|
29
|
-
TX_KEY
|
30
|
-
TRACE_ID_KEY
|
31
|
-
SAMPLED_KEY
|
32
|
-
TIMESTAMP_KEY
|
33
|
-
PRIORITY_KEY
|
34
|
-
|
35
|
-
# Intrinsic Keys
|
36
|
-
PARENT_TYPE_INTRINSIC_KEY = "parent.type".freeze
|
37
|
-
PARENT_APP_INTRINSIC_KEY = "parent.app".freeze
|
38
|
-
PARENT_ACCOUNT_ID_INTRINSIC_KEY = "parent.account".freeze
|
39
|
-
PARENT_TRANSPORT_TYPE_INTRINSIC_KEY = "parent.transportType".freeze
|
40
|
-
PARENT_TRANSPORT_DURATION_INTRINSIC_KEY = "parent.transportDuration".freeze
|
41
|
-
GUID_INTRINSIC_KEY = "guid".freeze
|
42
|
-
TRACE_ID_INTRINSIC_KEY = "traceId".freeze
|
43
|
-
PARENT_ID_INTRINSIC_KEY = "parentId".freeze
|
44
|
-
PARENT_SPAN_ID_INTRINSIC_KEY = "parentSpanId".freeze
|
45
|
-
SAMPLED_INTRINSIC_KEY = "sampled".freeze
|
46
|
-
COMMA = ",".freeze
|
47
|
-
|
48
|
-
INTRINSIC_KEYS = [
|
49
|
-
PARENT_TYPE_INTRINSIC_KEY,
|
50
|
-
PARENT_APP_INTRINSIC_KEY,
|
51
|
-
PARENT_ACCOUNT_ID_INTRINSIC_KEY,
|
52
|
-
PARENT_TRANSPORT_TYPE_INTRINSIC_KEY,
|
53
|
-
PARENT_TRANSPORT_DURATION_INTRINSIC_KEY,
|
54
|
-
GUID_INTRINSIC_KEY,
|
55
|
-
TRACE_ID_INTRINSIC_KEY,
|
56
|
-
PARENT_ID_INTRINSIC_KEY,
|
57
|
-
PARENT_SPAN_ID_INTRINSIC_KEY,
|
58
|
-
SAMPLED_INTRINSIC_KEY
|
59
|
-
].freeze
|
60
|
-
|
61
|
-
# Intrinsic Values
|
62
|
-
PARENT_TRANSPORT_TYPE_UNKNOWN = 'Unknown'.freeze
|
25
|
+
VERSION_KEY = 'v'
|
26
|
+
DATA_KEY = 'd'
|
27
|
+
PARENT_TYPE_KEY = 'ty'
|
28
|
+
PARENT_ACCOUNT_ID_KEY = 'ac'
|
29
|
+
PARENT_APP_KEY = 'ap'
|
30
|
+
TRUSTED_ACCOUNT_KEY = 'tk'
|
31
|
+
ID_KEY = 'id'
|
32
|
+
TX_KEY = 'tx'
|
33
|
+
TRACE_ID_KEY = 'tr'
|
34
|
+
SAMPLED_KEY = 'sa'
|
35
|
+
TIMESTAMP_KEY = 'ti'
|
36
|
+
PRIORITY_KEY = 'pr'
|
63
37
|
|
64
38
|
class << self
|
65
39
|
|
@@ -110,24 +84,12 @@ module NewRelic
|
|
110
84
|
from_json decoded_payload
|
111
85
|
end
|
112
86
|
|
113
|
-
def assign_initial_intrinsics transaction, transaction_payload
|
114
|
-
transaction_payload[GUID_INTRINSIC_KEY] = transaction.guid
|
115
|
-
transaction_payload[TRACE_ID_INTRINSIC_KEY] = transaction.trace_id
|
116
|
-
transaction_payload[SAMPLED_INTRINSIC_KEY] = transaction.sampled?
|
117
|
-
end
|
118
|
-
|
119
87
|
def major_version_matches?(payload)
|
120
88
|
payload.version[0] == VERSION[0]
|
121
89
|
end
|
122
90
|
|
123
91
|
private
|
124
92
|
|
125
|
-
# We use the presence of the account_id and primary_application in the
|
126
|
-
# config to tell if we have connected yet.
|
127
|
-
def connected?
|
128
|
-
Agent.config[:account_id] && Agent.config[:primary_application_id]
|
129
|
-
end
|
130
|
-
|
131
93
|
def assign_trusted_account_key payload, account_id
|
132
94
|
trusted_account_key = Agent.config[:trusted_account_key]
|
133
95
|
|
@@ -137,11 +99,14 @@ module NewRelic
|
|
137
99
|
end
|
138
100
|
|
139
101
|
def current_segment_id(transaction)
|
140
|
-
if Agent.config[:'span_events.enabled'] && transaction.
|
141
|
-
transaction.current_segment
|
102
|
+
if Agent.config[:'span_events.enabled'] && transaction.current_segment
|
142
103
|
transaction.current_segment.guid
|
143
104
|
end
|
144
105
|
end
|
106
|
+
|
107
|
+
def connected?
|
108
|
+
Agent.instance.connected?
|
109
|
+
end
|
145
110
|
end
|
146
111
|
|
147
112
|
attr_accessor :version,
|
@@ -158,16 +123,6 @@ module NewRelic
|
|
158
123
|
|
159
124
|
alias_method :sampled?, :sampled
|
160
125
|
|
161
|
-
attr_reader :caller_transport_type
|
162
|
-
|
163
|
-
def caller_transport_type=(type)
|
164
|
-
@caller_transport_type = valid_transport_type_for(type)
|
165
|
-
end
|
166
|
-
|
167
|
-
def initialize
|
168
|
-
@caller_transport_type = PARENT_TRANSPORT_TYPE_UNKNOWN
|
169
|
-
end
|
170
|
-
|
171
126
|
# Represent this payload as a raw JSON string.
|
172
127
|
#
|
173
128
|
# @return [String] Payload translated to JSON
|
@@ -205,38 +160,6 @@ module NewRelic
|
|
205
160
|
def http_safe
|
206
161
|
Base64.strict_encode64 text
|
207
162
|
end
|
208
|
-
|
209
|
-
def assign_intrinsics transaction, transaction_payload
|
210
|
-
transaction_payload[PARENT_TYPE_INTRINSIC_KEY] = parent_type
|
211
|
-
transaction_payload[PARENT_APP_INTRINSIC_KEY] = parent_app_id
|
212
|
-
transaction_payload[PARENT_ACCOUNT_ID_INTRINSIC_KEY] = parent_account_id
|
213
|
-
transaction_payload[PARENT_TRANSPORT_TYPE_INTRINSIC_KEY] = caller_transport_type
|
214
|
-
transaction_payload[PARENT_TRANSPORT_DURATION_INTRINSIC_KEY] = transaction.transport_duration
|
215
|
-
transaction_payload[GUID_INTRINSIC_KEY] = transaction.guid
|
216
|
-
transaction_payload[TRACE_ID_INTRINSIC_KEY] = trace_id
|
217
|
-
transaction_payload[PARENT_ID_INTRINSIC_KEY] = transaction.parent_id if transaction.parent_id
|
218
|
-
transaction_payload[PARENT_SPAN_ID_INTRINSIC_KEY] = id if id
|
219
|
-
transaction_payload[SAMPLED_INTRINSIC_KEY] = transaction.sampled?
|
220
|
-
end
|
221
|
-
|
222
|
-
private
|
223
|
-
|
224
|
-
ALLOWABLE_TRANSPORT_TYPES = Set.new(%w[
|
225
|
-
Unknown
|
226
|
-
HTTP
|
227
|
-
HTTPS
|
228
|
-
Kafka
|
229
|
-
JMS
|
230
|
-
IronMQ
|
231
|
-
AMQP
|
232
|
-
Queue
|
233
|
-
Other
|
234
|
-
]).freeze
|
235
|
-
|
236
|
-
def valid_transport_type_for(value)
|
237
|
-
return value if ALLOWABLE_TRANSPORT_TYPES.include?(value)
|
238
|
-
PARENT_TRANSPORT_TYPE_UNKNOWN
|
239
|
-
end
|
240
163
|
end
|
241
164
|
end
|
242
165
|
end
|