newrelic_rpm 4.5.0.337 → 4.6.0.338

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +2 -0
  3. data/CHANGELOG.md +8 -0
  4. data/lib/new_relic/agent.rb +1 -0
  5. data/lib/new_relic/agent/agent.rb +19 -12
  6. data/lib/new_relic/agent/configuration/default_source.rb +7 -0
  7. data/lib/new_relic/agent/distributed_trace_monitor.rb +29 -0
  8. data/lib/new_relic/agent/distributed_trace_payload.rb +223 -0
  9. data/lib/new_relic/agent/distributed_trace_priority_sampled_buffer.rb +72 -0
  10. data/lib/new_relic/agent/external.rb +137 -0
  11. data/lib/new_relic/agent/http_clients/abstract_request.rb +31 -0
  12. data/lib/new_relic/agent/http_clients/curb_wrappers.rb +3 -1
  13. data/lib/new_relic/agent/http_clients/excon_wrappers.rb +3 -1
  14. data/lib/new_relic/agent/http_clients/http_rb_wrappers.rb +3 -1
  15. data/lib/new_relic/agent/http_clients/httpclient_wrappers.rb +3 -1
  16. data/lib/new_relic/agent/http_clients/net_http_wrappers.rb +3 -1
  17. data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +3 -1
  18. data/lib/new_relic/agent/sql_sampler.rb +2 -2
  19. data/lib/new_relic/agent/throughput_monitor.rb +59 -0
  20. data/lib/new_relic/agent/transaction.rb +59 -15
  21. data/lib/new_relic/agent/transaction/abstract_segment.rb +17 -5
  22. data/lib/new_relic/agent/transaction/distributed_tracing.rb +121 -0
  23. data/lib/new_relic/agent/transaction/external_request_segment.rb +183 -19
  24. data/lib/new_relic/agent/transaction/segment.rb +2 -3
  25. data/lib/new_relic/agent/transaction/trace.rb +14 -5
  26. data/lib/new_relic/agent/transaction/trace_builder.rb +58 -0
  27. data/lib/new_relic/agent/transaction/trace_node.rb +34 -32
  28. data/lib/new_relic/agent/transaction/tracing.rb +4 -9
  29. data/lib/new_relic/agent/transaction_error_primitive.rb +18 -0
  30. data/lib/new_relic/agent/transaction_event_aggregator.rb +14 -0
  31. data/lib/new_relic/agent/transaction_event_primitive.rb +14 -0
  32. data/lib/new_relic/agent/transaction_event_recorder.rb +9 -1
  33. data/lib/new_relic/agent/transaction_sampler.rb +12 -66
  34. data/lib/new_relic/agent/transaction_state.rb +1 -3
  35. data/lib/new_relic/supportability_helper.rb +5 -0
  36. data/lib/new_relic/version.rb +1 -1
  37. data/newrelic.yml +1 -1
  38. data/newrelic_rpm.gemspec +1 -1
  39. data/test/agent_helper.rb +11 -3
  40. metadata +10 -4
  41. data/lib/new_relic/agent/transaction_sample_builder.rb +0 -138
@@ -22,7 +22,9 @@ module NewRelic
22
22
  def record payload
23
23
  return unless NewRelic::Agent.config[:'analytics_events.enabled']
24
24
 
25
- if synthetics_event? payload
25
+ if sampled_event? payload
26
+ transaction_event_aggregator.append_sampled { create_event(payload) }
27
+ elsif synthetics_event? payload
26
28
  event = create_event payload
27
29
  _, rejected = synthetics_event_aggregator.append_or_reject event
28
30
  transaction_event_aggregator.append event if rejected
@@ -39,6 +41,12 @@ module NewRelic
39
41
  payload.key? :synthetics_resource_id
40
42
  end
41
43
 
44
+ SAMPLED_KEY = 'nr.sampled'
45
+
46
+ def sampled_event? payload
47
+ !!payload[SAMPLED_KEY]
48
+ end
49
+
42
50
  def drop_buffered_data
43
51
  transaction_event_aggregator.reset!
44
52
  synthetics_event_aggregator.reset!
@@ -2,10 +2,10 @@
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/transaction_sample_builder'
6
5
  require 'new_relic/agent/transaction/slowest_sample_buffer'
7
6
  require 'new_relic/agent/transaction/synthetics_sample_buffer'
