newrelic_rpm 3.17.2.327 → 3.18.0.329

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +32 -10
  3. data/CHANGELOG.md +43 -3
  4. data/Rakefile +0 -21
  5. data/lib/new_relic/agent/cross_app_tracing.rb +34 -269
  6. data/lib/new_relic/agent/http_clients/curb_wrappers.rb +10 -2
  7. data/lib/new_relic/agent/http_clients/excon_wrappers.rb +18 -9
  8. data/lib/new_relic/agent/http_clients/http_rb_wrappers.rb +12 -6
  9. data/lib/new_relic/agent/http_clients/httpclient_wrappers.rb +13 -6
  10. data/lib/new_relic/agent/http_clients/net_http_wrappers.rb +13 -6
  11. data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +14 -3
  12. data/lib/new_relic/agent/instrumentation/action_cable_subscriber.rb +10 -15
  13. data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +4 -7
  14. data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +4 -19
  15. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +0 -1
  16. data/lib/new_relic/agent/instrumentation/curb.rb +9 -7
  17. data/lib/new_relic/agent/instrumentation/evented_subscriber.rb +4 -0
  18. data/lib/new_relic/agent/instrumentation/excon/connection.rb +15 -5
  19. data/lib/new_relic/agent/instrumentation/excon/middleware.rb +17 -12
  20. data/lib/new_relic/agent/instrumentation/http.rb +12 -5
  21. data/lib/new_relic/agent/instrumentation/httpclient.rb +13 -4
  22. data/lib/new_relic/agent/instrumentation/net.rb +13 -2
  23. data/lib/new_relic/agent/instrumentation/rails5/action_controller.rb +2 -10
  24. data/lib/new_relic/agent/instrumentation/typhoeus.rb +8 -3
  25. data/lib/new_relic/agent/method_tracer_helpers.rb +3 -1
  26. data/lib/new_relic/agent/parameter_filtering.rb +1 -1
  27. data/lib/new_relic/agent/stats_engine/metric_stats.rb +0 -18
  28. data/lib/new_relic/agent/supported_versions.rb +1 -0
  29. data/lib/new_relic/agent/transaction/abstract_segment.rb +7 -9
  30. data/lib/new_relic/agent/transaction/external_request_segment.rb +139 -0
  31. data/lib/new_relic/agent/transaction/segment.rb +1 -1
  32. data/lib/new_relic/agent/transaction/tracing.rb +10 -1
  33. data/lib/new_relic/recipes/capistrano3.rb +3 -1
  34. data/lib/new_relic/version.rb +2 -2
  35. data/lib/tasks/multiverse.rb +27 -7
  36. data/test/environments/rails42/Gemfile +1 -0
  37. data/test/multiverse/lib/multiverse.rb +32 -0
  38. data/test/multiverse/lib/multiverse/runner.rb +2 -2
  39. data/test/multiverse/lib/multiverse/suite.rb +43 -22
  40. data/test/multiverse/suites/active_record/Envfile +3 -1
  41. data/test/multiverse/suites/activemerchant/Envfile +5 -1
  42. data/test/multiverse/suites/agent_only/Envfile +1 -0
  43. data/test/multiverse/suites/capistrano/deployment_test.rb +6 -9
  44. data/test/multiverse/suites/capistrano2/deployment_test.rb +6 -6
  45. data/test/multiverse/suites/curb/curb_test.rb +2 -3
  46. data/test/multiverse/suites/datamapper/Envfile +4 -0
  47. data/test/multiverse/suites/datamapper/datamapper_test.rb +106 -36
  48. data/test/multiverse/suites/delayed_job/Envfile +3 -3
  49. data/test/multiverse/suites/excon/excon_test.rb +1 -1
  50. data/test/multiverse/suites/grape/grape_test.rb +1 -1
  51. data/test/multiverse/suites/grape/grape_test_api.rb +1 -1
  52. data/test/multiverse/suites/grape/grape_versioning_test.rb +1 -1
  53. data/test/multiverse/suites/grape/grape_versioning_test_api.rb +1 -1
  54. data/test/multiverse/suites/grape/unsupported_version_test.rb +1 -1
  55. data/test/multiverse/suites/httpclient/Envfile +2 -0
  56. data/test/multiverse/suites/httpclient/httpclient_test.rb +1 -1
  57. data/test/multiverse/suites/httprb/Envfile +2 -0
  58. data/test/multiverse/suites/httprb/httprb_test.rb +1 -1
  59. data/test/multiverse/suites/json/Envfile +7 -2
  60. data/test/multiverse/suites/memcached/Envfile +2 -0
  61. data/test/multiverse/suites/mongo/Envfile +2 -0
  62. data/test/multiverse/suites/mongo/helpers/mongo_operation_tests.rb +95 -33
  63. data/test/multiverse/suites/mongo/mongo2_instrumentation_test.rb +62 -23
  64. data/test/multiverse/suites/net_http/Envfile +2 -0
  65. data/test/multiverse/suites/net_http/net_http_test.rb +7 -3
  66. data/test/multiverse/suites/padrino/Envfile +2 -0
  67. data/test/multiverse/suites/rack/Envfile +2 -0
  68. data/test/multiverse/suites/rack/url_map_test.rb +4 -0
  69. data/test/multiverse/suites/rails/Envfile +34 -29
  70. data/test/multiverse/suites/rake/Envfile +11 -6
  71. data/test/multiverse/suites/redis/Envfile +2 -0
  72. data/test/multiverse/suites/redis/redis_instrumentation_test.rb +31 -12
  73. data/test/multiverse/suites/sidekiq/Envfile +6 -2
  74. data/test/multiverse/suites/sinatra/Envfile +2 -0
  75. data/test/multiverse/suites/typhoeus/Envfile +31 -27
  76. data/test/multiverse/suites/typhoeus/typhoeus_test.rb +4 -3
  77. data/test/multiverse/suites/yajl/Envfile +4 -2
  78. data/test/new_relic/agent/datastores_test.rb +0 -10
  79. data/test/new_relic/agent/instrumentation/action_cable_subscriber_test.rb +2 -2
  80. data/test/new_relic/agent/instrumentation/action_view_subscriber_test.rb +64 -65
  81. data/test/new_relic/agent/instrumentation/active_record_subscriber_test.rb +11 -9
  82. data/test/new_relic/agent/instrumentation/instance_identification_test.rb +9 -8
  83. data/test/new_relic/agent/instrumentation/mongodb_command_subscriber_test.rb +7 -11
  84. data/test/new_relic/agent/instrumentation/net_instrumentation_test.rb +4 -0
  85. data/test/new_relic/agent/method_tracer/instance_methods/trace_execution_scoped_test.rb +0 -9
  86. data/test/new_relic/agent/method_tracer_test.rb +24 -8
  87. data/test/new_relic/agent/parameter_filtering_test.rb +2 -2
  88. data/test/new_relic/agent/stats_engine/metric_stats_test.rb +1 -0
  89. data/test/new_relic/agent/transaction/abstract_segment_test.rb +25 -16
  90. data/test/new_relic/agent/transaction/datastore_segment_test.rb +55 -38
  91. data/test/new_relic/agent/transaction/external_request_segment_test.rb +330 -0
  92. data/test/new_relic/agent/transaction/segment_test.rb +28 -4
  93. data/test/new_relic/agent/transaction/tracing_test.rb +60 -22
  94. data/test/new_relic/agent_test.rb +2 -1
  95. data/test/new_relic/collection_helper_test.rb +1 -0
  96. data/test/new_relic/dispatcher_test.rb +1 -0
  97. data/test/new_relic/fake_external_server.rb +1 -1
  98. data/test/new_relic/filtering_test_app.rb +1 -1
  99. data/test/new_relic/http_client_test_cases.rb +38 -20
  100. data/test/new_relic/rack/error_collector_test.rb +1 -0
  101. data/test/performance/suites/external_segment.rb +82 -0
  102. data/test/script/before_install/update_bundler.sh +12 -0
  103. data/test/script/external_server.rb +31 -0
  104. metadata +8 -5
  105. data/test/multiverse/lib/multiverse/environment.rb +0 -19
  106. data/test/new_relic/agent/cross_app_tracing_test.rb +0 -71
  107. data/test/script/before_install/jruby_bundler.sh +0 -22
