newrelic_rpm 3.9.6.257 → 3.9.7.266

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG +45 -0
  3. data/lib/new_relic/agent.rb +0 -1
  4. data/lib/new_relic/agent/agent.rb +61 -22
  5. data/lib/new_relic/agent/agent_logger.rb +11 -9
  6. data/lib/new_relic/agent/configuration/default_source.rb +25 -2
  7. data/lib/new_relic/agent/cross_app_monitor.rb +15 -53
  8. data/lib/new_relic/agent/cross_app_tracing.rb +11 -3
  9. data/lib/new_relic/agent/custom_event_aggregator.rb +98 -0
  10. data/lib/new_relic/agent/event_buffer.rb +84 -0
  11. data/lib/new_relic/agent/harvester.rb +4 -15
  12. data/lib/new_relic/agent/hostname.rb +1 -9
  13. data/lib/new_relic/agent/inbound_request_monitor.rb +41 -0
  14. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +2 -2
  15. data/lib/new_relic/agent/instrumentation/queue_time.rb +0 -5
  16. data/lib/new_relic/agent/instrumentation/resque.rb +4 -9
  17. data/lib/new_relic/agent/javascript_instrumentor.rb +0 -12
  18. data/lib/new_relic/agent/method_tracer_helpers.rb +3 -1
  19. data/lib/new_relic/agent/new_relic_service.rb +1 -1
  20. data/lib/new_relic/agent/sampled_buffer.rb +13 -41
  21. data/lib/new_relic/agent/samplers/delayed_job_sampler.rb +52 -24
  22. data/lib/new_relic/agent/sized_buffer.rb +23 -0
  23. data/lib/new_relic/agent/synthetics_monitor.rb +50 -0
  24. data/lib/new_relic/agent/system_info.rb +28 -0
  25. data/lib/new_relic/agent/transaction.rb +78 -9
  26. data/lib/new_relic/agent/transaction/synthetics_sample_buffer.rb +25 -0
  27. data/lib/new_relic/agent/{request_sampler.rb → transaction_event_aggregator.rb} +53 -19
  28. data/lib/new_relic/agent/transaction_sample_builder.rb +3 -1
  29. data/lib/new_relic/agent/transaction_sampler.rb +10 -0
  30. data/lib/new_relic/agent/transaction_state.rb +1 -9
  31. data/lib/new_relic/coerce.rb +8 -2
  32. data/lib/new_relic/control.rb +0 -1
  33. data/lib/new_relic/local_environment.rb +12 -8
  34. data/lib/new_relic/metric_spec.rb +11 -2
  35. data/lib/new_relic/rack/developer_mode.rb +9 -1
  36. data/lib/new_relic/transaction_sample.rb +4 -10
  37. data/lib/new_relic/version.rb +1 -1
  38. data/newrelic_rpm.gemspec +1 -0
  39. data/test/agent_helper.rb +15 -2
  40. data/test/environments/norails/Gemfile +1 -0
  41. data/test/environments/rails21/Gemfile +1 -0
  42. data/test/environments/rails22/Gemfile +1 -0
  43. data/test/environments/rails23/Gemfile +1 -0
  44. data/test/environments/rails30/Gemfile +1 -0
  45. data/test/environments/rails31/Gemfile +1 -0
  46. data/test/environments/rails32/Gemfile +2 -1
  47. data/test/environments/rails40/Gemfile +2 -1
  48. data/test/environments/rails41/Gemfile +3 -1
  49. data/test/environments/rails42/Gemfile +3 -1
  50. data/test/fixtures/cross_agent_tests/README.md +6 -2
  51. data/test/fixtures/cross_agent_tests/docker_container_id/README.md +6 -0
  52. data/test/fixtures/cross_agent_tests/docker_container_id/cases.json +22 -0
  53. data/test/fixtures/cross_agent_tests/docker_container_id/docker-0.9.1.txt +10 -0
  54. data/test/fixtures/cross_agent_tests/docker_container_id/docker-1.0.0.txt +10 -0
  55. data/test/fixtures/cross_agent_tests/docker_container_id/docker-1.3.txt +9 -0
  56. data/test/fixtures/cross_agent_tests/docker_container_id/empty.txt +0 -0
  57. data/test/fixtures/cross_agent_tests/docker_container_id/lxc-containers-without-docker.txt +10 -0
  58. data/test/fixtures/cross_agent_tests/proc_meminfo/README.md +7 -0
  59. data/test/fixtures/cross_agent_tests/proc_meminfo/meminfo_4096MB.txt +47 -0
  60. data/test/fixtures/cross_agent_tests/rum_client_config.json +0 -80
  61. data/test/fixtures/cross_agent_tests/synthetics/synthetics.json +317 -0
  62. data/test/multiverse/lib/multiverse/runner.rb +1 -1
  63. data/test/multiverse/lib/multiverse/suite.rb +1 -0
  64. data/test/multiverse/suites/active_record/Envfile +42 -8
  65. data/test/multiverse/suites/active_record/ar_method_aliasing.rb +8 -4
  66. data/test/multiverse/suites/agent_only/audit_log_test.rb +0 -2
  67. data/test/multiverse/suites/agent_only/collector_exception_handling_test.rb +1 -2
  68. data/test/multiverse/suites/agent_only/cross_application_tracing_test.rb +5 -5
  69. data/test/multiverse/suites/agent_only/encoding_handling_test.rb +2 -0
  70. data/test/multiverse/suites/agent_only/harvest_timestamps_test.rb +8 -0
  71. data/test/multiverse/suites/agent_only/synthetics_test.rb +139 -0
  72. data/test/multiverse/suites/delayed_job/Envfile +79 -0
  73. data/test/multiverse/suites/delayed_job/before_suite.rb +33 -0
  74. data/test/multiverse/suites/delayed_job/config/newrelic.yml +18 -0
  75. data/test/multiverse/suites/delayed_job/delayed_job_sampler_test.rb +131 -0
  76. data/test/multiverse/suites/delayed_job/unsupported_backend_test.rb +24 -0
  77. data/test/multiverse/suites/high_security/high_security_test.rb +3 -10
  78. data/test/multiverse/suites/rails/Envfile +4 -4
  79. data/test/multiverse/suites/rails/request_statistics_test.rb +4 -4
  80. data/test/new_relic/agent/agent_test.rb +32 -4
  81. data/test/new_relic/agent/configuration/default_source_test.rb +6 -0
  82. data/test/new_relic/agent/cross_app_monitor_test.rb +23 -29
  83. data/test/new_relic/agent/custom_event_aggregator_test.rb +88 -0
  84. data/test/new_relic/agent/event_buffer_test_cases.rb +152 -0
  85. data/test/new_relic/agent/harvester_test.rb +5 -25
  86. data/test/new_relic/agent/hostname_test.rb +1 -1
  87. data/test/new_relic/agent/inbound_request_monitor_test.rb +49 -0
  88. data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +9 -9
  89. data/test/new_relic/agent/instrumentation/queue_time_test.rb +0 -19
  90. data/test/new_relic/agent/javascript_instrumentor_test.rb +0 -45
  91. data/test/new_relic/agent/new_relic_service_test.rb +17 -12
  92. data/test/new_relic/agent/pipe_channel_manager_test.rb +4 -4
  93. data/test/new_relic/agent/sampled_buffer_test.rb +73 -145
  94. data/test/new_relic/agent/sized_buffer_test.rb +29 -0
  95. data/test/new_relic/agent/synthetics_monitor_test.rb +96 -0
  96. data/test/new_relic/agent/system_info_test.rb +19 -3
  97. data/test/new_relic/agent/transaction/developer_mode_sample_buffer_test.rb +14 -8
  98. data/test/new_relic/agent/transaction/synthetics_sample_buffer_test.rb +38 -0
  99. data/test/new_relic/agent/{request_sampler_test.rb → transaction_event_aggregator_test.rb} +55 -4
  100. data/test/new_relic/agent/transaction_sampler_test.rb +33 -11
  101. data/test/new_relic/agent/transaction_state_test.rb +0 -1
  102. data/test/new_relic/agent/transaction_test.rb +121 -19
  103. data/test/new_relic/coerce_test.rb +38 -3
  104. data/test/new_relic/control_test.rb +1 -0
  105. data/test/new_relic/fake_collector.rb +6 -2
  106. data/test/new_relic/fake_external_server.rb +2 -6
  107. data/test/new_relic/fake_server.rb +46 -29
  108. data/test/new_relic/http_client_test_cases.rb +71 -2
  109. data/test/new_relic/local_environment_test.rb +78 -0
  110. data/test/new_relic/metric_parser/metric_parser_test.rb +2 -0
  111. data/test/new_relic/metric_spec_test.rb +43 -0
  112. data/test/new_relic/multiverse_helpers.rb +11 -18
  113. data/test/new_relic/rack/browser_monitoring_test.rb +1 -18
  114. data/test/new_relic/rack/developer_mode_test.rb +1 -1
  115. data/test/new_relic/transaction_sample_test.rb +14 -4
  116. data/test/performance/suites/rack_middleware.rb +3 -1
  117. data/test/test_helper.rb +33 -0
  118. metadata +48 -7
  119. metadata.gz.sig +0 -0
  120. data/lib/new_relic/agent/browser_token.rb +0 -41
  121. data/test/multiverse/suites/agent_only/before_suite.rb +0 -7
  122. data/test/new_relic/agent/browser_token_test.rb +0 -56