8
7
  require 'new_relic/agent/transaction/xray_sample_buffer'
8
+ require 'new_relic/agent/transaction/trace_builder'
9
9
 
10
10
  module NewRelic
11
11
  module Agent
@@ -54,29 +54,6 @@ module NewRelic
54
54
  Agent.config[:'transaction_tracer.enabled']
55
55
  end
56
56
 
57
- def on_start_transaction(state, start_time)
58
- if enabled?
59
- start_builder(state, start_time.to_f)
60
- end
61
- end
62
-
63
- # This delegates to the builder to create a new open transaction node
64
- # for the frame, beginning at the optionally specified time.
65
- def notice_push_frame(state, time=Time.now)
66
- builder = state.transaction_sample_builder
67
- return unless builder
68
-
69
- builder.trace_entry(time.to_f)
70
- end
71
-
72
- # Informs the transaction sample builder about the end of a traced frame
73
- def notice_pop_frame(state, frame, time = Time.now)
74
- builder = state.transaction_sample_builder
75
- return unless builder
76
- raise "finished already???" if builder.sample.finished
77
- builder.trace_exit(frame, time.to_f)
78
- end
79
-
80
57
  # This is called when we are done with the transaction. We've
81
58
  # unwound the stack to the top level. It also clears the
82
59
  # transaction sample builder so that it won't continue to have
@@ -85,23 +62,11 @@ module NewRelic
85
62
  # It sets various instance variables to the finished sample,
86
63
  # depending on which settings are active. See `store_sample`
87
64
  def on_finishing_transaction(state, txn, time=Time.now)
88
- last_builder = state.transaction_sample_builder
89
- return unless last_builder && enabled?
90
-
91
- state.transaction_sample_builder = nil
92
- return if txn.ignore_trace?
93
-
94
- last_builder.finish_trace(time.to_f)
95
-
96
- last_sample = last_builder.sample
97
- last_sample.transaction_name = txn.best_name
98
- last_sample.uri = txn.request_path
99
- last_sample.guid = txn.guid
100
- last_sample.attributes = txn.attributes
65
+ return if !enabled? || txn.ignore_trace?
101
66
 
102
67
  @samples_lock.synchronize do
103
- @last_sample = last_sample
104
- store_sample(@last_sample)
68
+ @last_sample = txn
69
+ store_sample(txn)
105
70
  @last_sample
106
71
  end
107
72
  end
@@ -112,13 +77,6 @@ module NewRelic
112
77
  end
113
78
  end
114
79
 
115
- # Set parameters on the current node.
116
- def add_node_parameters(params) #THREAD_LOCAL_ACCESS
117
- builder = tl_builder
118
- return unless builder
119
- params.each { |k,v| builder.current_node[k] = v }
120
- end
121
-
122
80
  # Gather transaction traces that we'd like to transmit to the server.
123
81
  def harvest!
124
82
  return [] unless enabled?
@@ -164,7 +122,14 @@ module NewRelic
164
122
  # know, Ruby 1.8.6 :/
165
123
  result = []
166
124
  @sample_buffers.each { |buffer| result.concat(buffer.harvest_samples) }
167
- result.uniq
125
+ result.uniq!
126
+ result.map! do |sample|
127
+ if Transaction === sample
128
+ Transaction::TraceBuilder.build_trace sample
129
+ else
130
+ sample
131
+ end
132
+ end
168
133
  end
169
134
 
170
135
  # reset samples without rebooting the web server (used by dev mode)
@@ -174,25 +139,6 @@ module NewRelic
174
139
  @sample_buffers.each { |sample_buffer| sample_buffer.reset! }
175
140
  end
176
141
  end
177
-
178
- # Checks to see if the transaction sampler is disabled, if
179
- # transaction trace recording is disabled by a thread local, or
180
- # if execution is untraced - if so it clears the transaction
181
- # sample builder from the thread local, otherwise it generates a
182
- # new transaction sample builder with the stated time as a
183
- # starting point and saves it in the thread local variable
184
- def start_builder(state, time=nil)
185
- if !enabled? || !state.is_transaction_traced? || !state.is_execution_traced?
186
- state.transaction_sample_builder = nil
187
- else
188
- state.transaction_sample_builder ||= TransactionSampleBuilder.new(time)
189
- end
190
- end
191
-
192
- # The current thread-local transaction sample builder
193
- def tl_builder
194
- TransactionState.tl_get.transaction_sample_builder
195
- end
196
142
  end
