newrelic_rpm 6.3.0.355 → 6.8.0.360

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +50 -10
  4. data/CHANGELOG.md +198 -0
  5. data/Guardfile +7 -1
  6. data/lib/new_relic/agent.rb +80 -0
  7. data/lib/new_relic/agent/agent.rb +87 -26
  8. data/lib/new_relic/agent/agent_logger.rb +4 -0
  9. data/lib/new_relic/agent/attribute_filter.rb +7 -7
  10. data/lib/new_relic/agent/attributes.rb +152 -0
  11. data/lib/new_relic/agent/autostart.rb +19 -14
  12. data/lib/new_relic/agent/commands/agent_command_router.rb +2 -21
  13. data/lib/new_relic/agent/configuration/default_source.rb +129 -39
  14. data/lib/new_relic/agent/configuration/environment_source.rb +4 -2
  15. data/lib/new_relic/agent/configuration/event_harvest_config.rb +45 -0
  16. data/lib/new_relic/agent/configuration/high_security_source.rb +1 -0
  17. data/lib/new_relic/agent/configuration/manager.rb +13 -9
  18. data/lib/new_relic/agent/configuration/server_source.rb +33 -9
  19. data/lib/new_relic/agent/configuration/yaml_source.rb +10 -5
  20. data/lib/new_relic/agent/connect/request_builder.rb +11 -13
  21. data/lib/new_relic/agent/connect/response_handler.rb +1 -1
  22. data/lib/new_relic/agent/cross_app_monitor.rb +1 -1
  23. data/lib/new_relic/agent/datastores/mongo/event_formatter.rb +2 -2
  24. data/lib/new_relic/agent/datastores/mongo/obfuscator.rb +8 -8
  25. data/lib/new_relic/agent/distributed_trace_intrinsics.rb +90 -0
  26. data/lib/new_relic/agent/distributed_trace_metrics.rb +74 -0
  27. data/lib/new_relic/agent/distributed_trace_monitor.rb +2 -12
  28. data/lib/new_relic/agent/distributed_trace_payload.rb +9 -76
  29. data/lib/new_relic/agent/distributed_trace_transport_type.rb +43 -0
  30. data/lib/new_relic/agent/error_collector.rb +2 -2
  31. data/lib/new_relic/agent/error_event_aggregator.rb +2 -1
  32. data/lib/new_relic/agent/error_trace_aggregator.rb +1 -0
  33. data/lib/new_relic/agent/event_aggregator.rb +26 -32
  34. data/lib/new_relic/agent/guid_generator.rb +28 -0
  35. data/lib/new_relic/agent/inbound_request_monitor.rb +2 -2
  36. data/lib/new_relic/agent/instrumentation/action_cable_subscriber.rb +24 -42
  37. data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +45 -69
  38. data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +70 -53
  39. data/lib/new_relic/agent/instrumentation/active_record_notifications.rb +25 -18
  40. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +33 -47
  41. data/lib/new_relic/agent/instrumentation/active_storage_subscriber.rb +4 -4
  42. data/lib/new_relic/agent/instrumentation/grape.rb +2 -3
  43. data/lib/new_relic/agent/instrumentation/{evented_subscriber.rb → notifications_subscriber.rb} +7 -66
  44. data/lib/new_relic/agent/instrumentation/rails_notifications/action_cable.rb +2 -3
  45. data/lib/new_relic/agent/javascript_instrumentor.rb +1 -1
  46. data/lib/new_relic/agent/logging.rb +129 -0
  47. data/lib/new_relic/agent/new_relic_service.rb +7 -9
  48. data/lib/new_relic/agent/priority_sampled_buffer.rb +2 -0
  49. data/lib/new_relic/agent/span_event_aggregator.rb +2 -4
  50. data/lib/new_relic/agent/span_event_primitive.rb +29 -7
  51. data/lib/new_relic/agent/sql_sampler.rb +1 -1
  52. data/lib/new_relic/agent/threading/backtrace_service.rb +3 -3
  53. data/lib/new_relic/agent/threading/thread_profile.rb +9 -23
  54. data/lib/new_relic/agent/trace_context.rb +244 -0
  55. data/lib/new_relic/agent/trace_context_payload.rb +134 -0
  56. data/lib/new_relic/agent/trace_context_request_monitor.rb +42 -0
  57. data/lib/new_relic/agent/tracer.rb +32 -0
  58. data/lib/new_relic/agent/transaction.rb +26 -20
  59. data/lib/new_relic/agent/transaction/abstract_segment.rb +2 -2
  60. data/lib/new_relic/agent/transaction/distributed_tracing.rb +20 -101
  61. data/lib/new_relic/agent/transaction/external_request_segment.rb +18 -5
  62. data/lib/new_relic/agent/transaction/segment.rb +7 -1
  63. data/lib/new_relic/agent/transaction/trace.rb +3 -8
  64. data/lib/new_relic/agent/transaction/trace_builder.rb +0 -1
  65. data/lib/new_relic/agent/transaction/trace_context.rb +159 -0
  66. data/lib/new_relic/agent/transaction/trace_node.rb +8 -3
  67. data/lib/new_relic/agent/transaction_error_primitive.rb +4 -11
  68. data/lib/new_relic/agent/transaction_event_primitive.rb +3 -11
  69. data/lib/new_relic/agent/transaction_event_recorder.rb +3 -3
  70. data/lib/new_relic/agent/transaction_sampler.rb +1 -5
  71. data/lib/new_relic/cli/commands/deployments.rb +1 -1
  72. data/lib/new_relic/coerce.rb +29 -6
  73. data/lib/new_relic/control/instance_methods.rb +10 -1
  74. data/lib/new_relic/dependency_detection.rb +4 -4
  75. data/lib/new_relic/noticed_error.rb +8 -4
  76. data/lib/new_relic/rack/browser_monitoring.rb +10 -8
  77. data/lib/new_relic/version.rb +1 -1
  78. data/lib/tasks/config.rake +1 -2
  79. data/newrelic_rpm.gemspec +13 -4
  80. data/test/agent_helper.rb +95 -9
  81. data/true +0 -0
  82. metadata +58 -24
  83. data/lib/new_relic/agent/commands/xray_session.rb +0 -55
  84. data/lib/new_relic/agent/commands/xray_session_collection.rb +0 -161
  85. data/lib/new_relic/agent/configuration/event_data.rb +0 -39
  86. data/lib/new_relic/agent/transaction/attributes.rb +0 -154
  87. data/lib/new_relic/agent/transaction/xray_sample_buffer.rb +0 -64
  88. data/lib/tasks/versions.html.erb +0 -28
  89. data/lib/tasks/versions.postface.html +0 -8
  90. data/lib/tasks/versions.preface.html +0 -9
  91. data/lib/tasks/versions.rake +0 -65
  92. data/lib/tasks/versions.txt.erb +0 -14