@@ -19,6 +19,9 @@ module NewRelic
19
19
  # The cross app transaction header for "outgoing" calls
20
20
  NR_TXN_HEADER = 'X-NewRelic-Transaction'
21
21
 
22
+ # The cross app synthetics header
23
+ NR_SYNTHETICS_HEADER = 'X-NewRelic-Synthetics'
24
+
22
25
  # The index of the transaction GUID in the appdata header of responses
23
26
  APPDATA_TXN_GUID_INDEX = 5
24
27
 
@@ -169,9 +172,14 @@ module NewRelic
169
172
 
170
173
  state.is_cross_app_caller = true
171
174
  txn_guid = state.request_guid
172
- if state.current_transaction
173
- trip_id = state.current_transaction.cat_trip_id(state)
174
- path_hash = state.current_transaction.cat_path_hash(state)
175
+ txn = state.current_transaction
176
+ if txn
177
+ trip_id = txn.cat_trip_id(state)
178
+ path_hash = txn.cat_path_hash(state)
179
+
180
+ if txn.raw_synthetics_header
181
+ request[NR_SYNTHETICS_HEADER] = txn.raw_synthetics_header
182
+ end
175
183
  end
176
184
  txn_data = NewRelic::JSONWrapper.dump([txn_guid, false, trip_id, path_hash])