197
143
  end
198
144
  end
@@ -53,7 +53,6 @@ module NewRelic
53
53
  @client_cross_app_id = nil
54
54
  @referring_transaction_info = nil
55
55
 
56
- @transaction_sample_builder = nil
57
56
  @sql_sampler_transaction_data = nil
58
57
 
59
58
  @busy_entries = 0
@@ -87,9 +86,8 @@ module NewRelic
87
86
  current_transaction.guid
88
87
  end
89
88
 
90
- # Current transaction stack and sample building
89
+ # Current transaction stack
91
90
  attr_reader :current_transaction
92
- attr_accessor :transaction_sample_builder
93
91
 
94
92
  def transaction_start_time
95
93
  current_transaction.start_time if current_transaction
@@ -21,6 +21,8 @@ module NewRelic
21
21
  :disable_sql_recording,
22
22
  :disable_transaction_tracing,
23
23
  :drop_buffered_data,
24
+ :get_request_metadata,
25
+ :get_response_metadata,
24
26
  :get_transaction_name,
25
27
  :ignore_apdex,
26
28
  :ignore_enduser,
@@ -35,6 +37,8 @@ module NewRelic
35
37
  :notice_sql,
36
38
  :notice_statement,
37
39
  :perform_action_with_newrelic_trace,
40
+ :process_request_metadata,
41
+ :process_response_metadata,
38
42
  :record_custom_event,
39
43
  :record_metric,
40
44
  :recording_web_transaction?,
@@ -42,6 +46,7 @@ module NewRelic
42
46
  :set_sql_obfuscator,
43
47
  :set_transaction_name,
44
48
  :shutdown,
49
+ :start_segment,
45
50
  :trace,
46
51
  :trace_execution_scoped,
47
52
  :trace_execution_unscoped,
@@ -11,7 +11,7 @@ module NewRelic
11
11
  end
12
12
 
13
13
  MAJOR = 4
14
- MINOR = 5
14
+ MINOR = 6
15
15
  TINY = 0
16
16
 
17
17
  begin
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # This file configures the New Relic Agent. New Relic monitors Ruby, Java,
3
- # .NET, PHP, Python and Node applications with deep visibility and low
3
+ # .NET, PHP, Python, Node, and Go applications with deep visibility and low
4
4
  # overhead. For more information, visit www.newrelic.com.
5
5
  #
6
6
  # Generated <%= Time.now.strftime('%B %d, %Y') %><%= ", for version #{@agent_version}" if @agent_version %>
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
10
10
  s.version = NewRelic::VERSION::STRING
11
11
  s.required_ruby_version = '>= 2.0.0'
12
12
  s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
13
- s.authors = [ "Matthew Wear", "Kenichi Nakamura", "Chris Pine", "Dana Scheider" ]
13
+ s.authors = [ "Matthew Wear", "Chris Pine", "Dana Scheider" ]
14
14
  s.date = Time.now.strftime('%Y-%m-%d')
15
15
  s.licenses = ['New Relic']
16
16
  s.description = <<-EOS
@@ -55,6 +55,14 @@ def last_transaction_event
55
55
  harvest_transaction_events!.last.last
56
56
  end
57
57
 
58
+ def harvest_error_events!
59
+ NewRelic::Agent.instance.error_collector.error_event_aggregator.harvest!
60
+ end
61
+
62
+ def last_error_event
63
+ harvest_error_events!.last.last
64
+ end
65
+
58
66
  unless defined?( assert_block )
59
67
  def assert_block(*msgs)
60
68
  assert yield, *msgs
@@ -362,7 +370,8 @@ def refute_contains_request_params(attributes)
362
370
  end
363
371
 
364
372
  def last_transaction_trace
365
- NewRelic::Agent.agent.transaction_sampler.last_sample
373
+ return unless last_sample = NewRelic::Agent.agent.transaction_sampler.last_sample
374
+ NewRelic::Agent::Transaction::TraceBuilder.build_trace(last_sample)
366
375
  end
367
376
 
368
377
  def last_transaction_trace_request_params
@@ -387,8 +396,7 @@ def find_last_transaction_node(transaction_sample=nil)
387
396
  if transaction_sample
388
397
  root_node = transaction_sample.root_node
389
398
  else