@@ -19,10 +19,12 @@ module ::Excon
19
19
  # accompanying response_call/error_call.
20
20
  if datum[:connection] && !datum[:connection].instance_variable_get(TRACE_DATA_IVAR)
21
21
  wrapped_request = ::NewRelic::Agent::HTTPClients::ExconHTTPRequest.new(datum)
22
- state = ::NewRelic::Agent::TransactionState.tl_get
23
- t0 = Time.now
24
- node = ::NewRelic::Agent::CrossAppTracing.start_trace(state, t0, wrapped_request)
25
- datum[:connection].instance_variable_set(TRACE_DATA_IVAR, [t0, node, wrapped_request])
22
+ segment = NewRelic::Agent::Transaction.start_external_request_segment(
23
+ wrapped_request.type, wrapped_request.uri, wrapped_request.method)
24
+
25
+ segment.add_request_headers wrapped_request
26
+
27
+ datum[:connection].instance_variable_set(TRACE_DATA_IVAR, segment)
26
28
  end
27
29
  rescue => e
28
30
  NewRelic::Agent.logger.debug(e)
@@ -41,15 +43,18 @@ module ::Excon
41
43
  end
42
44
 
43
45
  def finish_trace(datum) #THREAD_LOCAL_ACCESS
44
- trace_data = datum[:connection] && datum[:connection].instance_variable_get(TRACE_DATA_IVAR)
45
- if trace_data
46
- datum[:connection].instance_variable_set(TRACE_DATA_IVAR, nil)
47
- t0, node, wrapped_request = trace_data
48
- if datum[:response]
49
- wrapped_response = ::NewRelic::Agent::HTTPClients::ExconHTTPResponse.new(datum[:response])
46
+ segment = datum[:connection] && datum[:connection].instance_variable_get(TRACE_DATA_IVAR)
47
+ if segment
48
+ begin
49
+ datum[:connection].instance_variable_set(TRACE_DATA_IVAR, nil)
50
+
51
+ if datum[:response]
52
+ wrapped_response = ::NewRelic::Agent::HTTPClients::ExconHTTPResponse.new(datum[:response])
53
+ segment.read_response_headers wrapped_response
54
+ end
55
+ ensure
56
+ segment.finish
50
57
  end