177
185
 
@@ -0,0 +1,98 @@
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/sized_buffer'
6
+
7
+ module NewRelic
8
+ module Agent
9
+ class CustomEventAggregator
10
+ include NewRelic::Coerce
11
+
12
+ TYPE = 'type'.freeze
13
+ TIMESTAMP = 'timestamp'.freeze
14
+ SOURCE = 'source'.freeze
15
+ AGENT_SOURCE = 'Agent'.freeze
16
+ EVENT_PARAMS_CTX = 'recording custom event'.freeze
17
+ EVENT_TYPE_REGEX = /^[a-zA-Z0-9:_ ]+$/.freeze
18
+
19
+ DEFAULT_CAPACITY_KEY = :'custom_insights_events.max_samples_stored'
20
+
21
+ def initialize
22
+ @lock = Mutex.new
23
+ @buffer = SampledBuffer.new(NewRelic::Agent.config[DEFAULT_CAPACITY_KEY])
24
+ @type_strings = Hash.new { |hash, key| hash[key] = key.to_s.freeze }
25
+ register_config_callbacks
26
+ end
27
+
28
+ def register_config_callbacks
29
+ NewRelic::Agent.config.register_callback(DEFAULT_CAPACITY_KEY) do |max_samples|
30
+ NewRelic::Agent.logger.debug "CustomEventAggregator max_samples set to #{max_samples}"
31
+ @lock.synchronize do
32
+ @buffer.capacity = max_samples
33
+ end
34
+ end
35
+ end
36
+
37
+ def record(type, attributes, source=AGENT_SOURCE)
38
+ type = @type_strings[type]
39
+ unless type =~ EVENT_TYPE_REGEX
40
+ note_dropped_event(type)
41
+ return false
42
+ end
43
+
44
+ event = [
45
+ { TYPE => type, TIMESTAMP => Time.now.to_i, SOURCE => source },
46
+ event_params(attributes, EVENT_PARAMS_CTX)
47
+ ]
48
+
49
+ stored = @lock.synchronize do
50
+ @buffer.append(event)
51
+ end
52
+ stored
53
+ end
54
+
55
+ def harvest!
56
+ results = []
57
+ drop_count = 0
58
+ @lock.synchronize do
59
+ results.concat(@buffer.to_a)
60
+ drop_count += @buffer.num_dropped
61
+ @buffer.reset!
62
+ end
63
+ note_dropped_events(results.size, drop_count)
64
+ results
65
+ end
66
+
67
+ def note_dropped_events(captured_count, dropped_count)
68
+ total_count = captured_count + dropped_count
69
+ if dropped_count > 0
70
+ NewRelic::Agent.logger.warn("Dropped #{dropped_count} custom events out of #{total_count}.")
71
+ end
72
+ engine = NewRelic::Agent.instance.stats_engine
73
+ engine.tl_record_supportability_metric_count("Events/Customer/Seen" , total_count)
74
+ engine.tl_record_supportability_metric_count("Events/Customer/Sent" , captured_count)
75
+ engine.tl_record_supportability_metric_count("Events/Customer/Dropped", dropped_count)
76
+ end
77
+
78
+ def merge!(events)
79
+ @lock.synchronize do
80
+ events.each do |event|
81
+ @buffer.append(event)
82
+ end
83
+ end
84
+ end
85
+
86
+ def reset!
87
+ @lock.synchronize { @buffer.reset! }
88
+ end
89
+
90
+ def note_dropped_event(type)
91
+ ::NewRelic::Agent.logger.log_once(:warn, "dropping_event_of_type:#{type}",
92
+ "Invalid event type name '#{type}', not recording.")
93
+ @buffer.note_dropped
94
+ end
95
+
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,84 @@
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
+ # EventBuffer is intended to be an abstract base class. It should not be
6
+ # instantiated directly. Subclasses should define an `append_event` method
7
+ # looking something like this:
8
+ #
9
+ # def append_event(x)
10
+ # <attempt to append>
11
+ # if append_success?
12
+ # return x
13
+ # else
14
+ # return nil
15
+ # end
16
+ # end
17
+
18
+ module NewRelic
19
+ module Agent
20
+ class EventBuffer
21
+ attr_reader :capacity
22
+
23
+ def initialize(capacity)
24
+ @capacity = capacity
25
+ @items = []
26
+ @seen = 0
27
+ end
28
+
29
+ def reset!
30
+ @items = []
31
+ @seen = 0
32
+ end
33
+
34
+ def capacity=(new_capacity)
35
+ @capacity = new_capacity
36
+ old_items = @items
37
+ @items = []
38
+ old_seen = @seen
39
+ old_items.each { |i| append(i) }
40
+ @seen = old_seen
41
+ end
42
+
43
+ def append(x)
44
+ @seen += 1
45
+ append_event(x)
46
+ end
47
+
48
+ def <<(x)
49
+ append(x)
50
+ self # return self for method chaining
51
+ end
52
+
53
+ def full?
54
+ @items.size >= @capacity
55
+ end
56
+
57
+ def size
58
+ @items.size
59
+ end
60
+
61
+ def note_dropped
62
+ @seen += 1
63
+ end
64
+
65
+ def num_seen
66
+ @seen
67
+ end
68
+
69
+ def num_dropped
70
+ @seen - @items.size
71
+ end
72
+
73
+ def sample_rate
74
+ @seen > 0 ? (size.to_f / @seen) : 0.0
75
+ end
76
+
77
+ def to_a
78
+ @items.dup
79
+ end
80
+
81
+ end
82
+ end
83
+ end
84
+
@@ -13,9 +13,7 @@ module NewRelic
13
13
  # We intentionally don't set our pid as started at this point.