390
- builder = NewRelic::Agent.agent.transaction_sampler.tl_builder
391
- root_node = builder.current_node
399
+ root_node = last_transaction_trace.root_node
392
400
  end
393
401
 
394
402
  last_node = nil
metadata CHANGED
@@ -1,17 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: newrelic_rpm
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.5.0.337
4
+ version: 4.6.0.338
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Wear
8
- - Kenichi Nakamura
9
8
  - Chris Pine
10
9
  - Dana Scheider
11
10
  autorequire:
12
11
  bindir: bin
13
12
  cert_chain: []
14
- date: 2017-09-22 00:00:00.000000000 Z
13
+ date: 2017-10-27 00:00:00.000000000 Z
15
14
  dependencies:
16
15
  - !ruby/object:Gem::Dependency
17
16
  name: rake
@@ -207,6 +206,9 @@ files:
207
206
  - lib/new_relic/agent/datastores/mongo/statement_formatter.rb
208
207
  - lib/new_relic/agent/datastores/redis.rb
209
208
  - lib/new_relic/agent/deprecator.rb
209
+ - lib/new_relic/agent/distributed_trace_monitor.rb
210
+ - lib/new_relic/agent/distributed_trace_payload.rb
211
+ - lib/new_relic/agent/distributed_trace_priority_sampled_buffer.rb
210
212
  - lib/new_relic/agent/encoding_normalizer.rb
211
213
  - lib/new_relic/agent/error_collector.rb
212
214
  - lib/new_relic/agent/error_event_aggregator.rb
@@ -215,8 +217,10 @@ files:
215
217
  - lib/new_relic/agent/event_buffer.rb
216
218
  - lib/new_relic/agent/event_listener.rb
217
219
  - lib/new_relic/agent/event_loop.rb
220
+ - lib/new_relic/agent/external.rb
218
221
  - lib/new_relic/agent/harvester.rb
219
222
  - lib/new_relic/agent/hostname.rb
223
+ - lib/new_relic/agent/http_clients/abstract_request.rb
220
224
  - lib/new_relic/agent/http_clients/curb_wrappers.rb
221
225
  - lib/new_relic/agent/http_clients/excon_wrappers.rb
222
226
  - lib/new_relic/agent/http_clients/http_rb_wrappers.rb
@@ -329,10 +333,12 @@ files:
329
333
  - lib/new_relic/agent/threading/backtrace_node.rb
330
334
  - lib/new_relic/agent/threading/backtrace_service.rb
331
335
  - lib/new_relic/agent/threading/thread_profile.rb
336
+ - lib/new_relic/agent/throughput_monitor.rb
332
337
  - lib/new_relic/agent/transaction.rb
333
338
  - lib/new_relic/agent/transaction/abstract_segment.rb
334
339
  - lib/new_relic/agent/transaction/attributes.rb
335
340
  - lib/new_relic/agent/transaction/datastore_segment.rb
341
+ - lib/new_relic/agent/transaction/distributed_tracing.rb
336
342
  - lib/new_relic/agent/transaction/external_request_segment.rb
337
343
  - lib/new_relic/agent/transaction/message_broker_segment.rb
338
344
  - lib/new_relic/agent/transaction/request_attributes.rb
@@ -340,6 +346,7 @@ files:
340
346
  - lib/new_relic/agent/transaction/slowest_sample_buffer.rb
341
347
  - lib/new_relic/agent/transaction/synthetics_sample_buffer.rb
342
348
  - lib/new_relic/agent/transaction/trace.rb
349
+ - lib/new_relic/agent/transaction/trace_builder.rb
343
350
  - lib/new_relic/agent/transaction/trace_node.rb
344
351
  - lib/new_relic/agent/transaction/tracing.rb
345
352
  - lib/new_relic/agent/transaction/transaction_sample_buffer.rb
@@ -349,7 +356,6 @@ files:
349
356
  - lib/new_relic/agent/transaction_event_primitive.rb
350
357
  - lib/new_relic/agent/transaction_event_recorder.rb
351
358
  - lib/new_relic/agent/transaction_metrics.rb
352
- - lib/new_relic/agent/transaction_sample_builder.rb
353
359
  - lib/new_relic/agent/transaction_sampler.rb
354
360
  - lib/new_relic/agent/transaction_state.rb
355
361
  - lib/new_relic/agent/transaction_timings.rb