51
- state = ::NewRelic::Agent::TransactionState.tl_get
52
- ::NewRelic::Agent::CrossAppTracing.finish_trace(state, t0, node, wrapped_request, wrapped_response)
53
58
  end
54
59
  end
55
60
  end
@@ -20,13 +20,20 @@ DependencyDetection.defer do
20
20
  def perform_with_newrelic_trace(request, options)
21
21
  wrapped_request = ::NewRelic::Agent::HTTPClients::HTTPRequest.new(request)
22
22
 
23
- response = nil
24
- ::NewRelic::Agent::CrossAppTracing.tl_trace_http_request(wrapped_request) do
23
+ begin
24
+ segment = NewRelic::Agent::Transaction.start_external_request_segment(
25
+ wrapped_request.type, wrapped_request.uri, wrapped_request.method)
26
+
27
+ segment.add_request_headers wrapped_request
28
+
25
29
  response = perform_without_newrelic_trace(request, options)
26
- ::NewRelic::Agent::HTTPClients::HTTPResponse.new(response)
27
- end
30
+ wrapped_response = ::NewRelic::Agent::HTTPClients::HTTPResponse.new response
31
+ segment.read_response_headers wrapped_response
28
32
 
29
- response
33
+ response
34
+ ensure
35
+ segment.finish if segment
36
+ end
30
37
  end
31
38
 
32
39
  alias perform_without_newrelic_trace perform
@@ -28,15 +28,24 @@ DependencyDetection.defer do
28
28
  class HTTPClient
29
29
  def do_get_block_with_newrelic(req, proxy, conn, &block)
30
30
  wrapped_request = NewRelic::Agent::HTTPClients::HTTPClientRequest.new(req)
31
+ segment = NewRelic::Agent::Transaction.start_external_request_segment(
32
+ wrapped_request.type, wrapped_request.uri, wrapped_request.method)
33
+
34
+ begin
35
+ response = nil
36
+ segment.add_request_headers wrapped_request
31
37
 
32
- response = nil
33
- ::NewRelic::Agent::CrossAppTracing.tl_trace_http_request(wrapped_request) do
34
38
  do_get_block_without_newrelic(req, proxy, conn, &block)
35
39
  response = conn.pop
36
40
  conn.push response
37
- ::NewRelic::Agent::HTTPClients::HTTPClientResponse.new(response)
41
+
42
+ wrapped_response = ::NewRelic::Agent::HTTPClients::HTTPClientResponse.new(response)
43
+ segment.read_response_headers wrapped_response
44
+
45
+ response
46
+ ensure
47
+ segment.finish
38
48
  end