14
14
  # Startup routines must call mark_started when they consider us set!
15
15
  @starting_pid = nil
16
-
17
16
  @after_forker = after_forker
18
- @lock = Mutex.new
19
17
 
20
18
  if events
21
19
  events.subscribe(:start_transaction, &method(:on_transaction))
@@ -23,17 +21,11 @@ module NewRelic
23
21
  end
24
22
 
25
23
  def on_transaction(*_)
26
- return unless restart_in_children_enabled? && needs_restart? && harvest_thread_enabled?
27
-
28
- needs_thread_start = false
29
- @lock.synchronize do
30
- needs_thread_start = needs_restart?
31
- mark_started
32
- end
24
+ return unless restart_in_children_enabled? &&
25
+ needs_restart? &&
26
+ harvest_thread_enabled?
33
27
 
34
- if needs_thread_start
35
- restart_harvest_thread
36
- end
28
+ restart_harvest_thread
37
29
  end
38
30
 
39
31
  def mark_started(pid = Process.pid)
@@ -53,11 +45,8 @@ module NewRelic
53
45
  end
54
46
 
55
47
  def restart_harvest_thread
56
- # Daemonize reports thread as still alive when it isn't... whack!
57
- NewRelic::Agent.instance.instance_variable_set(:@worker_thread, nil)
58
48
  @after_forker.after_fork(:force_reconnect => true)
