newrelic_rpm 4.5.0.337 → 4.6.0.338
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +2 -0
- data/CHANGELOG.md +8 -0
- data/lib/new_relic/agent.rb +1 -0
- data/lib/new_relic/agent/agent.rb +19 -12
- data/lib/new_relic/agent/configuration/default_source.rb +7 -0
- data/lib/new_relic/agent/distributed_trace_monitor.rb +29 -0
- data/lib/new_relic/agent/distributed_trace_payload.rb +223 -0
- data/lib/new_relic/agent/distributed_trace_priority_sampled_buffer.rb +72 -0
- data/lib/new_relic/agent/external.rb +137 -0
- data/lib/new_relic/agent/http_clients/abstract_request.rb +31 -0
- data/lib/new_relic/agent/http_clients/curb_wrappers.rb +3 -1
- data/lib/new_relic/agent/http_clients/excon_wrappers.rb +3 -1
- data/lib/new_relic/agent/http_clients/http_rb_wrappers.rb +3 -1
- data/lib/new_relic/agent/http_clients/httpclient_wrappers.rb +3 -1
- data/lib/new_relic/agent/http_clients/net_http_wrappers.rb +3 -1
- data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +3 -1
- data/lib/new_relic/agent/sql_sampler.rb +2 -2
- data/lib/new_relic/agent/throughput_monitor.rb +59 -0
- data/lib/new_relic/agent/transaction.rb +59 -15
- data/lib/new_relic/agent/transaction/abstract_segment.rb +17 -5
- data/lib/new_relic/agent/transaction/distributed_tracing.rb +121 -0
- data/lib/new_relic/agent/transaction/external_request_segment.rb +183 -19
- data/lib/new_relic/agent/transaction/segment.rb +2 -3
- data/lib/new_relic/agent/transaction/trace.rb +14 -5
- data/lib/new_relic/agent/transaction/trace_builder.rb +58 -0
- data/lib/new_relic/agent/transaction/trace_node.rb +34 -32
- data/lib/new_relic/agent/transaction/tracing.rb +4 -9
- data/lib/new_relic/agent/transaction_error_primitive.rb +18 -0
- data/lib/new_relic/agent/transaction_event_aggregator.rb +14 -0
- data/lib/new_relic/agent/transaction_event_primitive.rb +14 -0
- data/lib/new_relic/agent/transaction_event_recorder.rb +9 -1
- data/lib/new_relic/agent/transaction_sampler.rb +12 -66
- data/lib/new_relic/agent/transaction_state.rb +1 -3
- data/lib/new_relic/supportability_helper.rb +5 -0
- data/lib/new_relic/version.rb +1 -1
- data/newrelic.yml +1 -1
- data/newrelic_rpm.gemspec +1 -1
- data/test/agent_helper.rb +11 -3
- metadata +10 -4
- data/lib/new_relic/agent/transaction_sample_builder.rb +0 -138
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f0dcf7789c565bfbc24cc8b1c65ec3d3b05d715
|
4
|
+
data.tar.gz: 50ba88cad5a895adafc8c4923143b30f0d85f1e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 98acebde2bc526125b36318ccd71e94dec996adb273894e25b38497ba3e4fe3b62d86613c5dc2d8cef198e0c83084584e8b7b5205002bb79155dbca323f3615c
|
7
|
+
data.tar.gz: 8d0f588e0b0c40b4398f2cee2a4d3d30d6f0022a584713c0f068d1546c2d975bc624e93b77c318cb94cbd4f59ecac0611e6f10c7d7fac04e5d15a197854f1d01
|
data/.yardopts
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
--api public
|
3
3
|
lib/new_relic/agent.rb
|
4
4
|
lib/new_relic/agent/method_tracer.rb
|
5
|
+
lib/new_relic/agent/external.rb
|
5
6
|
lib/new_relic/agent/instrumentation/controller_instrumentation.rb
|
6
7
|
lib/new_relic/agent/instrumentation/rack.rb
|
7
8
|
lib/new_relic/agent/instrumentation/metric_frame.rb
|
@@ -15,6 +16,7 @@ lib/new_relic/rack/agent_hooks.rb
|
|
15
16
|
lib/new_relic/rack/browser_monitoring.rb
|
16
17
|
lib/new_relic/rack/error_collector.rb
|
17
18
|
lib/new_relic/rack.rb
|
19
|
+
lib/new_relic/agent/transaction/external_request_segment.rb
|
18
20
|
-
|
19
21
|
LICENSE
|
20
22
|
CHANGELOG
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# New Relic Ruby Agent Release Notes #
|
2
2
|
|
3
|
+
## v4.6.0 ##
|
4
|
+
|
5
|
+
* Public API for External Requests
|
6
|
+
|
7
|
+
The agent now has public API for instrumenting external requests and linking
|
8
|
+
up transactions via cross application tracing. See the [API Guide](https://docs.newrelic.com/docs/agents/ruby-agent/customization/ruby-agent-api-guide#externals)
|
9
|
+
for more details this new functionality.
|
10
|
+
|
3
11
|
## v4.5.0 ##
|
4
12
|
|
5
13
|
* Send synthetics headers even when CAT disabled
|
data/lib/new_relic/agent.rb
CHANGED
@@ -54,6 +54,7 @@ module NewRelic
|
|
54
54
|
require 'new_relic/agent/rules_engine'
|
55
55
|
require 'new_relic/agent/http_clients/uri_util'
|
56
56
|
require 'new_relic/agent/system_info'
|
57
|
+
require 'new_relic/agent/external'
|
57
58
|
|
58
59
|
require 'new_relic/agent/instrumentation/controller_instrumentation'
|
59
60
|
|
@@ -19,6 +19,7 @@ require 'new_relic/agent/database'
|
|
19
19
|
require 'new_relic/agent/commands/agent_command_router'
|
20
20
|
require 'new_relic/agent/event_listener'
|
21
21
|
require 'new_relic/agent/cross_app_monitor'
|
22
|
+
require 'new_relic/agent/distributed_trace_monitor'
|
22
23
|
require 'new_relic/agent/synthetics_monitor'
|
23
24
|
require 'new_relic/agent/synthetics_event_buffer'
|
24
25
|
require 'new_relic/agent/transaction_event_recorder'
|
@@ -29,6 +30,7 @@ require 'new_relic/agent/vm/monotonic_gc_profiler'
|
|
29
30
|
require 'new_relic/agent/utilization_data'
|
30
31
|
require 'new_relic/environment_report'
|
31
32
|
require 'new_relic/agent/attribute_filter'
|
33
|
+
require 'new_relic/agent/throughput_monitor'
|
32
34
|
|
33
35
|
module NewRelic
|
34
36
|
module Agent
|
@@ -48,18 +50,20 @@ module NewRelic
|
|
48
50
|
|
49
51
|
@service = NewRelicService.new
|
50
52
|
|
51
|
-
@events
|
52
|
-
@stats_engine
|
53
|
-
@transaction_sampler
|
54
|
-
@sql_sampler
|
55
|
-
@agent_command_router
|
56
|
-
@cross_app_monitor
|
57
|
-
@
|
58
|
-
@
|
59
|
-
@
|
60
|
-
@
|
61
|
-
@
|
62
|
-
@
|
53
|
+
@events = NewRelic::Agent::EventListener.new
|
54
|
+
@stats_engine = NewRelic::Agent::StatsEngine.new
|
55
|
+
@transaction_sampler = NewRelic::Agent::TransactionSampler.new
|
56
|
+
@sql_sampler = NewRelic::Agent::SqlSampler.new
|
57
|
+
@agent_command_router = NewRelic::Agent::Commands::AgentCommandRouter.new(@events)
|
58
|
+
@cross_app_monitor = NewRelic::Agent::CrossAppMonitor.new(@events)
|
59
|
+
@distributed_trace_monitor = NewRelic::Agent::DistributedTraceMonitor.new(@events)
|
60
|
+
@synthetics_monitor = NewRelic::Agent::SyntheticsMonitor.new(@events)
|
61
|
+
@error_collector = NewRelic::Agent::ErrorCollector.new
|
62
|
+
@transaction_rules = NewRelic::Agent::RulesEngine.new
|
63
|
+
@harvest_samplers = NewRelic::Agent::SamplerCollection.new(@events)
|
64
|
+
@monotonic_gc_profiler = NewRelic::Agent::VM::MonotonicGCProfiler.new
|
65
|
+
@javascript_instrumentor = NewRelic::Agent::JavascriptInstrumentor.new(@events)
|
66
|
+
@throughput_monitor = NewRelic::Agent::ThroughputMonitor.new
|
63
67
|
|
64
68
|
@harvester = NewRelic::Agent::Harvester.new(@events)
|
65
69
|
@after_fork_lock = Mutex.new
|
@@ -140,6 +144,7 @@ module NewRelic
|
|
140
144
|
attr_reader :custom_event_aggregator
|
141
145
|
attr_reader :transaction_event_recorder
|
142
146
|
attr_reader :attribute_filter
|
147
|
+
attr_reader :throughput_monitor
|
143
148
|
|
144
149
|
def transaction_event_aggregator
|
145
150
|
@transaction_event_recorder.transaction_event_aggregator
|
@@ -543,6 +548,7 @@ module NewRelic
|
|
543
548
|
@transaction_event_recorder.drop_buffered_data
|
544
549
|
@custom_event_aggregator.reset!
|
545
550
|
@sql_sampler.reset!
|
551
|
+
|
546
552
|
if Agent.config[:clear_transaction_state_after_fork]
|
547
553
|
TransactionState.tl_clear
|
548
554
|
end
|
@@ -1148,6 +1154,7 @@ module NewRelic
|
|
1148
1154
|
harvest_and_send_for_agent_commands
|
1149
1155
|
end
|
1150
1156
|
ensure
|
1157
|
+
throughput_monitor.reset!
|
1151
1158
|
NewRelic::Agent::Database.close_connections
|
1152
1159
|
duration = (Time.now - now).to_f
|
1153
1160
|
NewRelic::Agent.record_metric('Supportability/Harvest', duration)
|
@@ -1639,6 +1639,13 @@ module NewRelic
|
|
1639
1639
|
:type => Boolean,
|
1640
1640
|
:allowed_from_server => false,
|
1641
1641
|
:description => 'If <code>true</code>, the agent will clear <code>TransactionState</code> in <code>Agent.drop_buffered_data</code>.'
|
1642
|
+
},
|
1643
|
+
:'distributed_tracing.enabled' => {
|
1644
|
+
:default => false,
|
1645
|
+
:public => false,
|
1646
|
+
:type => Boolean,
|
1647
|
+
:allowed_from_server => false,
|
1648
|
+
:description => 'If <code>true</code> enables experimental distributed tracing feature.'
|
1642
1649
|
}
|
1643
1650
|
}.freeze
|
1644
1651
|
end
|
@@ -0,0 +1,29 @@
|
|
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
|
+
|
5
|
+
require 'new_relic/agent/inbound_request_monitor'
|
6
|
+
require 'new_relic/agent/cross_app_tracing'
|
7
|
+
|
8
|
+
module NewRelic
|
9
|
+
module Agent
|
10
|
+
class DistributedTraceMonitor < InboundRequestMonitor
|
11
|
+
NEWRELIC_TRACE_KEY = 'HTTP_X_NEWRELIC_TRACE'.freeze
|
12
|
+
HTTP_TRANSPORT_TYPE = 'HTTP'.freeze
|
13
|
+
|
14
|
+
def on_finished_configuring(events)
|
15
|
+
return unless NewRelic::Agent.config[:'distributed_tracing.enabled']
|
16
|
+
events.subscribe(:before_call, &method(:on_before_call))
|
17
|
+
end
|
18
|
+
|
19
|
+
def on_before_call(request)
|
20
|
+
return unless CrossAppTracing.cross_app_enabled?
|
21
|
+
return unless payload = request[NEWRELIC_TRACE_KEY]
|
22
|
+
|
23
|
+
state = NewRelic::Agent::TransactionState.tl_get
|
24
|
+
txn = state.current_transaction
|
25
|
+
txn.accept_distributed_trace_payload HTTP_TRANSPORT_TYPE, payload
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,223 @@
|
|
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
|
+
require 'json'
|
5
|
+
require 'base64'
|
6
|
+
|
7
|
+
module NewRelic
|
8
|
+
module Agent
|
9
|
+
class DistributedTracePayload
|
10
|
+
VERSION =[0, 0].freeze
|
11
|
+
CALLER_TYPE = "App".freeze
|
12
|
+
POUND = '#'.freeze
|
13
|
+
|
14
|
+
# Key names for serialization
|
15
|
+
VERSION_KEY = 'v'.freeze
|
16
|
+
DATA_KEY = 'd'.freeze
|
17
|
+
CALLER_TYPE_KEY = 'ty'.freeze
|
18
|
+
CALLER_ACCOUNT_KEY = 'ac'.freeze
|
19
|
+
CALLER_APP_KEY = 'ap'.freeze
|
20
|
+
ID_KEY = 'id'.freeze
|
21
|
+
TRIP_ID_KEY = 'tr'.freeze
|
22
|
+
SAMPLED_KEY = 'sa'.freeze
|
23
|
+
PARENT_IDS_KEY = 'pa'.freeze
|
24
|
+
DEPTH_KEY = 'de'.freeze
|
25
|
+
ORDER_KEY = 'or'.freeze
|
26
|
+
TIMESTAMP_KEY = 'ti'.freeze
|
27
|
+
HOST_KEY = 'ho'.freeze
|
28
|
+
SYNTHETICS_KEY = 'sy'.freeze
|
29
|
+
SYNTHETICS_RESOURCE_KEY = 'r'.freeze
|
30
|
+
SYNTHETICS_JOB_KEY = 'j'.freeze
|
31
|
+
SYNTHETICS_MONITOR_KEY = 'm'.freeze
|
32
|
+
|
33
|
+
# Intrinsic Keys
|
34
|
+
CALLER_TYPE_INTRINSIC_KEY = "caller.type".freeze
|
35
|
+
CALLER_APP_INTRINSIC_KEY = "caller.app".freeze
|
36
|
+
CALLER_ACCOUNT_ID_INTRINSIC_KEY = "caller.account".freeze
|
37
|
+
CALLER_TRANSPORT_TYPE_INTRINSIC_KEY = "caller.transportType".freeze
|
38
|
+
CALLER_TRANSPORT_DURATION_INTRINSIC_KEY = "caller.transportDuration".freeze
|
39
|
+
CALLER_HOST_INTRINSIC_KEY = "caller.host".freeze
|
40
|
+
DEPTH_INTRINSIC_KEY = "nr.depth".freeze
|
41
|
+
ORDER_INTRINSIC_KEY = "nr.order".freeze
|
42
|
+
GUID_INTRINSIC_KEY = "nr.guid".freeze
|
43
|
+
REFERRING_TRANSACTION_GUID_INTRINSIC_KEY = "nr.referringTransactionGuid".freeze
|
44
|
+
TRIP_ID_INTRINSIC_KEY = "nr.tripId".freeze
|
45
|
+
PARENT_IDS_INTRINSIC_KEY = "nr.parentIds".freeze
|
46
|
+
COMMA = ",".freeze
|
47
|
+
|
48
|
+
INTRINSIC_KEYS = [
|
49
|
+
CALLER_TYPE_INTRINSIC_KEY,
|
50
|
+
CALLER_APP_INTRINSIC_KEY,
|
51
|
+
CALLER_ACCOUNT_ID_INTRINSIC_KEY,
|
52
|
+
CALLER_TRANSPORT_TYPE_INTRINSIC_KEY,
|
53
|
+
CALLER_TRANSPORT_DURATION_INTRINSIC_KEY,
|
54
|
+
CALLER_HOST_INTRINSIC_KEY,
|
55
|
+
DEPTH_INTRINSIC_KEY,
|
56
|
+
ORDER_INTRINSIC_KEY,
|
57
|
+
GUID_INTRINSIC_KEY,
|
58
|
+
REFERRING_TRANSACTION_GUID_INTRINSIC_KEY,
|
59
|
+
TRIP_ID_INTRINSIC_KEY,
|
60
|
+
PARENT_IDS_INTRINSIC_KEY
|
61
|
+
].freeze
|
62
|
+
|
63
|
+
class << self
|
64
|
+
def for_transaction transaction, uri=nil
|
65
|
+
payload = new
|
66
|
+
return payload unless connected?
|
67
|
+
|
68
|
+
payload.version = VERSION
|
69
|
+
payload.caller_type = CALLER_TYPE
|
70
|
+
|
71
|
+
# We should not rely on the xp_id being formulated this way, but we have
|
72
|
+
# seen nil account ids coming down in staging for some accounts
|
73
|
+
account_id, fallback_app_id = Agent.config[:cross_process_id].split(POUND)
|
74
|
+
payload.caller_account_id = account_id
|
75
|
+
|
76
|
+
payload.caller_app_id = if Agent.config[:application_id].empty?
|
77
|
+
fallback_app_id
|
78
|
+
else
|
79
|
+
Agent.config[:application_id]
|
80
|
+
end
|
81
|
+
|
82
|
+
payload.timestamp = (Time.now.to_f * 1000).round
|
83
|
+
payload.id = transaction.guid
|
84
|
+
payload.trip_id = transaction.distributed_tracing_trip_id
|
85
|
+
payload.sampled = transaction.sampled?
|
86
|
+
payload.parent_ids = transaction.parent_ids
|
87
|
+
payload.depth = transaction.depth + 1
|
88
|
+
payload.order = transaction.order
|
89
|
+
payload.host = uri.host if uri
|
90
|
+
|
91
|
+
if transaction.synthetics_payload
|
92
|
+
payload.synthetics_resource = transaction.synthetics_payload[2]
|
93
|
+
payload.synthetics_job = transaction.synthetics_payload[3]
|
94
|
+
payload.synthetics_monitor = transaction.synthetics_payload[4]
|
95
|
+
end
|
96
|
+
|
97
|
+
payload
|
98
|
+
end
|
99
|
+
|
100
|
+
def from_json serialized_payload
|
101
|
+
raw_payload = JSON.parse serialized_payload
|
102
|
+
payload_data = raw_payload[DATA_KEY]
|
103
|
+
|
104
|
+
payload = new
|
105
|
+
payload.version = raw_payload[VERSION_KEY]
|
106
|
+
payload.caller_type = payload_data[CALLER_TYPE_KEY]
|
107
|
+
payload.caller_account_id = payload_data[CALLER_ACCOUNT_KEY]
|
108
|
+
payload.caller_app_id = payload_data[CALLER_APP_KEY]
|
109
|
+
payload.timestamp = payload_data[TIMESTAMP_KEY]
|
110
|
+
payload.id = payload_data[ID_KEY]
|
111
|
+
payload.trip_id = payload_data[TRIP_ID_KEY]
|
112
|
+
payload.sampled = payload_data[SAMPLED_KEY]
|
113
|
+
payload.parent_ids = payload_data[PARENT_IDS_KEY]
|
114
|
+
payload.depth = payload_data[DEPTH_KEY]
|
115
|
+
payload.order = payload_data[ORDER_KEY]
|
116
|
+
payload.host = payload_data[HOST_KEY]
|
117
|
+
|
118
|
+
if payload_synthetics = payload_data[SYNTHETICS_KEY]
|
119
|
+
payload.synthetics_resource = payload_synthetics[SYNTHETICS_RESOURCE_KEY]
|
120
|
+
payload.synthetics_job = payload_synthetics[SYNTHETICS_JOB_KEY]
|
121
|
+
payload.synthetics_monitor = payload_synthetics[SYNTHETICS_MONITOR_KEY]
|
122
|
+
end
|
123
|
+
|
124
|
+
payload
|
125
|
+
end
|
126
|
+
|
127
|
+
def from_http_safe http_safe_payload
|
128
|
+
decoded_payload = Base64.strict_decode64 http_safe_payload
|
129
|
+
from_json decoded_payload
|
130
|
+
end
|
131
|
+
|
132
|
+
#assigns intrinsics for the first distributed trace in a trip
|
133
|
+
def assign_initial_intrinsics transaction, payload
|
134
|
+
payload[TRIP_ID_INTRINSIC_KEY] = transaction.distributed_tracing_trip_id
|
135
|
+
payload[DEPTH_INTRINSIC_KEY] = transaction.depth
|
136
|
+
payload[PARENT_IDS_INTRINSIC_KEY] = transaction.parent_ids
|
137
|
+
end
|
138
|
+
|
139
|
+
private
|
140
|
+
|
141
|
+
# We use the presence of the cross_process_id in the config to tell if we
|
142
|
+
# have connected yet.
|
143
|
+
def connected?
|
144
|
+
!!Agent.config[:'cross_process_id']
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
attr_accessor :version,
|
149
|
+
:caller_type,
|
150
|
+
:caller_transport_type,
|
151
|
+
:caller_account_id,
|
152
|
+
:caller_app_id,
|
153
|
+
:id,
|
154
|
+
:trip_id,
|
155
|
+
:sampled,
|
156
|
+
:parent_ids,
|
157
|
+
:synthetics_resource,
|
158
|
+
:synthetics_job,
|
159
|
+
:synthetics_monitor,
|
160
|
+
:order,
|
161
|
+
:depth,
|
162
|
+
:timestamp,
|
163
|
+
:host
|
164
|
+
|
165
|
+
alias_method :sampled?, :sampled
|
166
|
+
|
167
|
+
def synthetics?
|
168
|
+
!!(synthetics_resource || synthetics_job || synthetics_monitor)
|
169
|
+
end
|
170
|
+
|
171
|
+
def to_json
|
172
|
+
result = {
|
173
|
+
VERSION_KEY => version
|
174
|
+
}
|
175
|
+
|
176
|
+
result[DATA_KEY] = {
|
177
|
+
CALLER_TYPE_KEY => caller_type,
|
178
|
+
CALLER_ACCOUNT_KEY => caller_account_id,
|
179
|
+
CALLER_APP_KEY => caller_app_id,
|
180
|
+
ID_KEY => id,
|
181
|
+
TRIP_ID_KEY => trip_id,
|
182
|
+
SAMPLED_KEY => sampled,
|
183
|
+
PARENT_IDS_KEY => parent_ids,
|
184
|
+
DEPTH_KEY => depth,
|
185
|
+
ORDER_KEY => order,
|
186
|
+
HOST_KEY => host,
|
187
|
+
TIMESTAMP_KEY => timestamp,
|
188
|
+
}
|
189
|
+
|
190
|
+
if synthetics?
|
191
|
+
result[DATA_KEY][SYNTHETICS_KEY] = {
|
192
|
+
SYNTHETICS_RESOURCE_KEY => synthetics_resource,
|
193
|
+
SYNTHETICS_JOB_KEY => synthetics_job,
|
194
|
+
SYNTHETICS_MONITOR_KEY => synthetics_monitor
|
195
|
+
}
|
196
|
+
end
|
197
|
+
|
198
|
+
JSON.dump(result)
|
199
|
+
end
|
200
|
+
|
201
|
+
alias_method :text, :to_json
|
202
|
+
|
203
|
+
def http_safe
|
204
|
+
Base64.strict_encode64 to_json
|
205
|
+
end
|
206
|
+
|
207
|
+
def assign_intrinsics transaction, payload
|
208
|
+
payload[CALLER_TYPE_INTRINSIC_KEY] = caller_type
|
209
|
+
payload[CALLER_APP_INTRINSIC_KEY] = caller_app_id
|
210
|
+
payload[CALLER_ACCOUNT_ID_INTRINSIC_KEY] = caller_account_id
|
211
|
+
payload[CALLER_TRANSPORT_TYPE_INTRINSIC_KEY] = caller_transport_type
|
212
|
+
payload[CALLER_TRANSPORT_DURATION_INTRINSIC_KEY] = transaction.transport_duration
|
213
|
+
payload[CALLER_HOST_INTRINSIC_KEY] = host
|
214
|
+
payload[DEPTH_INTRINSIC_KEY] = depth
|
215
|
+
payload[ORDER_INTRINSIC_KEY] = order
|
216
|
+
payload[GUID_INTRINSIC_KEY] = transaction.guid
|
217
|
+
payload[REFERRING_TRANSACTION_GUID_INTRINSIC_KEY] = id
|
218
|
+
payload[TRIP_ID_INTRINSIC_KEY] = trip_id
|
219
|
+
payload[PARENT_IDS_INTRINSIC_KEY] = parent_ids.join COMMA if parent_ids
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
@@ -0,0 +1,72 @@
|
|
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
|
+
|
5
|
+
require 'new_relic/agent/event_buffer'
|
6
|
+
require 'set'
|
7
|
+
|
8
|
+
module NewRelic
|
9
|
+
module Agent
|
10
|
+
class DistributedTracePrioritySampledBuffer < SampledBuffer
|
11
|
+
attr_reader :seen_lifetime, :captured_lifetime
|
12
|
+
|
13
|
+
def initialize(capacity)
|
14
|
+
@low_priority_indices = []
|
15
|
+
@high_priority_indices = Set.new
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def append_sampled(x = nil, &blk)
|
20
|
+
raise ArgumentError, "Expected argument or block, but received both" if x && blk
|
21
|
+
|
22
|
+
@seen += 1
|
23
|
+
@seen_lifetime += 1
|
24
|
+
if @items.size < @capacity
|
25
|
+
x = blk.call if block_given?
|
26
|
+
insert_high_priority x
|
27
|
+
@captured_lifetime += 1
|
28
|
+
return x
|
29
|
+
elsif !@low_priority_indices.empty? # overwite random low priority sample
|
30
|
+
m = rand(@low_priority_indices.size)
|
31
|
+
insert_high_priority x, @low_priority_indices.delete_at(m)
|
32
|
+
return x
|
33
|
+
else
|
34
|
+
NewRelic::Agent.increment_metric "Supportability/DistributedTracing/SampledBufferFailure/BufferFull"
|
35
|
+
return nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def append_event(x = nil, &blk)
|
40
|
+
raise ArgumentError, "Expected argument or block, but received both" if x && blk
|
41
|
+
|
42
|
+
if @items.size < @capacity
|
43
|
+
x = blk.call if block_given?
|
44
|
+
insert_low_priority x
|
45
|
+
@captured_lifetime += 1
|
46
|
+
return x
|
47
|
+
else
|
48
|
+
m = rand(@seen) # [0, @seen)
|
49
|
+
if m < @capacity && !@high_priority_indices.include?(m)
|
50
|
+
x = blk.call if block_given?
|
51
|
+
insert_low_priority x, m
|
52
|
+
return x
|
53
|
+
else
|
54
|
+
# discard current sample
|
55
|
+
return nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def insert_low_priority x, index = @items.size
|
61
|
+
@items[index] = x
|
62
|
+
@low_priority_indices << index
|
63
|
+
end
|
64
|
+
|
65
|
+
def insert_high_priority x, index = @items.size
|
66
|
+
@items[index] = x
|
67
|
+
@high_priority_indices << index
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|