newrelic_rpm 4.8.0.341 → 5.0.0.342
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.travis.yml +27 -0
- data/CHANGELOG.md +39 -0
- data/config.dot +0 -3
- data/lib/new_relic/agent/{throughput_monitor.rb → adaptive_sampler.rb} +22 -13
- data/lib/new_relic/agent/agent.rb +3 -4
- data/lib/new_relic/agent/configuration/default_source.rb +22 -17
- data/lib/new_relic/agent/configuration/high_security_source.rb +0 -2
- data/lib/new_relic/agent/database.rb +5 -0
- data/lib/new_relic/agent/database/explain_plan_helpers.rb +11 -0
- data/lib/new_relic/agent/distributed_trace_monitor.rb +4 -2
- data/lib/new_relic/agent/distributed_trace_payload.rb +88 -119
- data/lib/new_relic/agent/external.rb +14 -0
- data/lib/new_relic/agent/heap.rb +140 -0
- data/lib/new_relic/agent/instrumentation/bunny.rb +5 -1
- data/lib/new_relic/agent/instrumentation/rails5/action_cable.rb +5 -1
- data/lib/new_relic/agent/messaging.rb +10 -0
- data/lib/new_relic/agent/new_relic_service.rb +43 -23
- data/lib/new_relic/agent/priority_sampled_buffer.rb +68 -0
- data/lib/new_relic/agent/supported_versions.rb +1 -1
- data/lib/new_relic/agent/transaction.rb +14 -8
- data/lib/new_relic/agent/transaction/distributed_tracing.rb +113 -55
- data/lib/new_relic/agent/transaction/external_request_segment.rb +17 -11
- data/lib/new_relic/agent/transaction/message_broker_segment.rb +12 -4
- data/lib/new_relic/agent/transaction_error_primitive.rb +2 -8
- data/lib/new_relic/agent/transaction_event_aggregator.rb +16 -13
- data/lib/new_relic/agent/transaction_event_primitive.rb +5 -3
- data/lib/new_relic/agent/transaction_event_recorder.rb +3 -11
- data/lib/new_relic/recipes/capistrano3.rb +5 -2
- data/lib/new_relic/version.rb +2 -2
- data/newrelic_rpm.gemspec +3 -2
- metadata +38 -9
- data/lib/new_relic/agent/distributed_trace_priority_sampled_buffer.rb +0 -72
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 10c4b8fa117aaa061a4e13071bfa6a568e03dc27b4d9a75040cbf9c5b0772749
|
4
|
+
data.tar.gz: 1536ab0db32670d6f604cd9c662d1b7633366e77957051e8ace104df942ed97d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aff7fb607ba79d6f8707a8c4f99bee62dc32c87df71a8809517ed1e29ba57760f0991c241d56816dfc50af99aad98bd918f82d97365cc36882962973efe12551
|
7
|
+
data.tar.gz: 8f2c281d13b955a25d9b7717ed248d5dc3a230e1e42ebf4fd25ad010253cfe42ba7692b288e2d093b9cd64a84d56d7a3edc1d274207ad01402c1ea36cc62af1a
|
data/.travis.yml
CHANGED
@@ -16,6 +16,11 @@ before_install:
|
|
16
16
|
|
17
17
|
install: bundle install
|
18
18
|
|
19
|
+
addons:
|
20
|
+
apt:
|
21
|
+
packages:
|
22
|
+
- haveged
|
23
|
+
|
19
24
|
before_script: ./test/script/before_script/install_mongodb.sh
|
20
25
|
|
21
26
|
script: ./test/script/ci.sh
|
@@ -171,3 +176,25 @@ matrix:
|
|
171
176
|
env: TYPE=UNIT ENVIRONMENT=rails31
|
172
177
|
- rvm: jruby-9.1.13.0
|
173
178
|
env: TYPE=UNIT ENVIRONMENT=rails32
|
179
|
+
|
180
|
+
# Travis (and only Travis) has been throwing difficult-to-reproduce
|
181
|
+
# errors in various JRuby tests. These appeared after a build image
|
182
|
+
# update, and they seem to be unrelated to any agent code changes.
|
183
|
+
# So, we'll allow these specific test runs to fail while we track
|
184
|
+
# the issue (RUBY-1869).
|
185
|
+
#
|
186
|
+
allow_failures:
|
187
|
+
- rvm: jruby-9.1.13.0
|
188
|
+
env: TYPE=UNIT ENVIRONMENT=rails40
|
189
|
+
- rvm: jruby-9.1.13.0
|
190
|
+
env: TYPE=UNIT ENVIRONMENT=rails41
|
191
|
+
- rvm: jruby-9.1.13.0
|
192
|
+
env: TYPE=UNIT ENVIRONMENT=rails42
|
193
|
+
- rvm: jruby-9.1.13.0
|
194
|
+
env: TYPE=UNIT ENVIRONMENT=rails50
|
195
|
+
- rvm: jruby-9.1.13.0
|
196
|
+
env: TYPE=UNIT ENVIRONMENT=rails51
|
197
|
+
- rvm: jruby-9.1.13.0
|
198
|
+
env: TYPE=UNIT ENVIRONMENT=norails
|
199
|
+
- rvm: jruby-9.1.13.0
|
200
|
+
env: TYPE=FUNCTIONAL GROUP=background_2
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,44 @@
|
|
1
1
|
# New Relic Ruby Agent Release Notes #
|
2
2
|
|
3
|
+
## v5.0.0 ##
|
4
|
+
|
5
|
+
* SSL connections to New Relic are now mandatory
|
6
|
+
|
7
|
+
Prior to this version, using an SSL connection to New Relic was
|
8
|
+
the default behavior, but could be overridden. SSL connections are
|
9
|
+
now enforced (not overrideable).
|
10
|
+
|
11
|
+
* Additional security checking before trying to explain
|
12
|
+
multi-statement SQL queries
|
13
|
+
|
14
|
+
Customer applications might submit SQL queries containing multiple
|
15
|
+
statements (e.g., SELECT * FROM table; SELECT * FROM table). For
|
16
|
+
security reasons, we should not generate explain plans in this
|
17
|
+
situation.
|
18
|
+
|
19
|
+
Although the agent correctly skipped explain plans for these
|
20
|
+
queries during testing, we have added extra checks for this
|
21
|
+
scenario.
|
22
|
+
|
23
|
+
* Bugfix for RabbitMQ exchange names that are symbols
|
24
|
+
|
25
|
+
The agent no longer raises a TypeError when a RabbitMQ exchange
|
26
|
+
name is a Ruby symbol instead of a string.
|
27
|
+
|
28
|
+
* Bugfix for audit logging to stdout
|
29
|
+
|
30
|
+
Previous agents configured to log to stdout would correctly send
|
31
|
+
regular agent logs to stdout, but would incorrectly send audit
|
32
|
+
logs to a text file named "stdout". This release corrects the
|
33
|
+
error.
|
34
|
+
|
35
|
+
* Bugfix for Capistrano deployment notifications on v3.7 and beyond
|
36
|
+
|
37
|
+
Starting with version 3.7, Capistrano uses a different technique
|
38
|
+
to determine a project's version control system. The agent now
|
39
|
+
works correctly with this new behavior. Thanks to Jimmy Zhang for
|
40
|
+
the contribution.
|
41
|
+
|
3
42
|
## v4.8.0 ##
|
4
43
|
|
5
44
|
* Initialize New Relic Agent before config initializers
|
data/config.dot
CHANGED
@@ -21,7 +21,6 @@ digraph AgentEnabled {
|
|
21
21
|
"[error_collector.ignore_errors]"
|
22
22
|
"[browser_monitoring.auto_instrument]"
|
23
23
|
"[license_key]"
|
24
|
-
"[ssl]"
|
25
24
|
"[verify_certificate]"
|
26
25
|
"[api_host]"
|
27
26
|
"[api_port]"
|
@@ -164,14 +163,12 @@ digraph AgentEnabled {
|
|
164
163
|
"Control#server_from_host" -> "[host]"
|
165
164
|
"Control#server_from_host" -> "[port]"
|
166
165
|
"Control#server_from_host" -> "Control#convert_to_ip_address"
|
167
|
-
"Control#http_connection" -> "[ssl]"
|
168
166
|
"Control#http_connection" -> "[verify_certificate]"
|
169
167
|
"Control#http_connection" -> "Control#proxy_server"
|
170
168
|
"Control#set_log_level!" -> "[log_level]"
|
171
169
|
"Control#log_path" -> "[log_file_path]"
|
172
170
|
"Control#log_path" -> "Control#log_to_stdout?"
|
173
171
|
"Control#log_to_stdout?" -> "[log_file_path]"
|
174
|
-
"Control#convert_to_ip_address" -> "[ssl]"
|
175
172
|
"Control#convert_to_ip_address" -> "[verify_certificate]"
|
176
173
|
"Control#server" -> "Control#server_from_host"
|
177
174
|
"Control#setup_log" -> "Control#set_log_level!"
|
@@ -4,14 +4,16 @@
|
|
4
4
|
|
5
5
|
module NewRelic
|
6
6
|
module Agent
|
7
|
-
class
|
7
|
+
class AdaptiveSampler
|
8
8
|
|
9
|
-
def initialize target_samples = 10
|
9
|
+
def initialize target_samples = 10, interval_duration = 60
|
10
10
|
@target = target_samples
|
11
11
|
@seen = 0
|
12
12
|
@seen_last = 0
|
13
13
|
@sampled_count = 0
|
14
|
-
@
|
14
|
+
@interval_duration = interval_duration
|
15
|
+
@first_interval = true
|
16
|
+
@interval_start = Time.now.to_f
|
15
17
|
@lock = Mutex.new
|
16
18
|
end
|
17
19
|
|
@@ -20,7 +22,8 @@ module NewRelic
|
|
20
22
|
# sampled. This uses the adaptive sampling algorithm.
|
21
23
|
def sampled?
|
22
24
|
@lock.synchronize do
|
23
|
-
|
25
|
+
reset_if_interval_expired!
|
26
|
+
sampled = if @first_interval
|
24
27
|
@sampled_count < 10
|
25
28
|
elsif @sampled_count < @target
|
26
29
|
rand(@seen_last) < @target
|
@@ -35,15 +38,6 @@ module NewRelic
|
|
35
38
|
end
|
36
39
|
end
|
37
40
|
|
38
|
-
def reset!
|
39
|
-
@lock.synchronize do
|
40
|
-
@first_cycle = false
|
41
|
-
@seen_last = @seen
|
42
|
-
@seen = 0
|
43
|
-
@sampled_count = 0
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
41
|
def stats
|
48
42
|
@lock.synchronize do
|
49
43
|
{
|
@@ -54,6 +48,21 @@ module NewRelic
|
|
54
48
|
}
|
55
49
|
end
|
56
50
|
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def reset_if_interval_expired!
|
55
|
+
now = Time.now.to_f
|
56
|
+
return unless @interval_start + @interval_duration <= now
|
57
|
+
|
58
|
+
elapsed_intervals = Integer((now - @interval_start) / @interval_duration)
|
59
|
+
@interval_start = @interval_start + elapsed_intervals * @interval_duration
|
60
|
+
|
61
|
+
@first_interval = false
|
62
|
+
@seen_last = elapsed_intervals > 1 ? 0 : @seen
|
63
|
+
@seen = 0
|
64
|
+
@sampled_count = 0
|
65
|
+
end
|
57
66
|
end
|
58
67
|
end
|
59
68
|
end
|
@@ -30,7 +30,7 @@ require 'new_relic/agent/vm/monotonic_gc_profiler'
|
|
30
30
|
require 'new_relic/agent/utilization_data'
|
31
31
|
require 'new_relic/environment_report'
|
32
32
|
require 'new_relic/agent/attribute_filter'
|
33
|
-
require 'new_relic/agent/
|
33
|
+
require 'new_relic/agent/adaptive_sampler'
|
34
34
|
|
35
35
|
module NewRelic
|
36
36
|
module Agent
|
@@ -63,7 +63,7 @@ module NewRelic
|
|
63
63
|
@harvest_samplers = NewRelic::Agent::SamplerCollection.new(@events)
|
64
64
|
@monotonic_gc_profiler = NewRelic::Agent::VM::MonotonicGCProfiler.new
|
65
65
|
@javascript_instrumentor = NewRelic::Agent::JavascriptInstrumentor.new(@events)
|
66
|
-
@
|
66
|
+
@adaptive_sampler = NewRelic::Agent::AdaptiveSampler.new
|
67
67
|
|
68
68
|
@harvester = NewRelic::Agent::Harvester.new(@events)
|
69
69
|
@after_fork_lock = Mutex.new
|
@@ -144,7 +144,7 @@ module NewRelic
|
|
144
144
|
attr_reader :custom_event_aggregator
|
145
145
|
attr_reader :transaction_event_recorder
|
146
146
|
attr_reader :attribute_filter
|
147
|
-
attr_reader :
|
147
|
+
attr_reader :adaptive_sampler
|
148
148
|
|
149
149
|
def transaction_event_aggregator
|
150
150
|
@transaction_event_recorder.transaction_event_aggregator
|
@@ -1154,7 +1154,6 @@ module NewRelic
|
|
1154
1154
|
harvest_and_send_for_agent_commands
|
1155
1155
|
end
|
1156
1156
|
ensure
|
1157
|
-
throughput_monitor.reset!
|
1158
1157
|
NewRelic::Agent::Database.close_connections
|
1159
1158
|
duration = (Time.now - now).to_f
|
1160
1159
|
NewRelic::Agent.record_metric('Supportability/Harvest', duration)
|
@@ -113,9 +113,15 @@ module NewRelic
|
|
113
113
|
}
|
114
114
|
end
|
115
115
|
|
116
|
+
DEFAULT_LOG_DIR = 'log/'.freeze
|
117
|
+
|
116
118
|
def self.audit_log_path
|
117
119
|
Proc.new {
|
118
|
-
|
120
|
+
log_file_path = NewRelic::Agent.config[:log_file_path]
|
121
|
+
wants_stdout = (log_file_path.upcase == 'STDOUT')
|
122
|
+
audit_log_dir = wants_stdout ? DEFAULT_LOG_DIR : log_file_path
|
123
|
+
|
124
|
+
File.join(audit_log_dir, 'newrelic_audit.log')
|
119
125
|
}
|
120
126
|
end
|
121
127
|
|
@@ -142,10 +148,6 @@ module NewRelic
|
|
142
148
|
Proc.new { NewRelic::Agent.config[:apdex_t] * 4 }
|
143
149
|
end
|
144
150
|
|
145
|
-
def self.port
|
146
|
-
Proc.new { NewRelic::Agent.config[:ssl] ? 443 : 80 }
|
147
|
-
end
|
148
|
-
|
149
151
|
def self.profiling_available
|
150
152
|
Proc.new {
|
151
153
|
begin
|
@@ -157,6 +159,17 @@ module NewRelic
|
|
157
159
|
}
|
158
160
|
end
|
159
161
|
|
162
|
+
def self.host
|
163
|
+
Proc.new do
|
164
|
+
regex = /\A(?<identifier>.+?)x/
|
165
|
+
if matches = regex.match(String(NewRelic::Agent.config[:license_key]))
|
166
|
+
"collector.#{matches['identifier']}.nr-data.net"
|
167
|
+
else
|
168
|
+
'collector.newrelic.com'
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
160
173
|
def self.convert_to_regexp_list(raw_value)
|
161
174
|
value_list = convert_to_list(raw_value)
|
162
175
|
value_list.map do |value|
|
@@ -299,14 +312,6 @@ module NewRelic
|
|
299
312
|
:allowed_from_server => false,
|
300
313
|
:description => 'If <code>true</code>, enables <a href="https://docs.newrelic.com/docs/accounts-partnerships/accounts/security/high-security">high security mode</a>. Ensure you understand the implications of high security mode before enabling this setting.'
|
301
314
|
},
|
302
|
-
:ssl => {
|
303
|
-
:default => true,
|
304
|
-
:allow_nil => true,
|
305
|
-
:public => true,
|
306
|
-
:type => Boolean,
|
307
|
-
:allowed_from_server => false,
|
308
|
-
:description => 'If <code>true</code>, enables SSL for transmissions to the New Relic <a href="https://docs.newrelic.com/docs/apm/new-relic-apm/getting-started/glossary#collector">collector</a>.'
|
309
|
-
},
|
310
315
|
:proxy_host => {
|
311
316
|
:default => nil,
|
312
317
|
:allow_nil => true,
|
@@ -450,7 +455,7 @@ module NewRelic
|
|
450
455
|
:description => 'Specify a whitelist of exceptions you do not want the agent to strip when <a href="#strip_exception_messages-enabled">strip_exception_messages</a> is <code>true</code>. Separate exceptions with a comma. For example, <code>"ImportantException,PreserveMessageException"</code>.'
|
451
456
|
},
|
452
457
|
:host => {
|
453
|
-
:default =>
|
458
|
+
:default => DefaultSource.host,
|
454
459
|
:public => false,
|
455
460
|
:type => String,
|
456
461
|
:allowed_from_server => false,
|
@@ -464,7 +469,7 @@ module NewRelic
|
|
464
469
|
:description => 'API host for New Relic.'
|
465
470
|
},
|
466
471
|
:port => {
|
467
|
-
:default =>
|
472
|
+
:default => 443,
|
468
473
|
:public => false,
|
469
474
|
:type => Integer,
|
470
475
|
:allowed_from_server => false,
|
@@ -578,7 +583,7 @@ module NewRelic
|
|
578
583
|
:description => 'Defines a name for the log file.'
|
579
584
|
},
|
580
585
|
:log_file_path => {
|
581
|
-
:default =>
|
586
|
+
:default => DefaultSource::DEFAULT_LOG_DIR,
|
582
587
|
:public => true,
|
583
588
|
:type => String,
|
584
589
|
:allowed_from_server => false,
|
@@ -1082,7 +1087,7 @@ module NewRelic
|
|
1082
1087
|
:description => 'List of trusted New Relic account IDs for the purposes of cross-application tracing. Inbound requests from applications including cross-application headers that do not come from an account in this list will be ignored.'
|
1083
1088
|
},
|
1084
1089
|
:"cross_application_tracer.enabled" => {
|
1085
|
-
:default =>
|
1090
|
+
:default => Proc.new { !NewRelic::Agent.config[:'distributed_tracing.enabled'] },
|
1086
1091
|
:public => true,
|
1087
1092
|
:type => Boolean,
|
1088
1093
|
:allowed_from_server => true,
|
@@ -21,6 +21,17 @@ module NewRelic
|
|
21
21
|
Obfuscator.instance.obfuscate_single_quote_literals(sql) =~ /\$\d+/
|
22
22
|
end
|
23
23
|
|
24
|
+
# SQL containing a semicolon in the middle (with something
|
25
|
+
# other than whitespace after it) may contain two or more
|
26
|
+
# queries. It's not safe to EXPLAIN this kind of expression,
|
27
|
+
# since it could lead to executing unwanted SQL.
|
28
|
+
#
|
29
|
+
MULTIPLE_QUERIES = Regexp.new(';\s*\S+')
|
30
|
+
|
31
|
+
def multiple_queries?(sql)
|
32
|
+
sql =~ MULTIPLE_QUERIES
|
33
|
+
end
|
34
|
+
|
24
35
|
def handle_exception_in_explain
|
25
36
|
yield
|
26
37
|
rescue => e
|
@@ -17,12 +17,14 @@ module NewRelic
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def on_before_call(request)
|
20
|
-
return unless
|
20
|
+
return unless NewRelic::Agent.config[:'distributed_tracing.enabled']
|
21
21
|
return unless payload = request[NEWRELIC_TRACE_KEY]
|
22
22
|
|
23
23
|
state = NewRelic::Agent::TransactionState.tl_get
|
24
24
|
txn = state.current_transaction
|
25
|
-
txn.accept_distributed_trace_payload
|
25
|
+
if txn.accept_distributed_trace_payload payload
|
26
|
+
txn.distributed_trace_payload.caller_transport_type = HTTP_TRANSPORT_TYPE
|
27
|
+
end
|
26
28
|
end
|
27
29
|
end
|
28
30
|
end
|
@@ -7,73 +7,66 @@ require 'base64'
|
|
7
7
|
module NewRelic
|
8
8
|
module Agent
|
9
9
|
class DistributedTracePayload
|
10
|
-
VERSION =[0,
|
11
|
-
|
10
|
+
VERSION =[0, 1].freeze
|
11
|
+
PARENT_TYPE = "App".freeze
|
12
12
|
POUND = '#'.freeze
|
13
13
|
|
14
14
|
# Key names for serialization
|
15
|
-
VERSION_KEY
|
16
|
-
DATA_KEY
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
ID_KEY
|
21
|
-
|
22
|
-
SAMPLED_KEY
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
15
|
+
VERSION_KEY = 'v'.freeze
|
16
|
+
DATA_KEY = 'd'.freeze
|
17
|
+
PARENT_TYPE_KEY = 'ty'.freeze
|
18
|
+
PARENT_ACCOUNT_ID_KEY = 'ac'.freeze
|
19
|
+
PARENT_APP_KEY = 'ap'.freeze
|
20
|
+
ID_KEY = 'id'.freeze
|
21
|
+
TRACE_ID_KEY = 'tr'.freeze
|
22
|
+
SAMPLED_KEY = 'sa'.freeze
|
23
|
+
PARENT_ID_KEY = 'pa'.freeze
|
24
|
+
TIMESTAMP_KEY = 'ti'.freeze
|
25
|
+
PRIORITY_KEY = 'pr'.freeze
|
32
26
|
|
33
27
|
# Intrinsic Keys
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
ORDER_INTRINSIC_KEY = "nr.order".freeze
|
42
|
-
GUID_INTRINSIC_KEY = "nr.guid".freeze
|
43
|
-
REFERRING_TRANSACTION_GUID_INTRINSIC_KEY = "nr.referringTransactionGuid".freeze
|
28
|
+
PARENT_TYPE_INTRINSIC_KEY = "parent.type".freeze
|
29
|
+
PARENT_APP_INTRINSIC_KEY = "parent.app".freeze
|
30
|
+
PARENT_ACCOUNT_ID_INTRINSIC_KEY = "parent.account".freeze
|
31
|
+
PARENT_TRANSPORT_TYPE_INTRINSIC_KEY = "parent.transportType".freeze
|
32
|
+
PARENT_TRANSPORT_DURATION_INTRINSIC_KEY = "parent.transportDuration".freeze
|
33
|
+
GUID_INTRINSIC_KEY = "guid".freeze
|
34
|
+
TRACE_ID_INTRINSIC_KEY = "traceId".freeze
|
44
35
|
TRIP_ID_INTRINSIC_KEY = "nr.tripId".freeze
|
45
|
-
|
36
|
+
PARENT_ID_INTRINSIC_KEY = "parentId".freeze
|
37
|
+
GRANDPARENT_ID_INTRINSIC_KEY = "grandparentId".freeze
|
46
38
|
COMMA = ",".freeze
|
47
39
|
|
48
40
|
INTRINSIC_KEYS = [
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
CALLER_HOST_INTRINSIC_KEY,
|
55
|
-
DEPTH_INTRINSIC_KEY,
|
56
|
-
ORDER_INTRINSIC_KEY,
|
41
|
+
PARENT_TYPE_INTRINSIC_KEY,
|
42
|
+
PARENT_APP_INTRINSIC_KEY,
|
43
|
+
PARENT_ACCOUNT_ID_INTRINSIC_KEY,
|
44
|
+
PARENT_TRANSPORT_TYPE_INTRINSIC_KEY,
|
45
|
+
PARENT_TRANSPORT_DURATION_INTRINSIC_KEY,
|
57
46
|
GUID_INTRINSIC_KEY,
|
58
|
-
|
47
|
+
TRACE_ID_INTRINSIC_KEY,
|
59
48
|
TRIP_ID_INTRINSIC_KEY,
|
60
|
-
|
49
|
+
PARENT_ID_INTRINSIC_KEY,
|
50
|
+
GRANDPARENT_ID_INTRINSIC_KEY
|
61
51
|
].freeze
|
62
52
|
|
53
|
+
# Intrinsic Values
|
54
|
+
PARENT_TRANSPORT_TYPE_UNKNOWN = 'unknown'.freeze
|
55
|
+
|
63
56
|
class << self
|
64
|
-
def for_transaction transaction
|
57
|
+
def for_transaction transaction
|
65
58
|
payload = new
|
66
59
|
return payload unless connected?
|
67
60
|
|
68
61
|
payload.version = VERSION
|
69
|
-
payload.
|
62
|
+
payload.parent_type = PARENT_TYPE
|
70
63
|
|
71
64
|
# We should not rely on the xp_id being formulated this way, but we have
|
72
65
|
# seen nil account ids coming down in staging for some accounts
|
73
66
|
account_id, fallback_app_id = Agent.config[:cross_process_id].split(POUND)
|
74
|
-
payload.
|
67
|
+
payload.parent_account_id = account_id
|
75
68
|
|
76
|
-
payload.
|
69
|
+
payload.parent_app_id = if Agent.config[:application_id].empty?
|
77
70
|
fallback_app_id
|
78
71
|
else
|
79
72
|
Agent.config[:application_id]
|
@@ -81,18 +74,11 @@ module NewRelic
|
|
81
74
|
|
82
75
|
payload.timestamp = (Time.now.to_f * 1000).round
|
83
76
|
payload.id = transaction.guid
|
84
|
-
payload.
|
77
|
+
payload.trace_id = transaction.trace_id
|
85
78
|
payload.sampled = transaction.sampled?
|
86
|
-
payload.
|
87
|
-
payload.
|
88
|
-
payload.
|
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
|
79
|
+
payload.priority = transaction.priority
|
80
|
+
payload.parent_id = transaction.parent_id
|
81
|
+
payload.grandparent_id = transaction.grandparent_id
|
96
82
|
|
97
83
|
payload
|
98
84
|
end
|
@@ -103,23 +89,16 @@ module NewRelic
|
|
103
89
|
|
104
90
|
payload = new
|
105
91
|
payload.version = raw_payload[VERSION_KEY]
|
106
|
-
payload.
|
107
|
-
payload.
|
108
|
-
payload.
|
92
|
+
payload.parent_type = payload_data[PARENT_TYPE_KEY]
|
93
|
+
payload.parent_account_id = payload_data[PARENT_ACCOUNT_ID_KEY]
|
94
|
+
payload.parent_app_id = payload_data[PARENT_APP_KEY]
|
109
95
|
payload.timestamp = payload_data[TIMESTAMP_KEY]
|
110
96
|
payload.id = payload_data[ID_KEY]
|
111
|
-
payload.
|
97
|
+
payload.trace_id = payload_data[TRACE_ID_KEY]
|
112
98
|
payload.sampled = payload_data[SAMPLED_KEY]
|
113
|
-
payload.
|
114
|
-
payload.
|
115
|
-
payload.
|
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
|
99
|
+
payload.priority = payload_data[PRIORITY_KEY]
|
100
|
+
payload.parent_id = payload_data[ID_KEY] # Our parent ID is the caller's GUID
|
101
|
+
payload.grandparent_id = payload_data[PARENT_ID_KEY] # Our grandparent ID is the caller's parent ID
|
123
102
|
|
124
103
|
payload
|
125
104
|
end
|
@@ -129,11 +108,15 @@ module NewRelic
|
|
129
108
|
from_json decoded_payload
|
130
109
|
end
|
131
110
|
|
132
|
-
#
|
133
|
-
def
|
134
|
-
|
135
|
-
|
136
|
-
|
111
|
+
# Assigns intrinsics for the first distributed trace in a trip
|
112
|
+
def assign_intrinsics_for_first_trace transaction, transaction_payload
|
113
|
+
transaction_payload[GUID_INTRINSIC_KEY] = transaction.guid
|
114
|
+
transaction_payload[TRACE_ID_INTRINSIC_KEY] = transaction.trace_id
|
115
|
+
transaction_payload[TRIP_ID_INTRINSIC_KEY] = transaction.trace_id
|
116
|
+
end
|
117
|
+
|
118
|
+
def major_version_matches?(payload)
|
119
|
+
payload.version[0] == VERSION[0]
|
137
120
|
end
|
138
121
|
|
139
122
|
private
|
@@ -146,26 +129,22 @@ module NewRelic
|
|
146
129
|
end
|
147
130
|
|
148
131
|
attr_accessor :version,
|
149
|
-
:
|
132
|
+
:parent_type,
|
150
133
|
:caller_transport_type,
|
151
|
-
:
|
152
|
-
:
|
134
|
+
:parent_account_id,
|
135
|
+
:parent_app_id,
|
153
136
|
:id,
|
154
|
-
:
|
137
|
+
:trace_id,
|
155
138
|
:sampled,
|
156
|
-
:
|
157
|
-
:
|
158
|
-
:
|
159
|
-
:
|
160
|
-
:order,
|
161
|
-
:depth,
|
162
|
-
:timestamp,
|
163
|
-
:host
|
139
|
+
:priority,
|
140
|
+
:parent_id,
|
141
|
+
:grandparent_id,
|
142
|
+
:timestamp
|
164
143
|
|
165
144
|
alias_method :sampled?, :sampled
|
166
145
|
|
167
|
-
def
|
168
|
-
|
146
|
+
def initialize
|
147
|
+
@caller_transport_type = PARENT_TRANSPORT_TYPE_UNKNOWN
|
169
148
|
end
|
170
149
|
|
171
150
|
def to_json
|
@@ -174,27 +153,19 @@ module NewRelic
|
|
174
153
|
}
|
175
154
|
|
176
155
|
result[DATA_KEY] = {
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
ID_KEY
|
181
|
-
|
182
|
-
SAMPLED_KEY
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
156
|
+
PARENT_TYPE_KEY => parent_type,
|
157
|
+
PARENT_ACCOUNT_ID_KEY => parent_account_id,
|
158
|
+
PARENT_APP_KEY => parent_app_id,
|
159
|
+
ID_KEY => id,
|
160
|
+
TRACE_ID_KEY => trace_id,
|
161
|
+
SAMPLED_KEY => sampled,
|
162
|
+
PRIORITY_KEY => priority,
|
163
|
+
PARENT_ID_KEY => parent_id,
|
164
|
+
# GRANDPARENT_ID_KEY does not go into the outbound JSON payload;
|
165
|
+
# the callee will take our parent ID as its grandparent ID
|
187
166
|
TIMESTAMP_KEY => timestamp,
|
188
167
|
}
|
189
168
|
|
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
169
|
JSON.dump(result)
|
199
170
|
end
|
200
171
|
|
@@ -204,19 +175,17 @@ module NewRelic
|
|
204
175
|
Base64.strict_encode64 to_json
|
205
176
|
end
|
206
177
|
|
207
|
-
def assign_intrinsics transaction,
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
payload[TRIP_ID_INTRINSIC_KEY] = trip_id
|
219
|
-
payload[PARENT_IDS_INTRINSIC_KEY] = parent_ids.join COMMA if parent_ids
|
178
|
+
def assign_intrinsics transaction, transaction_payload
|
179
|
+
transaction_payload[PARENT_TYPE_INTRINSIC_KEY] = parent_type
|
180
|
+
transaction_payload[PARENT_APP_INTRINSIC_KEY] = parent_app_id
|
181
|
+
transaction_payload[PARENT_ACCOUNT_ID_INTRINSIC_KEY] = parent_account_id
|
182
|
+
transaction_payload[PARENT_TRANSPORT_TYPE_INTRINSIC_KEY] = caller_transport_type
|
183
|
+
transaction_payload[PARENT_TRANSPORT_DURATION_INTRINSIC_KEY] = transaction.transport_duration
|
184
|
+
transaction_payload[GUID_INTRINSIC_KEY] = transaction.guid
|
185
|
+
transaction_payload[TRACE_ID_INTRINSIC_KEY] = trace_id
|
186
|
+
transaction_payload[TRIP_ID_INTRINSIC_KEY] = trace_id
|
187
|
+
transaction_payload[PARENT_ID_INTRINSIC_KEY] = parent_id if parent_id
|
188
|
+
transaction_payload[GRANDPARENT_ID_INTRINSIC_KEY] = grandparent_id if grandparent_id
|
220
189
|
end
|
221
190
|
end
|
222
191
|
end
|