59
49
  end
60
-
61
50
  end
62
51
  end
63
52
  end
@@ -22,16 +22,8 @@ module NewRelic
22
22
  end
23
23
  end
24
24
 
25
- # TODO: Once config transforms are in, use those instead of handcoding
26
25
  def self.get_dyno_prefixes
27
- dyno_prefixes = ::NewRelic::Agent.config[:'heroku.dyno_name_prefixes_to_shorten'] || []
28
- if dyno_prefixes.is_a?(String)
29
- dyno_prefixes = dyno_prefixes.split(',')
30
- elsif !dyno_prefixes.respond_to?(:find)
31
- ::NewRelic::Agent.logger.warn("Ignoring invalid setting found for 'heroku.dyno_name_prefixes_to_shorten', #{dyno_prefixes}.")
32
- dyno_prefixes = []
33
- end
34
- dyno_prefixes
26
+ ::NewRelic::Agent.config[:'heroku.dyno_name_prefixes_to_shorten']
35
27
  end
36
28
  end
37
29
  end
@@ -0,0 +1,41 @@
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
+ # This class serves as the base for objects wanting to monitor and respond to
6
+ # incoming web requests. Examples include cross application tracing and
7
+ # synthetics.
8
+ #
9
+ # Subclasses are expected to define on_finished_configuring(events) which will
10
+ # be called when the agent is fully configured. That method is expected to
11
+ # subscribe to the necessary request events, such as before_call and after_call
12
+ # for the monitor to do its work.
13
+ module NewRelic
14
+ module Agent
15
+ class InboundRequestMonitor
16
+
17
+ attr_reader :obfuscator
18
+
19
+ def initialize(events)
20
+ events.subscribe(:finished_configuring) do
21
+ # This requires :encoding_key, so must wait until :finished_configuring
22
+ setup_obfuscator
23
+ on_finished_configuring(events)
24
+ end
25
+ end
26
+
27
+ def setup_obfuscator
28
+ @obfuscator = NewRelic::Agent::Obfuscator.new(NewRelic::Agent.config[:encoding_key])
29
+ end
30
+
31
+ def deserialize_header(encoded_header, key)
32
+ decoded_header = obfuscator.deobfuscate(encoded_header)
33
+ NewRelic::JSONWrapper.load(decoded_header)
34
+ rescue => err
35
+ # If we have a failure of any type here, just return nil and carry on
36
+ NewRelic::Agent.logger.debug("Failure deserializing encoded header '#{key}' in #{self.class}, #{err.class}, #{err.message}")
37
+ nil
38
+ end
39
+ end
40
+ end
41
+ end
@@ -213,7 +213,7 @@ module NewRelic
213
213
  end