@@ -21,6 +21,7 @@ module NewRelic
21
21
  "cross_process_id",
22
22
  "data_report_period",
23
23
  "encoding_key",
24
+ "entity_guid",
24
25
  "error_beacon",
25
26
  "js_agent_file",
26
27
  "js_agent_loader",
@@ -38,7 +39,7 @@ module NewRelic
38
39
  merge_top_level_keys(merged_settings, connect_reply)
39
40
  merge_agent_config_hash(merged_settings, connect_reply)
40
41
  fix_transaction_threshold(merged_settings)
41
- add_event_data(merged_settings, connect_reply)
42
+ add_event_harvest_config(merged_settings, connect_reply)
42
43
  filter_keys(merged_settings)
43
44
 
44
45
  apply_feature_gates(merged_settings, connect_reply, existing_config)
@@ -74,14 +75,37 @@ module NewRelic
74
75
  end
75
76
  end
76
77
 
77
- def add_event_data(merged_settings, connect_reply)
78
- if connect_reply['event_data']
79
- merged_settings.merge! EventData.to_config_hash(connect_reply)
80
- else
81
- NewRelic::Agent.logger.warn "No event data configuration found " \
82
- "in connect response; using default event report period."
83
- NewRelic::Agent.record_metric('Supportability/Agent/Collector/MissingEventData', 1)
84
- end
78
+ EVENT_HARVEST_CONFIG_SUPPORTABILITY_METRIC_NAMES = {
79
+ :'analytics_events.max_samples_stored' => 'Supportability/EventHarvest/AnalyticEventData/HarvestLimit',
80
+ :'custom_insights_events.max_samples_stored' => 'Supportability/EventHarvest/CustomEventData/HarvestLimit',
81
+ :'error_collector.max_event_samples_stored'=> 'Supportability/EventHarvest/ErrorEventData/HarvestLimit',
82
+ :'span_events.max_samples_stored'=> 'Supportability/EventHarvest/SpanEventData/HarvestLimit',
83
+ :event_report_period => 'Supportability/EventHarvest/ReportPeriod'
84
+ }
85
+
86
+ def add_event_harvest_config(merged_settings, connect_reply)
87
+ return unless event_harvest_config_is_valid connect_reply
88
+
89
+ event_harvest_config = EventHarvestConfig.to_config_hash(connect_reply)
90
+ EVENT_HARVEST_CONFIG_SUPPORTABILITY_METRIC_NAMES.each do |config_key, metric_name|
91
+ NewRelic::Agent.record_metric metric_name, event_harvest_config[config_key]
92
+ end
93
+
94
+ merged_settings.merge! event_harvest_config
95
+ end
96
+
97
+ def event_harvest_config_is_valid connect_reply
98
+ event_harvest_config = connect_reply['event_harvest_config']
99
+
100
+ if event_harvest_config.nil? \
101
+ || event_harvest_config['harvest_limits'].values.min < 0 \
102
+ || (event_harvest_config['report_period_ms'] / 1000) <= 0
103
+ NewRelic::Agent.logger.warn "Invalid event harvest config found " \
104
+ "in connect response; using default event report period."
105
+ false
106
+ else
107
+ true
108
+ end
85
109
  end