39
- response
40
49
  end
41
50
 
42
51
  alias do_get_block_without_newrelic do_get_block
@@ -20,12 +20,23 @@ DependencyDetection.defer do
20
20
  def request_with_newrelic_trace(request, *args, &block)
21
21
  wrapped_request = NewRelic::Agent::HTTPClients::NetHTTPRequest.new(self, request)
22
22
 
23
- NewRelic::Agent::CrossAppTracing.tl_trace_http_request( wrapped_request ) do
23
+ segment = NewRelic::Agent::Transaction.start_external_request_segment(
24
+ wrapped_request.type, wrapped_request.uri, wrapped_request.method)
25
+
26
+ begin
27
+ response = nil
28
+ segment.add_request_headers wrapped_request
29
+
24
30
  # RUBY-1244 Disable further tracing in request to avoid double
25
31
  # counting if connection wasn't started (which calls request again).
26
32
  NewRelic::Agent.disable_all_tracing do
27
- request_without_newrelic_trace( request, *args, &block )
33
+ response = request_without_newrelic_trace( request, *args, &block )
28
34
  end
35
+
36
+ segment.read_response_headers response
37
+ response
38
+ ensure
39
+ segment.finish
29
40
  end
30
41
  end
31
42
 
@@ -20,16 +20,8 @@ DependencyDetection.defer do
20
20
  end
21
21
 
22
22
  executes do
23
- if defined?(ActionController::Base)
24
- class ActionController::Base
25
- include NewRelic::Agent::Instrumentation::ControllerInstrumentation
26
- end
27
- end
28
-
29
- if defined?(ActionController::API)
30
- class ActionController::API
31
- include NewRelic::Agent::Instrumentation::ControllerInstrumentation
32
- end
23
+ ActiveSupport.on_load(:action_controller) do |c|
24
+ c.include NewRelic::Agent::Instrumentation::ControllerInstrumentation
33
25
  end
34
26
 
35
27
  NewRelic::Agent::Instrumentation::ActionControllerSubscriber \
@@ -64,11 +64,16 @@ module NewRelic::Agent::Instrumentation::TyphoeusTracing
64
64
  state = NewRelic::Agent::TransactionState.tl_get
65
65
  if state.is_execution_traced? && !request_is_hydra_enabled?(request)
66
66
  wrapped_request = ::NewRelic::Agent::HTTPClients::TyphoeusHTTPRequest.new(request)
67
- t0 = Time.now
68
- node = ::NewRelic::Agent::CrossAppTracing.start_trace(state, t0, wrapped_request)
67
+
68
+ segment = NewRelic::Agent::Transaction.start_external_request_segment(
69
+ wrapped_request.type, wrapped_request.uri, wrapped_request.method)
70
+
71
+ segment.add_request_headers wrapped_request
72
+
69
73
  callback = Proc.new do
70
74
  wrapped_response = ::NewRelic::Agent::HTTPClients::TyphoeusHTTPResponse.new(request.response)
71
- ::NewRelic::Agent::CrossAppTracing.finish_trace(state, t0, node, wrapped_request, wrapped_response)
75
+ segment.read_response_headers wrapped_response
76
+ segment.finish
72
77
  end
73
78
  request.on_complete.unshift(callback)
74
79
  end
@@ -75,7 +75,9 @@ module NewRelic
75
75
  return yield unless first_name
76
76
 
77
77
  segment = NewRelic::Agent::Transaction.start_segment first_name, metric_names
78
- segment.record_metrics = options.fetch(:metric, true)
78
+ if options[:metric] == false
79
+ segment.record_metrics = false
80
+ end
79
81
 
80
82
  begin
81
83
  yield
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # This file is distributed under New Relic"s license terms.
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
5
  module NewRelic
@@ -66,15 +66,6 @@ module NewRelic
66
66
  end
67
67
  end
68
68
 
69
- # This aliasing was introduced for T2 so that MetricsStats and
70
- # TransactionStates have the same interface for recording
71
- # unscoped metrics. The tl_ version should be used outside of the
72
- # segment api.
73
- #
74
- # @api private
75
- #
76
- alias_method :record_unscoped, :tl_record_unscoped_metrics
77
-
78
69
  # Like tl_record_unscoped_metrics, but records a scoped metric as well.