214
214
 
215
215
  class TransactionNamer
216
- def self.name(txn, traced_obj, category, options={})
216
+ def self.name_for(txn, traced_obj, category, options={})
217
217
  "#{prefix_for_category(txn, category)}#{path_name(traced_obj, options)}"
218
218
  end
219
219
 
@@ -354,7 +354,7 @@ module NewRelic
354
354
 
355
355
  category = trace_options[:category] || :controller
356
356
  txn_options = create_transaction_options(trace_options, available_params)
357
- txn_options[:transaction_name] = TransactionNamer.name(nil, self, category, trace_options)
357
+ txn_options[:transaction_name] = TransactionNamer.name_for(nil, self, category, trace_options)
358
358
  txn_options[:apdex_start_time] = detect_queue_start_time(state)
359
359
 
360
360
  begin
@@ -49,11 +49,6 @@ module NewRelic
49
49
  earliest
50
50
  end
51
51
 
52
- def record_frontend_metrics(start_time, now=Time.now) #THREAD_LOCAL_ACCESS
53
- NewRelic::Agent.instance.stats_engine.tl_record_unscoped_metrics(
54
- ALL_QUEUE_METRIC, (now - start_time).to_f)
55
- end
56
-
57
52
  def timestamp_string_from_header_value(value)
58
53
  case value
59
54
  when /^\s*([\d+\.]+)\s*$/ then $1
@@ -15,12 +15,6 @@ DependencyDetection.defer do
15
15
  end
16
16
 
17
17
  executes do
18
- # == Resque Instrumentation
19
- #
20
- # Installs a hook to ensure the agent starts manually when the worker
21
- # starts and also adds the tracer to the process method which executes
22
- # in the forked task.
23
-
24
18
  module Resque
25
19
  module Plugins
26
20
  module NewRelicInstrumentation
@@ -40,8 +34,7 @@ DependencyDetection.defer do
40
34
  yield(*args)
41
35
  end
42
36
  ensure
43
- NewRelic::Agent.shutdown if NewRelic::LanguageSupport.can_fork? &&
44
- (!Resque.respond_to?(:inline) || !Resque.inline)
37
+ NewRelic::Agent.agent.flush_pipe_data
45
38
  end
46
39
  end
47
40
  end
@@ -97,7 +90,9 @@ DependencyDetection.defer do
97
90
  end
98
91
 
99
92
  ::Resque.before_fork do |job|
100
- NewRelic::Agent.register_report_channel(job.object_id)
93
+ if ENV['FORK_PER_JOB'] != 'false'
94
+ NewRelic::Agent.register_report_channel(job.object_id)
95
+ end
101
96
  end
102
97
 
103
98
  ::Resque.after_fork do |job|
@@ -125,8 +125,6 @@ module NewRelic
125
125
  TRANSACTION_NAME_KEY = "transactionName".freeze
126
126
  QUEUE_TIME_KEY = "queueTime".freeze
127
127
  APPLICATION_TIME_KEY = "applicationTime".freeze
128
- TT_GUID_KEY = "ttGuid".freeze
129
- AGENT_TOKEN_KEY = "agentToken".freeze
130
128
  AGENT_KEY = "agent".freeze
131
129
  USER_ATTRIBUTES_KEY = "userAttributes".freeze
132
130
  SSL_FOR_HTTP_KEY = "sslForHttp".freeze
@@ -143,14 +141,9 @@ module NewRelic
143
141
  TRANSACTION_NAME_KEY => obfuscator.obfuscate(timings.transaction_name_or_unknown),
144
142
  QUEUE_TIME_KEY => timings.queue_time_in_millis,
145
143
  APPLICATION_TIME_KEY => timings.app_time_in_millis,
146
- AGENT_TOKEN_KEY => state.request_token,
147
144
  AGENT_KEY => NewRelic::Agent.config[:js_agent_file]
148
145
  }
149
146
 
150
- if include_guid?(state, timings)
151
- data[TT_GUID_KEY] = state.request_guid
152
- end
153
-
154
147
  add_ssl_for_http(data)
155
148
  add_user_attributes(data, state.current_transaction)