86
110
 
87
111
  def filter_keys(merged_settings)
@@ -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 ro default
122
+ # auto means defer to default
122
123
  keys.each do |option|
123
- if config[option] == 'auto'
124
+ if 'auto' == config[option]
124
125
  config.delete(option)
125
126
  elsif !config[option].nil? && !is_boolean?(config[option])
126
- config[option] = !!(config[option] =~ /yes|on|true/i)
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 == !!value
137
+ !!value == value
133
138
  end
134
139
 
135
140
  def log_failure(*messages)
136
141
  ::NewRelic::Agent.logger.error(*messages)
137
- @failures << messages
142
+ messages.each { |message| @failures << message }
138
143
  end
139
144
  end
140
145
  end
@@ -3,7 +3,7 @@
3
3
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
4
 
5
5
  require 'new_relic/environment_report'
6
- require 'new_relic/agent/configuration/event_data'
6
+ require 'new_relic/agent/configuration/event_harvest_config'
7
7
 
8
8
  module NewRelic
9
9
  module Agent
@@ -11,9 +11,11 @@ module NewRelic
11
11
 
12
12
  class RequestBuilder
13
13
 
14
- def initialize(new_relic_service, config)
14
+ def initialize(new_relic_service, config, event_harvest_config, environment_report)
15
15
  @service = new_relic_service
16
16
  @config = config
17
+ @event_harvest_config = event_harvest_config
18
+ @environment_report = sanitize_environment_report(environment_report)
17
19
  end
18
20
 
19
21
 
@@ -24,16 +26,17 @@ module NewRelic
24
26
  :pid => $$,
25
27
  :host => local_host,
26
28
  :display_host => Agent.config[:'process_host.display_name'],
27
- :app_name => Agent.config.app_names,
29
+ :app_name => Agent.config[:app_name],
28
30
  :language => 'ruby',
29
31
  :labels => Agent.config.parsed_labels,
30
32
  :agent_version => NewRelic::VERSION::STRING,
31
- :environment => sanitize_environment_report(environment_report),
33
+ :environment => @environment_report,
34
+ :metadata => environment_metadata,
32
35
  :settings => Agent.config.to_collector_hash,
33
36
  :high_security => Agent.config[:high_security],
34
37
  :utilization => UtilizationData.new.to_collector_hash,
35
- :identifier => "ruby:#{local_host}:#{Agent.config.app_names.sort.join(',')}",
36
- :event_data => Configuration::EventData.from_config(Agent.config)
38
+ :identifier => "ruby:#{local_host}:#{Agent.config[:app_name].sort.join(',')}",
39
+ :event_harvest_config => @event_harvest_config
37
40
  }
38
41
  end
39
42
 
@@ -45,13 +48,8 @@ module NewRelic
45
48
  environment_report
46
49
  end
47
50
 
48
- # Checks whether we should send environment info, and if so,
49
- # returns the snapshot from the local environment.
50
- # Generating the EnvironmentReport has the potential to trigger
51
- # require calls in Rails environments, so this method should only
52
- # be called synchronously from on the main thread.
53
- def environment_report
54
- Agent.config[:send_environment_info] ? Array(EnvironmentReport.new) : []
51
+ def environment_metadata
52
+ ENV.select {|k, v| k =~ /^NEW_RELIC_METADATA_/}
55
53
  end
56
54
 
57
55
  def local_host
@@ -35,7 +35,7 @@ module NewRelic
35
35
  @agent.stats_engine.metric_rules = RulesEngine.create_metric_rules(config_data)
36
36
 
37
37
  # If you're adding something else here to respond to the server-side config,
38
- # use Agent.instance.events.subscribe(:finished_configuring) callback instead!
38
+ # use Agent.instance.events.subscribe(:initial_configuration_complete) callback instead!
39
39
  end
40
40
 
41
41
  def add_server_side_config(config_data)
@@ -28,7 +28,7 @@ module NewRelic
28
28
 
