newrelic_rpm 6.7.0.359 → 6.8.0.360
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +41 -6
- data/CHANGELOG.md +76 -0
- data/Guardfile +7 -1
- data/lib/new_relic/agent.rb +31 -0
- data/lib/new_relic/agent/agent.rb +7 -2
- 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 +152 -0
- data/lib/new_relic/agent/autostart.rb +19 -14
- data/lib/new_relic/agent/configuration/default_source.rb +72 -5
- data/lib/new_relic/agent/configuration/yaml_source.rb +10 -5
- data/lib/new_relic/agent/connect/request_builder.rb +3 -11
- 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_trace_intrinsics.rb +90 -0
- data/lib/new_relic/agent/distributed_trace_metrics.rb +74 -0
- data/lib/new_relic/agent/distributed_trace_monitor.rb +2 -12
- data/lib/new_relic/agent/distributed_trace_payload.rb +9 -76
- data/lib/new_relic/agent/distributed_trace_transport_type.rb +43 -0
- data/lib/new_relic/agent/guid_generator.rb +28 -0
- data/lib/new_relic/agent/logging.rb +4 -0
- data/lib/new_relic/agent/new_relic_service.rb +7 -5
- data/lib/new_relic/agent/span_event_aggregator.rb +1 -0
- data/lib/new_relic/agent/span_event_primitive.rb +29 -7
- data/lib/new_relic/agent/sql_sampler.rb +1 -1
- data/lib/new_relic/agent/trace_context.rb +244 -0
- data/lib/new_relic/agent/trace_context_payload.rb +134 -0
- data/lib/new_relic/agent/trace_context_request_monitor.rb +42 -0
- data/lib/new_relic/agent/transaction.rb +26 -18
- data/lib/new_relic/agent/transaction/abstract_segment.rb +2 -2
- data/lib/new_relic/agent/transaction/distributed_tracing.rb +20 -101
- data/lib/new_relic/agent/transaction/external_request_segment.rb +18 -5
- data/lib/new_relic/agent/transaction/segment.rb +7 -1
- data/lib/new_relic/agent/transaction/trace_context.rb +159 -0
- data/lib/new_relic/agent/transaction/trace_node.rb +8 -3
- data/lib/new_relic/agent/transaction_error_primitive.rb +4 -11
- data/lib/new_relic/agent/transaction_event_primitive.rb +3 -11
- data/lib/new_relic/coerce.rb +29 -6
- data/lib/new_relic/control/instance_methods.rb +10 -1
- data/lib/new_relic/dependency_detection.rb +4 -4
- data/lib/new_relic/noticed_error.rb +8 -4
- data/lib/new_relic/version.rb +1 -1
- data/newrelic_rpm.gemspec +6 -4
- data/test/agent_helper.rb +88 -9
- data/true +0 -0
- metadata +50 -18
- 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
@@ -20,23 +20,28 @@ module NewRelic
|
|
20
20
|
|
21
21
|
|
22
22
|
# The constants, executables (i.e. $0) and rake tasks used can be
|
23
|
-
# configured with the config keys 'autostart.
|
24
|
-
# 'autostart.
|
25
|
-
# 'autostart.
|
23
|
+
# configured with the config keys 'autostart.denylisted_constants',
|
24
|
+
# 'autostart.denylisted_executables' and
|
25
|
+
# 'autostart.denylisted_rake_tasks'
|
26
26
|
def agent_should_start?
|
27
|
-
!
|
28
|
-
!
|
29
|
-
!
|
27
|
+
!denylisted_constants? &&
|
28
|
+
!denylisted_executables? &&
|
29
|
+
!in_denylisted_rake_task?
|
30
30
|
end
|
31
31
|
|
32
|
-
|
33
|
-
|
32
|
+
COMMA = ",".freeze
|
33
|
+
|
34
|
+
def denylisted_constants?
|
35
|
+
# For backwards compatibility until :'autostart_blacklisted_constants' config option is removed
|
36
|
+
constants = NewRelic::Agent.config[:'autostart.denylisted_constants'] << COMMA << NewRelic::Agent.config[:'autostart.blacklisted_constants']
|
37
|
+
|
38
|
+
denylisted?(constants) do |name|
|
34
39
|
constant_is_defined?(name)
|
35
40
|
end
|
36
41
|
end
|
37
42
|
|
38
|
-
def
|
39
|
-
|
43
|
+
def denylisted_executables?
|
44
|
+
denylisted?(NewRelic::Agent.config[:'autostart.denylisted_executables']) do |bin|
|
40
45
|
File.basename($0) == bin
|
41
46
|
end
|
42
47
|
end
|
@@ -47,18 +52,18 @@ module NewRelic
|
|
47
52
|
!!::NewRelic::LanguageSupport.constantize(const_name)
|
48
53
|
end
|
49
54
|
|
50
|
-
def
|
55
|
+
def denylisted?(value, &block)
|
51
56
|
value.split(/\s*,\s*/).any?(&block)
|
52
57
|
end
|
53
58
|
|
54
|
-
def
|
59
|
+
def in_denylisted_rake_task?
|
55
60
|
tasks = begin
|
56
61
|
::Rake.application.top_level_tasks
|
57
62
|
rescue => e
|
58
|
-
::NewRelic::Agent.logger.debug("Not in Rake environment so skipping
|
63
|
+
::NewRelic::Agent.logger.debug("Not in Rake environment so skipping denylisted_rake_tasks check: #{e}")
|
59
64
|
[]
|
60
65
|
end
|
61
|
-
!(tasks & ::NewRelic::Agent.config[:'autostart.
|
66
|
+
!(tasks & ::NewRelic::Agent.config[:'autostart.denylisted_rake_tasks'].split(/\s*,\s*/)).empty?
|
62
67
|
end
|
63
68
|
end
|
64
69
|
end
|
@@ -218,9 +218,19 @@ module NewRelic
|
|
218
218
|
end
|
219
219
|
const_names.compact
|
220
220
|
end
|
221
|
+
|
222
|
+
def self.enforce_fallback(allowed_values: nil, fallback: nil)
|
223
|
+
Proc.new do |configured_value|
|
224
|
+
if allowed_values.any? { |v| v =~ /#{configured_value}/i }
|
225
|
+
configured_value
|
226
|
+
else
|
227
|
+
fallback
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
221
231
|
end
|
222
232
|
|
223
|
-
|
233
|
+
AUTOSTART_DENYLISTED_RAKE_TASKS = [
|
224
234
|
'about',
|
225
235
|
'assets:clean',
|
226
236
|
'assets:clobber',
|
@@ -416,6 +426,17 @@ module NewRelic
|
|
416
426
|
:description => 'Autodetected application framework used to enable framework-specific functionality.'
|
417
427
|
},
|
418
428
|
:'autostart.blacklisted_constants' => {
|
429
|
+
:default => 'Rails::Console',
|
430
|
+
:public => true,
|
431
|
+
:type => String,
|
432
|
+
:allowed_from_server => false,
|
433
|
+
:description => 'Deprecated. ' \
|
434
|
+
'For agent versions 6.8.0 or higher, ' \
|
435
|
+
'use <a href="#autostart-denylisted_constants"><code>' \
|
436
|
+
'autostart.denylisted_constants' \
|
437
|
+
'</code></a> instead.'
|
438
|
+
},
|
439
|
+
:'autostart.denylisted_constants' => {
|
419
440
|
:default => 'Rails::Console',
|
420
441
|
:public => true,
|
421
442
|
:type => String,
|
@@ -427,10 +448,32 @@ module NewRelic
|
|
427
448
|
:public => true,
|
428
449
|
:type => String,
|
429
450
|
:allowed_from_server => false,
|
451
|
+
:description => 'Deprecated. ' \
|
452
|
+
'For agent versions 6.8.0 or higher, ' \
|
453
|
+
'use <a href="#autostart-denylisted_executables"><code>' \
|
454
|
+
'autostart.denylisted_executables' \
|
455
|
+
'</code></a> instead.'
|
456
|
+
},
|
457
|
+
:'autostart.denylisted_executables' => {
|
458
|
+
:default => value_of(:'autostart.blacklisted_executables'),
|
459
|
+
:public => true,
|
460
|
+
:type => String,
|
461
|
+
:allowed_from_server => false,
|
430
462
|
:description => 'Defines a comma-delimited list of executables that the agent should not instrument. For example, <code>rake,my_ruby_script.rb</code>.'
|
431
463
|
},
|
432
464
|
:'autostart.blacklisted_rake_tasks' => {
|
433
|
-
:default =>
|
465
|
+
:default => AUTOSTART_DENYLISTED_RAKE_TASKS,
|
466
|
+
:public => true,
|
467
|
+
:type => String,
|
468
|
+
:allowed_from_server => false,
|
469
|
+
:description => 'Deprecated. ' \
|
470
|
+
'For agent versions 6.8.0 or higher, ' \
|
471
|
+
'use <a href="#autostart-denylisted_rake_tasks"><code>' \
|
472
|
+
'autostart.denylisted_rake_tasks' \
|
473
|
+
'</code></a> instead.'
|
474
|
+
},
|
475
|
+
:'autostart.denylisted_rake_tasks' => {
|
476
|
+
:default => value_of(:'autostart.blacklisted_rake_tasks'),
|
434
477
|
:public => true,
|
435
478
|
:type => String,
|
436
479
|
:allowed_from_server => false,
|
@@ -478,15 +521,29 @@ module NewRelic
|
|
478
521
|
:public => true,
|
479
522
|
:type => Boolean,
|
480
523
|
:allowed_from_server => false,
|
481
|
-
:description => 'If true, the agent strips messages from all exceptions except those in the <a href="#strip_exception_messages-
|
524
|
+
:description => 'If true, the agent strips messages from all exceptions except those in the <a href="#strip_exception_messages-allowlist">allowlist</a>. Enabled automatically in <a href="https://docs.newrelic.com/docs/accounts-partnerships/accounts/security/high-security">high security mode</a>.'
|
482
525
|
},
|
483
526
|
:'strip_exception_messages.whitelist' => {
|
484
527
|
:default => '',
|
485
528
|
:public => true,
|
486
529
|
:type => String,
|
530
|
+
:deprecated => true,
|
487
531
|
:allowed_from_server => false,
|
488
532
|
:transform => DefaultSource.method(:convert_to_constant_list),
|
489
|
-
:description => '
|
533
|
+
:description => 'Deprecated. ' \
|
534
|
+
'For agent versions 6.8.0 or higher, ' \
|
535
|
+
'use <a href="#strip_exception_messages-allowlist"><code>' \
|
536
|
+
'strip_exception_messages.allowed_classes' \
|
537
|
+
'</code></a> instead.'
|
538
|
+
},
|
539
|
+
:'strip_exception_messages.allowed_classes' => {
|
540
|
+
:default => '',
|
541
|
+
:public => true,
|
542
|
+
:type => String,
|
543
|
+
:deprecated => true,
|
544
|
+
:allowed_from_server => false,
|
545
|
+
:transform => DefaultSource.method(:convert_to_constant_list),
|
546
|
+
:description => 'Specify a list 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>.'
|
490
547
|
},
|
491
548
|
:host => {
|
492
549
|
:default => DefaultSource.host,
|
@@ -545,7 +602,7 @@ module NewRelic
|
|
545
602
|
:description => 'Use HTTP PUT requests instead of POST.'
|
546
603
|
},
|
547
604
|
:compressed_content_encoding => {
|
548
|
-
:default => '
|
605
|
+
:default => 'gzip',
|
549
606
|
:public => false,
|
550
607
|
:type => String,
|
551
608
|
:allowed_from_server => false,
|
@@ -1831,6 +1888,16 @@ module NewRelic
|
|
1831
1888
|
:allowed_from_server => false,
|
1832
1889
|
:description => 'Distributed tracing lets you see the path that a request takes through your distributed system. Enabling distributed tracing changes the behavior of some New Relic features, so carefully consult the <a href="https://docs.newrelic.com/docs/transition-guide-distributed-tracing">transition guide</a> before you enable this feature.'
|
1833
1890
|
},
|
1891
|
+
:'distributed_tracing.format' => {
|
1892
|
+
:default => 'newrelic',
|
1893
|
+
:public => false,
|
1894
|
+
:type => String,
|
1895
|
+
:transform => DefaultSource.enforce_fallback(
|
1896
|
+
allowed_values: ['w3c', 'newrelic'],
|
1897
|
+
fallback: 'newrelic'),
|
1898
|
+
:allowed_from_server => false,
|
1899
|
+
:description => 'The format to use for distributed tracing if it is enabled. Options are w3c for W3C Trace Context or newrelic for New Relic Distriburted Tracing. Defaults to New Relic Distributed Tracing.'
|
1900
|
+
},
|
1834
1901
|
:trusted_account_key => {
|
1835
1902
|
:default => nil,
|
1836
1903
|
:allow_nil => true,
|
@@ -12,6 +12,7 @@ module NewRelic
|
|
12
12
|
attr_reader :generated_for_user, :license_key
|
13
13
|
|
14
14
|
def initialize(path, env)
|
15
|
+
@path = path
|
15
16
|
config = {}
|
16
17
|
@failures = []
|
17
18
|
|
@@ -118,23 +119,27 @@ module NewRelic
|
|
118
119
|
end
|
119
120
|
|
120
121
|
def booleanify_values(config, *keys)
|
121
|
-
# auto means defer
|
122
|
+
# auto means defer to default
|
122
123
|
keys.each do |option|
|
123
|
-
if config[option]
|
124
|
+
if 'auto' == config[option]
|
124
125
|
config.delete(option)
|
125
126
|
elsif !config[option].nil? && !is_boolean?(config[option])
|
126
|
-
|
127
|
+
coerced_value = !!(config[option].to_s =~ /yes|on|true/i)
|
128
|
+
if !coerced_value
|
129
|
+
log_failure "Unexpected value (#{config[option]}) for '#{option}' in #{@path}"
|
130
|
+
end
|
131
|
+
config[option] = coerced_value
|
127
132
|
end
|
128
133
|
end
|
129
134
|
end
|
130
135
|
|
131
136
|
def is_boolean?(value)
|
132
|
-
value ==
|
137
|
+
!!value == value
|
133
138
|
end
|
134
139
|
|
135
140
|
def log_failure(*messages)
|
136
141
|
::NewRelic::Agent.logger.error(*messages)
|
137
|
-
@failures <<
|
142
|
+
messages.each { |message| @failures << message }
|
138
143
|
end
|
139
144
|
end
|
140
145
|
end
|
@@ -11,10 +11,11 @@ module NewRelic
|
|
11
11
|
|
12
12
|
class RequestBuilder
|
13
13
|
|
14
|
-
def initialize(new_relic_service, config, event_harvest_config)
|
14
|
+
def initialize(new_relic_service, config, event_harvest_config, environment_report)
|
15
15
|
@service = new_relic_service
|
16
16
|
@config = config
|
17
17
|
@event_harvest_config = event_harvest_config
|
18
|
+
@environment_report = sanitize_environment_report(environment_report)
|
18
19
|
end
|
19
20
|
|
20
21
|
|
@@ -29,7 +30,7 @@ module NewRelic
|
|
29
30
|
:language => 'ruby',
|
30
31
|
:labels => Agent.config.parsed_labels,
|
31
32
|
:agent_version => NewRelic::VERSION::STRING,
|
32
|
-
:environment =>
|
33
|
+
:environment => @environment_report,
|
33
34
|
:metadata => environment_metadata,
|
34
35
|
:settings => Agent.config.to_collector_hash,
|
35
36
|
:high_security => Agent.config[:high_security],
|
@@ -47,15 +48,6 @@ module NewRelic
|
|
47
48
|
environment_report
|
48
49
|
end
|
49
50
|
|
50
|
-
# Checks whether we should send environment info, and if so,
|
51
|
-
# returns the snapshot from the local environment.
|
52
|
-
# Generating the EnvironmentReport has the potential to trigger
|
53
|
-
# require calls in Rails environments, so this method should only
|
54
|
-
# be called synchronously from on the main thread.
|
55
|
-
def environment_report
|
56
|
-
Agent.config[:send_environment_info] ? Array(EnvironmentReport.new) : []
|
57
|
-
end
|
58
|
-
|
59
51
|
def environment_metadata
|
60
52
|
ENV.select {|k, v| k =~ /^NEW_RELIC_METADATA_/}
|
61
53
|
end
|
@@ -13,7 +13,7 @@ module NewRelic
|
|
13
13
|
OBFUSCATE_KEYS = [ 'filter', 'query', 'pipeline' ].freeze
|
14
14
|
|
15
15
|
# Keys that will get completely removed from the statement.
|
16
|
-
|
16
|
+
DENYLISTED_KEYS = [ 'deletes', 'documents', 'updates' ].freeze
|
17
17
|
|
18
18
|
def self.format(command_name, database_name, command)
|
19
19
|
return nil unless NewRelic::Agent.config[:'mongo.capture_queries']
|
@@ -25,7 +25,7 @@ module NewRelic
|
|
25
25
|
}
|
26
26
|
|
27
27
|
command.each do |key, value|
|
28
|
-
next if
|
28
|
+
next if DENYLISTED_KEYS.include?(key)
|
29
29
|
if OBFUSCATE_KEYS.include?(key)
|
30
30
|
obfuscated = obfuscate(value)
|
31
31
|
result[key] = obfuscated if obfuscated
|
@@ -8,31 +8,31 @@ module NewRelic
|
|
8
8
|
module Mongo
|
9
9
|
module Obfuscator
|
10
10
|
|
11
|
-
|
11
|
+
ALLOWLIST = [:operation].freeze
|
12
12
|
|
13
|
-
def self.obfuscate_statement(source,
|
13
|
+
def self.obfuscate_statement(source, allowlist = ALLOWLIST)
|
14
14
|
if source.is_a? Hash
|
15
15
|
obfuscated = {}
|
16
16
|
source.each do |key, value|
|
17
|
-
if
|
17
|
+
if allowlist.include?(key)
|
18
18
|
obfuscated[key] = value
|
19
19
|
else
|
20
|
-
obfuscated[key] = obfuscate_value(value,
|
20
|
+
obfuscated[key] = obfuscate_value(value, allowlist)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
obfuscated
|
24
24
|
else
|
25
|
-
obfuscate_value(source,
|
25
|
+
obfuscate_value(source, allowlist)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
29
|
QUESTION_MARK = '?'.freeze
|
30
30
|
|
31
|
-
def self.obfuscate_value(value,
|
31
|
+
def self.obfuscate_value(value, allowlist = ALLOWLIST)
|
32
32
|
if value.is_a?(Hash)
|
33
|
-
obfuscate_statement(value,
|
33
|
+
obfuscate_statement(value, allowlist)
|
34
34
|
elsif value.is_a?(Array)
|
35
|
-
value.map {|v| obfuscate_value(v,
|
35
|
+
value.map {|v| obfuscate_value(v, allowlist)}
|
36
36
|
else
|
37
37
|
QUESTION_MARK
|
38
38
|
end
|
@@ -0,0 +1,90 @@
|
|
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/distributed_trace_transport_type'
|
6
|
+
|
7
|
+
module NewRelic
|
8
|
+
module Agent
|
9
|
+
module DistributedTraceIntrinsics
|
10
|
+
extend self
|
11
|
+
|
12
|
+
# Intrinsic Keys
|
13
|
+
PARENT_TYPE_KEY = "parent.type".freeze
|
14
|
+
PARENT_APP_KEY = "parent.app".freeze
|
15
|
+
PARENT_ACCOUNT_ID_KEY = "parent.account".freeze
|
16
|
+
PARENT_TRANSPORT_TYPE_KEY = "parent.transportType".freeze
|
17
|
+
PARENT_TRANSPORT_DURATION_KEY = "parent.transportDuration".freeze
|
18
|
+
GUID_KEY = "guid".freeze
|
19
|
+
TRACE_ID_KEY = "traceId".freeze
|
20
|
+
PARENT_TRANSACTION_ID_KEY = "parentId".freeze
|
21
|
+
PARENT_SPAN_ID_KEY = "parentSpanId".freeze
|
22
|
+
SAMPLED_KEY = "sampled".freeze
|
23
|
+
|
24
|
+
INTRINSIC_KEYS = [
|
25
|
+
PARENT_TYPE_KEY,
|
26
|
+
PARENT_APP_KEY,
|
27
|
+
PARENT_ACCOUNT_ID_KEY,
|
28
|
+
PARENT_TRANSPORT_TYPE_KEY,
|
29
|
+
PARENT_TRANSPORT_DURATION_KEY,
|
30
|
+
GUID_KEY,
|
31
|
+
TRACE_ID_KEY,
|
32
|
+
PARENT_TRANSACTION_ID_KEY,
|
33
|
+
PARENT_SPAN_ID_KEY,
|
34
|
+
SAMPLED_KEY
|
35
|
+
].freeze
|
36
|
+
|
37
|
+
# This method extracts intrinsics from the transaction_payload and
|
38
|
+
# inserts them into the specified destination.
|
39
|
+
def copy_to_hash transaction_payload, destination
|
40
|
+
return unless enabled?
|
41
|
+
INTRINSIC_KEYS.each do |key|
|
42
|
+
value = transaction_payload[key]
|
43
|
+
destination[key] = value unless value.nil?
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# This method extracts intrinsics from the transaction_payload and
|
48
|
+
# inserts them as intrinsics in the specified transaction_attributes
|
49
|
+
def copy_to_attributes transaction_payload, destination
|
50
|
+
return unless enabled?
|
51
|
+
INTRINSIC_KEYS.each do |key|
|
52
|
+
next unless transaction_payload.key? key
|
53
|
+
destination.add_intrinsic_attribute key, transaction_payload[key]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# This method takes all distributed tracing intrinsics from the transaction
|
58
|
+
# and the distributed_trace_payload, and populates them into the destination
|
59
|
+
def copy_from_transaction transaction, distributed_trace_payload, destination
|
60
|
+
destination[GUID_KEY] = transaction.guid
|
61
|
+
destination[SAMPLED_KEY] = transaction.sampled?
|
62
|
+
destination[TRACE_ID_KEY] = transaction.trace_id
|
63
|
+
|
64
|
+
if transaction.parent_span_id
|
65
|
+
destination[PARENT_SPAN_ID_KEY] = transaction.parent_span_id
|
66
|
+
end
|
67
|
+
|
68
|
+
if distributed_trace_payload
|
69
|
+
destination[PARENT_TYPE_KEY] = distributed_trace_payload.parent_type
|
70
|
+
destination[PARENT_APP_KEY] = distributed_trace_payload.parent_app_id
|
71
|
+
destination[PARENT_ACCOUNT_ID_KEY] = distributed_trace_payload.parent_account_id
|
72
|
+
destination[PARENT_TRANSPORT_TYPE_KEY] = DistributedTraceTransportType.from distributed_trace_payload.caller_transport_type
|
73
|
+
|
74
|
+
destination[PARENT_TRANSPORT_DURATION_KEY] = transaction.calculate_transport_duration distributed_trace_payload
|
75
|
+
|
76
|
+
if transaction.parent_transaction_id
|
77
|
+
destination[PARENT_TRANSACTION_ID_KEY] = transaction.parent_transaction_id
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def enabled?
|
85
|
+
return Agent.config[:'distributed_tracing.enabled']
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,74 @@
|
|
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
|
+
|
6
|
+
module NewRelic
|
7
|
+
module Agent
|
8
|
+
module DistributedTraceMetrics
|
9
|
+
extend self
|
10
|
+
|
11
|
+
ALL_SUFFIX = "all".freeze
|
12
|
+
ALL_WEB_SUFFIX = "allWeb".freeze
|
13
|
+
ALL_OTHER_SUFFIX = "allOther".freeze
|
14
|
+
|
15
|
+
DURATION_BY_CALLER_UNKOWN_PREFIX = "DurationByCaller/Unknown/Unknown/Unknown/Unknown".freeze
|
16
|
+
ERRORS_BY_CALLER_UNKOWN_PREFIX = "ErrorsByCaller/Unknown/Unknown/Unknown/Unknown".freeze
|
17
|
+
|
18
|
+
def transaction_type_suffix
|
19
|
+
if Transaction.recording_web_transaction?
|
20
|
+
ALL_WEB_SUFFIX
|
21
|
+
else
|
22
|
+
ALL_OTHER_SUFFIX
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def record_metrics_for_transaction transaction
|
27
|
+
return unless Agent.config[:'distributed_tracing.enabled']
|
28
|
+
payload = if transaction.distributed_trace_payload
|
29
|
+
transaction.distributed_trace_payload
|
30
|
+
elsif transaction.trace_state_payload
|
31
|
+
transaction.trace_state_payload
|
32
|
+
end
|
33
|
+
|
34
|
+
record_caller_by_duration_metrics transaction, payload
|
35
|
+
record_transport_duration_metrics transaction, payload
|
36
|
+
record_errors_by_caller_metrics transaction, payload
|
37
|
+
end
|
38
|
+
|
39
|
+
def record_caller_by_duration_metrics transaction, payload
|
40
|
+
prefix = if payload
|
41
|
+
"DurationByCaller/#{payload.parent_type}/#{payload.parent_account_id}/#{payload.parent_app_id}/#{payload.caller_transport_type}"
|
42
|
+
else
|
43
|
+
DURATION_BY_CALLER_UNKOWN_PREFIX
|
44
|
+
end
|
45
|
+
|
46
|
+
transaction.metrics.record_unscoped "#{prefix}/#{ALL_SUFFIX}", transaction.duration
|
47
|
+
transaction.metrics.record_unscoped "#{prefix}/#{transaction_type_suffix}", transaction.duration
|
48
|
+
end
|
49
|
+
|
50
|
+
def record_transport_duration_metrics transaction, payload
|
51
|
+
return unless payload
|
52
|
+
|
53
|
+
prefix = "TransportDuration/#{payload.parent_type}/#{payload.parent_account_id}/#{payload.parent_app_id}/#{payload.caller_transport_type}"
|
54
|
+
duration = transaction.calculate_transport_duration payload
|
55
|
+
|
56
|
+
transaction.metrics.record_unscoped "#{prefix}/#{ALL_SUFFIX}", duration
|
57
|
+
transaction.metrics.record_unscoped "#{prefix}/#{transaction_type_suffix}", duration
|
58
|
+
end
|
59
|
+
|
60
|
+
def record_errors_by_caller_metrics transaction, payload
|
61
|
+
return unless transaction.exceptions.size > 0
|
62
|
+
|
63
|
+
prefix = if payload
|
64
|
+
"ErrorsByCaller/#{payload.parent_type}/#{payload.parent_account_id}/#{payload.parent_app_id}/#{payload.caller_transport_type}"
|
65
|
+
else
|
66
|
+
ERRORS_BY_CALLER_UNKOWN_PREFIX
|
67
|
+
end
|
68
|
+
|
69
|
+
transaction.metrics.record_unscoped "#{prefix}/#{ALL_SUFFIX}", 1
|
70
|
+
transaction.metrics.record_unscoped "#{prefix}/#{transaction_type_suffix}", 1
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|