@@ -1,138 +0,0 @@
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'
6
- require 'new_relic/agent/transaction/trace'
7
-
8
- module NewRelic
9
- module Agent
10
- # a builder is created with every sampled transaction, to dynamically
11
- # generate the sampled data. It is a thread-local object, and is not
12
- # accessed by any other thread so no need for synchronization.
13
- #
14
- # @api private
15
- class TransactionSampleBuilder
16
-
17
- # Once we hit the TT node limit, we use this class to hold our place in
18
- # the tree so that we can still get accurate names and times on the
19
- # nodes we've already created. The placeholder node keeps a
20
- # depth counter that's incremented on each node entry, and decremented
21
- # on exit, until it reaches zero, when we throw the placeholder away.
22
- # There should only ever be zero or one placeholder node at a time.
23
- #
24
- # @api private
25
- class PlaceholderNode
26
- attr_reader :parent_node
27
- attr_accessor :depth
28
-
29
- def initialize(parent_node)
30
- @parent_node = parent_node
31
- @depth = 1
32
- end
33
-
34
- # No-op - some clients expect to be able to use these to read/write
35
- # params on TT nodes.
36
- def [](key); end
37
- def []=(key, value); end
38
-
39
- # Stubbed out in case clients try to touch params directly.
40
- def params; {}; end
41
- def params=; end
42
- end
43
-
44
- attr_reader :current_node, :sample
45
-
46
- def initialize(time=Time.now)
47
- @sample = NewRelic::Agent::Transaction::Trace.new(time.to_f)
48
- @sample_start = time.to_f
49
- @current_node = @sample.root_node
50
- end
51
-
52
- def sample_id
53
- @sample.sample_id
54
- end
55
-
56
- def ignored?
57
- @ignore
58
- end
59
-
60
- def ignore_transaction
61
- @ignore = true
62
- end
63
-
64
- def node_limit
65
- Agent.config[:'transaction_tracer.limit_segments']
66
- end
67
-
68
- def trace_entry(time)
69
- if @sample.count_nodes < node_limit
70
- node = @sample.create_node(time.to_f - @sample_start)
71
- @current_node.add_called_node(node)
72
- @current_node = node
73
- if @sample.count_nodes == node_limit()
74
- ::NewRelic::Agent.logger.debug("Node limit of #{node_limit} reached, ceasing collection.")
75
- end
76
- else
77
- if @current_node.is_a?(PlaceholderNode)
78
- @current_node.depth += 1
79
- else
80
- @current_node = PlaceholderNode.new(@current_node)
81
- end
82
- end
83
- @current_node
84
- end
85
-
86
- def trace_exit(metric_name, time)
87
- if @current_node.is_a?(PlaceholderNode)
88
- @current_node.depth -= 1
89
- if @current_node.depth == 0
90
- @current_node = @current_node.parent_node
91
- end
92
- else
93
- @current_node.metric_name = metric_name
94
- @current_node.end_trace(time.to_f - @sample_start)
95
- @current_node = @current_node.parent_node
96
- end
97
- end
98
-
99
- def finish_trace(time=Time.now.to_f)
100
- # Should never get called twice, but in a rare case that we can't
101
- # reproduce in house it does. log forensics and return gracefully
102
- if @sample.finished
103
- ::NewRelic::Agent.logger.error "Unexpected double-finish_trace of Transaction Trace Object: \n#{@sample.to_s}"
104
- return
105
- end
106
- @sample.root_node.end_trace(time.to_f - @sample_start)
107
-
108
- @sample.threshold = transaction_trace_threshold
109
- @sample.finished = true
110
- @current_node = nil
111
- end
112
-
113
- TT_THRESHOLD_KEY = :'transaction_tracer.transaction_threshold'
114
-
115
- def transaction_trace_threshold #THREAD_LOCAL_ACCESS
116
- state = TransactionState.tl_get
117
- source_class = Agent.config.source(TT_THRESHOLD_KEY).class
118
- if source_class == Configuration::DefaultSource && state.current_transaction
119
- state.current_transaction.apdex_t * 4
120
- else
121
- Agent.config[TT_THRESHOLD_KEY]
122
- end
123
- end
124
-
125
- def scope_depth
126
- depth = -1 # have to account for the root
127
- current = @current_node
128
-
129
- while(current)
130
- depth += 1
131
- current = current.parent_node
132
- end
133
-
134
- depth
135
- end
136
- end
137
- end
138
- end