29
29
  def path_hash(txn_name, seed)
30
30
  rotated = ((seed << 1) | (seed >> 31)) & 0xffffffff
31
- app_name = NewRelic::Agent.config.app_names.first
31
+ app_name = NewRelic::Agent.config[:app_name].first
32
32
  identifier = "#{app_name};#{txn_name}"
33
33
  sprintf("%08x", rotated ^ hash_transaction_name(identifier))
34
34
  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
- BLACKLISTED_KEYS = [ 'deletes', 'documents', 'updates' ].freeze
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 BLACKLISTED_KEYS.include?(key)
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
- WHITELIST = [:operation].freeze
11
+ ALLOWLIST = [:operation].freeze
12
12
 
13
- def self.obfuscate_statement(source, whitelist = WHITELIST)
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 whitelist.include?(key)
17
+ if allowlist.include?(key)
18
18
  obfuscated[key] = value
19
19
  else
20
- obfuscated[key] = obfuscate_value(value, whitelist)
20
+ obfuscated[key] = obfuscate_value(value, allowlist)
21
21
  end
22
22
  end
23
23
  obfuscated
24
24
  else
25
- obfuscate_value(source, whitelist)
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, whitelist = WHITELIST)
31
+ def self.obfuscate_value(value, allowlist = ALLOWLIST)
32
32
  if value.is_a?(Hash)
33
- obfuscate_statement(value, whitelist)
33
+ obfuscate_statement(value, allowlist)
34
34
  elsif value.is_a?(Array)
35
- value.map {|v| obfuscate_value(v, whitelist)}
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
@@ -2,6 +2,7 @@
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
4
 
5
+ require 'new_relic/agent/distributed_trace_transport_type'
5
6
  require 'new_relic/agent/inbound_request_monitor'
6
7
  require 'new_relic/agent/cross_app_tracing'
7
8
 
@@ -21,20 +22,9 @@ module NewRelic
21
22
  return unless txn = Tracer.current_transaction
22
23
 
23
24
  if txn.accept_distributed_trace_payload payload
24
- txn.distributed_trace_payload.caller_transport_type = transport_type(request)
25
+ txn.distributed_trace_payload.caller_transport_type = DistributedTraceTransportType.for_rack_request(request)
25
26
  end
26
27
  end
27
-
28
- URL_SCHEMES = {
29
- 'http' => 'HTTP'.freeze,
30
- 'https' => 'HTTPS'.freeze
31
- }
32
-
33
- RACK_URL_SCHEME = 'rack.url_scheme'.freeze
34
-
35
- def transport_type(request)
36
- URL_SCHEMES[request[RACK_URL_SCHEME]]
37
- end
38
28
  end
39
29
  end
40
30
  end
@@ -5,6 +5,8 @@ require 'json'
5
5
  require 'base64'
6
6
  require 'set'
7
7
 
8
+ require 'new_relic/agent/distributed_trace_transport_type'
9
+
8
10
  module NewRelic
9
11
  module Agent
10
12
  #
@@ -32,35 +34,6 @@ module NewRelic
32
34
  TIMESTAMP_KEY = 'ti'.freeze
33
35
  PRIORITY_KEY = 'pr'.freeze
34
36
 
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
63
-
64
37
  class << self
65
38
 
66
39
  def for_transaction transaction
@@ -110,24 +83,12 @@ module NewRelic
110
83
  from_json decoded_payload
111
84
  end
112
85
 
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
86
  def major_version_matches?(payload)
120
87
  payload.version[0] == VERSION[0]
121
88
  end
122
89
 
123
90
  private
124
91
 
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
92
  def assign_trusted_account_key payload, account_id
132
93
  trusted_account_key = Agent.config[:trusted_account_key]
133
94
 
@@ -142,6 +103,10 @@ module NewRelic
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,
@@ -160,12 +125,12 @@ module NewRelic
160
125
 
161
126
  attr_reader :caller_transport_type
162
127
 
163
- def caller_transport_type=(type)
164
- @caller_transport_type = valid_transport_type_for(type)
128
+ def caller_transport_type= type
129
+ @caller_transport_type = DistributedTraceTransportType.from type
165
130
  end
166
131
 
167
132
  def initialize
168
- @caller_transport_type = PARENT_TRANSPORT_TYPE_UNKNOWN
133
+ @caller_transport_type = DistributedTraceTransportType::UNKNOWN
169
134
  end
170
135
 
171
136
  # Represent this payload as a raw JSON string.
@@ -205,38 +170,6 @@ module NewRelic
205
170
  def http_safe
206
171
  Base64.strict_encode64 text
207
172
  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
173
  end
241
174
  end
242
175
  end