156
149
 
@@ -172,11 +165,6 @@ module NewRelic
172
165
  data[USER_ATTRIBUTES_KEY] = obfuscator.obfuscate(json)
173
166
  end
174
167
 
175
- def include_guid?(state, timings)
176
- state.current_transaction &&
177
- state.current_transaction.include_guid?(state, timings.app_time_in_seconds)
178
- end
179
-
180
168
  # Still support deprecated capture_attributes.page_view_events for
181
169
  # clients that use it. Could potentially be removed if we don't have
182
170
  # anymore users with it set according to zeitgeist.
@@ -5,6 +5,8 @@
5
5
  module NewRelic
6
6
  module Agent
7
7
  module MethodTracerHelpers
8
+ MAX_ALLOWED_METRIC_DURATION = 1_000_000_000 # roughly 31 years
9
+
8
10
  extend self
9
11
 
10
12
  # helper for logging errors to the newrelic_agent.log
@@ -43,7 +45,7 @@ module NewRelic
43
45
  duration = t1 - t0
44
46
  exclusive = duration - frame.children_time
45
47
 
46
- if duration < 1_000_000_000 # roughly 31 years
48
+ if duration < MAX_ALLOWED_METRIC_DURATION
47
49
  if duration < 0
48
50
  ::NewRelic::Agent.logger.log_once(:warn, "metric_duration_negative:#{first_name}",
49
51
  "Metric #{first_name} has negative duration: #{duration} s")
@@ -414,7 +414,7 @@ module NewRelic
414
414
  end
415
415
  case response
416
416
  when Net::HTTPSuccess
417
- true # fall through
417
+ true # do nothing
418
418
  when Net::HTTPUnauthorized
419
419
  raise LicenseException, 'Invalid license key, please visit support.newrelic.com'
420
420
  when Net::HTTPServiceUnavailable
@@ -7,67 +7,39 @@
7
7
  # in the Array is equal. It uses reservoir sampling in order to achieve this:
8
8
  # http://xlinux.nist.gov/dads/HTML/reservoirSampling.html
9
9
 
10
+ require 'new_relic/agent/event_buffer'
11
+
10
12
  module NewRelic
11
13
  module Agent
12
- class SampledBuffer
13
- attr_reader :seen, :capacity, :seen_lifetime, :captured_lifetime
14
+ class SampledBuffer < EventBuffer
15
+ attr_reader :seen_lifetime, :captured_lifetime
14
16
 
15
17
  def initialize(capacity)
16
- @items = []
17
- @capacity = capacity
18
+ super
18
19
  @captured_lifetime = 0
19
- @seen = 0
20
- @seen_lifetime = 0
20
+ @seen_lifetime = 0
21
21
  end
22
22
 
23
- def reset
23
+ def reset!
24
24
  @captured_lifetime += @items.size
25
- @seen_lifetime += @seen
26
- @items = []
27
- @seen = 0
28
- end
29
-
30
- def full?
31
- @items.size >= @capacity
25
+ @seen_lifetime += @seen
26
+ super
32
27
  end
33
28
 
34
- # Like '<<', but returns the value of full?
35
- def append(x)
36
- (self << x).full?
37
- end
38
-
39
- def <<(x)
40
- @seen += 1
29
+ def append_event(x)
41
30
  if @items.size < @capacity
42
31
  @items << x
32
+ return x
43
33
  else
44
34
  m = rand(@seen) # [0, @seen)
45
35
  if m < @capacity
46
36
  @items[m] = x
37
+ return x
47
38
  else
48
39
  # discard current sample
40
+ return nil
49
41
  end
50
42
  end
51
- return self
52
- end
53
-
54
- def size
55
- @items.size
56
- end
57
-
58
- def to_a
59
- @items.dup
60
- end
61
-
62
- def capacity=(new_capacity)
63
- @capacity = new_capacity
64
- old_items = @items
65
- @items = []
66
- old_items.each { |i| self << i }
67
- end
68
-
69
- def sample_rate
70
- @seen > 0 ? (size.to_f / @seen) : 0.0
71
43
  end
72
44
 
73
45
  def sample_rate_lifetime