79
70
  #
80
71
  # This is an internal method, subject to change at any time. Client apps
@@ -117,15 +108,6 @@ module NewRelic
117
108
  end
118
109
  end
119
110
 
120
- # This aliasing was introduced for T2 so that MetricsStats and
121
- # TransactionStates have the same interface for recording
122
- # scoped metrics. The tl_ version should be used outside of the
123
- # segment api.
124
- #
125
- # @api private
126
- #
127
- alias_method :record_scoped_and_unscoped, :tl_record_scoped_and_unscoped_metrics
128
-
129
111
  # This method is deprecated and not thread safe, and should not be used
130
112
  # by any new client code.
131
113
  #
@@ -12,6 +12,7 @@ module NewRelic
12
12
  :type => :ruby,
13
13
  :name => "MRI",
14
14
  :supported => ["1.8.7", "1.9.2", "1.9.3", "2.0.0", "~> 2.1.0", "~> 2.2.0", "~> 2.3.0"],
15
+ :experimental=> ["2.4.0-preview3"],
15
16
  :url => "https://www.ruby-lang.org",
16
17
  :feed => "https://www.ruby-lang.org/en/feeds/news.rss",
17
18
  :notes => [
@@ -9,7 +9,7 @@ module NewRelic
9
9
  attr_reader :start_time, :end_time, :duration, :exclusive_duration
10
10
  attr_accessor :name, :children_time, :transaction
11
11
 
12
- def initialize name
12
+ def initialize name=nil
13
13
  @name = name
14
14
  @children_time = 0.0
15
15
  @record_metrics = true
@@ -24,9 +24,11 @@ module NewRelic
24
24
  @end_time = Time.now
25
25
  @duration = end_time.to_f - start_time.to_f
26
26
  @exclusive_duration = duration - children_time
27
- record_metrics if record_metrics?
28
- segment_complete
29
- @transaction.segment_complete self if transaction
27
+ if transaction
28
+ record_metrics if record_metrics?
29
+ segment_complete
30
+ transaction.segment_complete self
31
+ end
30
32
  rescue => e
31
33
  # This rescue block was added for the benefit of this test:
32
34
  # test/multiverse/suites/bare/standalone_instrumentation_test.rb
@@ -62,11 +64,7 @@ module NewRelic
62
64
  end
63
65
 
64
66
  def metric_cache
65
- if transaction
66
- transaction.metrics
67
- else
68
- NewRelic::Agent.instance.stats_engine
69
- end
67
+ transaction.metrics
70
68
  end
71
69
 
72
70
  def transaction_state
@@ -0,0 +1,139 @@
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/transaction/segment'
6
+ require 'new_relic/agent/http_clients/uri_util'
7
+
8
+ module NewRelic
9
+ module Agent
10
+ class Transaction
11
+ class ExternalRequestSegment < Segment
12
+ attr_reader :library, :uri, :procedure
13
+
14
+ def initialize library, uri, procedure
15
+ @library = library
16
+ @uri = normalize_uri uri
17
+ @procedure = procedure
18
+ @host_header = nil
19
+ @app_data = nil
20
+ super()
21
+ end
22
+
23
+ def name
24
+ @name ||= "External/#{host}/#{library}/#{procedure}"
25
+ end
26
+
27
+ def host
28
+ @host_header || uri.host
29
+ end
30
+
31
+ # This method will add NewRelic headers for cross application tracing and
32
+ # will check to see if a host header is used for the request. If a host
33
+ # header is used it will update the segment name to reflect the host header.
34
+ def add_request_headers request
35
+ process_host_header request
36
+ return unless record_metrics? && CrossAppTracing.cross_app_enabled?
37
+
38
+ transaction_state.is_cross_app_caller = true
39
+ txn_guid = transaction_state.request_guid
40
+ trip_id = transaction && transaction.cat_trip_id(transaction_state)
41
+ path_hash = transaction && transaction.cat_path_hash(transaction_state)
42
+ synthetics_header = transaction && transaction.raw_synthetics_header
43
+
44
+ CrossAppTracing.insert_request_headers request, txn_guid, trip_id, path_hash, synthetics_header
45
+ rescue => e
46
+ NewRelic::Agent.logger.error "Error in add_request_headers", e
47
+ end
48
+
49
+ def read_response_headers response
50
+ return unless record_metrics? && CrossAppTracing.cross_app_enabled?
51
+ return unless CrossAppTracing.response_has_crossapp_header?(response)
52
+ unless data = CrossAppTracing.extract_appdata(response)
53
+ NewRelic::Agent.logger.debug "Couldn't extract_appdata from external segment response"
54
+ return
55
+ end
56
+
57
+ if CrossAppTracing.valid_cross_app_id?(data[0])
58
+ @app_data = data
59
+ update_segment_name
60
+ else
61
+ NewRelic::Agent.logger.debug "External segment response has invalid cross_app_id"
62
+ end
63
+ rescue => e
64
+ NewRelic::Agent.logger.error "Error in read_response_headers", e
65
+ end
66
+
67
+ def cross_app_request?
68
+ !!@app_data
69
+ end
70
+
71
+ def cross_process_id
72
+ @app_data && @app_data[0]
73
+ end
74
+
75
+ def transaction_guid
76
+ @app_data && @app_data[5]
77
+ end
78
+
79
+ def cross_process_transaction_name
80
+ @app_data && @app_data[1]
81
+ end
82
+
83
+ private
84
+
85
+ def segment_complete
86
+ node_params = {:uri => HTTPClients::URIUtil.filter_uri(uri)}
87
+ if cross_app_request?
88
+ node_params[:transaction_guid] = transaction_guid
89
+ end
90
+ Agent.instance.transaction_sampler.add_node_parameters node_params
91
+ end
92
+
93
+ def normalize_uri uri
94
+ uri.is_a?(URI) ? uri : HTTPClients::URIUtil.parse_url(uri)
95
+ end
96
+
97
+ def process_host_header request
98
+ if @host_header = request.host_from_header
99
+ update_segment_name
100
+ end
101
+ end
102
+
103
+ EXTERNAL_ALL = "External/all".freeze
104
+
105
+ def unscoped_metrics
106
+ metrics = [ EXTERNAL_ALL,
107
+ "External/#{host}/all",
108
+ suffixed_rollup_metric
109
+ ]
110
+
111
+ if cross_app_request?
112
+ metrics << "ExternalApp/#{host}/#{cross_process_id}/all"
113
+ end
114
+
115
+ metrics
116
+ end
117
+
118
+ EXTERNAL_ALL_WEB = "External/allWeb".freeze
119
+ EXTERNAL_ALL_OTHER = "External/allOther".freeze
120
+
121
+ def suffixed_rollup_metric
122
+ if Transaction.recording_web_transaction?
123
+ EXTERNAL_ALL_WEB
124
+ else
125
+ EXTERNAL_ALL_OTHER
126
+ end
127
+ end
128
+
129
+ def update_segment_name
130
+ if @app_data
131
+ @name = "ExternalTransaction/#{host}/#{cross_process_id}/#{cross_process_transaction_name}"
132
+ else
133
+ @name = "External/#{host}/#{library}/#{procedure}"
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
@@ -13,7 +13,7 @@ module NewRelic
13
13
  # initialize it as an array that would be empty, have one item, or many items.
14
14
  attr_reader :unscoped_metrics
15
15
 
16
- def initialize name, unscoped_metrics=nil
16
+ def initialize name = nil, unscoped_metrics=nil
17
17
  @unscoped_metrics = unscoped_metrics
18
18
  super name
19
19
  end
@@ -4,6 +4,7 @@
4
4
 
5
5
  require 'new_relic/agent/transaction/segment'
6
6
  require 'new_relic/agent/transaction/datastore_segment'
7
+ require 'new_relic/agent/transaction/external_request_segment'
7
8
 
8
9
  module NewRelic
9
10
  module Agent
@@ -29,13 +30,21 @@ module NewRelic
29
30
  segment
30
31
  end
31
32
 
33
+ def start_external_request_segment library, uri, procedure
34
+ segment = ExternalRequestSegment.new library, uri, procedure
35
+ segment.start
36
+ add_segment segment
37
+ segment
38
+ end
39
+
32
40
  private
33
41
 
34
42
  def add_segment segment
35
43
  state = NewRelic::Agent::TransactionState.tl_get
36
- segment.record_metrics = state.is_execution_traced?
37
44
  if (txn = state.current_transaction) && state.is_execution_traced?
38
45
  txn.add_segment segment
46
+ else
47
+ segment.record_metrics = false
39
48
  end
40
49
  end
41
50
  end