newrelic_rpm 3.6.8.168 → 3.6.9.171

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. data.tar.gz.sig +0 -0
  2. data/.gitignore +1 -0
  3. data/.yardopts +17 -0
  4. data/CHANGELOG +48 -0
  5. data/README.md +8 -6
  6. data/lib/new_relic/agent.rb +65 -17
  7. data/lib/new_relic/agent/agent.rb +42 -113
  8. data/lib/new_relic/agent/browser_monitoring.rb +9 -1
  9. data/lib/new_relic/agent/configuration/default_source.rb +12 -0
  10. data/lib/new_relic/agent/error_collector.rb +13 -6
  11. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +5 -5
  12. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +15 -0
  13. data/lib/new_relic/agent/instrumentation/curb.rb +2 -2
  14. data/lib/new_relic/agent/instrumentation/metric_frame.rb +2 -2
  15. data/lib/new_relic/agent/instrumentation/rack.rb +2 -0
  16. data/lib/new_relic/agent/instrumentation/resque.rb +9 -3
  17. data/lib/new_relic/agent/instrumentation/sidekiq.rb +5 -0
  18. data/lib/new_relic/agent/method_tracer.rb +45 -27
  19. data/lib/new_relic/agent/new_relic_service.rb +14 -6
  20. data/lib/new_relic/agent/pipe_service.rb +1 -1
  21. data/lib/new_relic/agent/request_sampler.rb +10 -7
  22. data/lib/new_relic/agent/rules_engine.rb +5 -0
  23. data/lib/new_relic/agent/samplers/object_sampler.rb +1 -1
  24. data/lib/new_relic/agent/sql_sampler.rb +4 -2
  25. data/lib/new_relic/agent/stats_engine.rb +3 -0
  26. data/lib/new_relic/agent/stats_engine/gc_profiler.rb +17 -7
  27. data/lib/new_relic/agent/stats_engine/metric_stats.rb +5 -7
  28. data/lib/new_relic/agent/stats_engine/stats_hash.rb +2 -0
  29. data/lib/new_relic/agent/supported_versions.rb +247 -0
  30. data/lib/new_relic/agent/threading/backtrace_service.rb +1 -1
  31. data/lib/new_relic/agent/threading/thread_profile.rb +2 -1
  32. data/lib/new_relic/agent/transaction.rb +7 -6
  33. data/lib/new_relic/agent/transaction/developer_mode_sample_buffer.rb +11 -5
  34. data/lib/new_relic/agent/transaction/force_persist_sample_buffer.rb +3 -3
  35. data/lib/new_relic/agent/transaction/slowest_sample_buffer.rb +3 -3
  36. data/lib/new_relic/agent/transaction/transaction_sample_buffer.rb +23 -4
  37. data/lib/new_relic/agent/transaction/xray_sample_buffer.rb +4 -4
  38. data/lib/new_relic/agent/transaction_sampler.rb +14 -18
  39. data/lib/new_relic/agent/worker_loop.rb +1 -0
  40. data/lib/new_relic/control.rb +1 -0
  41. data/lib/new_relic/control/instance_methods.rb +0 -1
  42. data/lib/new_relic/helper.rb +1 -2
  43. data/lib/new_relic/language_support.rb +12 -2
  44. data/lib/new_relic/local_environment.rb +12 -11
  45. data/lib/new_relic/rack.rb +9 -0
  46. data/lib/new_relic/rack/agent_hooks.rb +6 -0
  47. data/lib/new_relic/rack/browser_monitoring.rb +9 -2
  48. data/lib/new_relic/rack/developer_mode.rb +15 -1
  49. data/lib/new_relic/rack/error_collector.rb +7 -0
  50. data/lib/new_relic/recipes.rb +2 -0
  51. data/lib/new_relic/transaction_sample.rb +39 -48
  52. data/lib/new_relic/version.rb +1 -1
  53. data/lib/tasks/install.rake +44 -2
  54. data/lib/tasks/versions.html.erb +31 -0
  55. data/lib/tasks/versions.rake +52 -0
  56. data/lib/tasks/versions.txt.erb +14 -0
  57. data/newrelic_rpm.gemspec +4 -2
  58. data/test/agent_helper.rb +21 -1
  59. data/test/environments/lib/environments/runner.rb +19 -5
  60. data/test/environments/norails/Gemfile +4 -1
  61. data/test/environments/rails21/Gemfile +4 -6
  62. data/test/environments/rails21/Rakefile +4 -0
  63. data/test/environments/rails21/config/database.yml +2 -7
  64. data/test/environments/rails22/Gemfile +6 -13
  65. data/test/environments/rails22/Rakefile +4 -0
  66. data/test/environments/rails22/config/database.yml +2 -7
  67. data/test/environments/rails22/config/environment.rb +1 -1
  68. data/test/environments/rails23/Gemfile +3 -4
  69. data/test/environments/rails23/Rakefile +4 -0
  70. data/test/environments/rails23/config/database.yml +2 -7
  71. data/test/environments/rails30/Gemfile +2 -4
  72. data/test/environments/rails30/Rakefile +2 -0
  73. data/test/environments/rails30/config/database.yml +2 -7
  74. data/test/environments/rails31/Gemfile +2 -4
  75. data/test/environments/rails31/Rakefile +2 -0
  76. data/test/environments/rails31/config/database.yml +2 -7
  77. data/test/environments/rails32/Gemfile +2 -5
  78. data/test/environments/rails32/Rakefile +2 -0
  79. data/test/environments/rails32/config/database.yml +1 -1
  80. data/test/environments/rails40/Gemfile +7 -4
  81. data/test/environments/rails40/Rakefile +2 -0
  82. data/test/environments/rails40/config/database.yml +2 -7
  83. data/test/helpers/runtime_detection.rb +17 -0
  84. data/test/multiverse/lib/multiverse/suite.rb +20 -4
  85. data/test/multiverse/suites/agent_only/key_transactions_test.rb +1 -1
  86. data/test/multiverse/suites/agent_only/marshaling_test.rb +1 -1
  87. data/test/multiverse/suites/agent_only/thread_profiling_test.rb +32 -7
  88. data/test/multiverse/suites/agent_only/xray_sessions_test.rb +1 -0
  89. data/test/multiverse/suites/config_file_loading/config_file_loading_test.rb +4 -3
  90. data/test/multiverse/suites/curb/curb_test.rb +8 -0
  91. data/test/multiverse/suites/excon/excon_test.rb +8 -0
  92. data/test/multiverse/suites/httpclient/httpclient_test.rb +8 -0
  93. data/test/multiverse/suites/net_http/net_http_test.rb +8 -0
  94. data/test/multiverse/suites/padrino/Envfile +3 -2
  95. data/test/multiverse/suites/rails/gc_instrumentation_test.rb +17 -8
  96. data/test/multiverse/suites/resque/Envfile +3 -3
  97. data/test/multiverse/suites/resque/instrumentation_test.rb +47 -5
  98. data/test/multiverse/suites/sequel/Envfile +0 -3
  99. data/test/multiverse/suites/sequel/database.rb +53 -0
  100. data/test/{new_relic/agent/instrumentation/sequel_test.rb → multiverse/suites/sequel/sequel_instrumentation_test.rb} +12 -53
  101. data/test/multiverse/suites/sequel/{sequel_test.rb → sequel_safety_test.rb} +2 -17
  102. data/test/multiverse/suites/sidekiq/sidekiq_instrumentation_test.rb +50 -5
  103. data/test/multiverse/suites/sinatra/sinatra_metric_explosion_test.rb +15 -2
  104. data/test/multiverse/suites/typhoeus/typhoeus_test.rb +8 -0
  105. data/test/new_relic/agent/agent/connect_test.rb +3 -2
  106. data/test/new_relic/agent/agent_test.rb +89 -82
  107. data/test/new_relic/agent/browser_monitoring_test.rb +44 -1
  108. data/test/new_relic/agent/error_collector_test.rb +17 -20
  109. data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +13 -10
  110. data/test/new_relic/agent/instrumentation/active_record_subscriber_test.rb +16 -1
  111. data/test/new_relic/agent/instrumentation/task_instrumentation_test.rb +2 -2
  112. data/test/new_relic/agent/method_tracer/instance_methods/trace_execution_scoped_test.rb +1 -1
  113. data/test/new_relic/agent/new_relic_service_test.rb +78 -9
  114. data/test/new_relic/agent/pipe_channel_manager_test.rb +7 -9
  115. data/test/new_relic/agent/pipe_service_test.rb +4 -4
  116. data/test/new_relic/agent/request_sampler_test.rb +2 -2
  117. data/test/new_relic/agent/stats_engine/gc_profiler_test.rb +15 -35
  118. data/test/new_relic/agent/stats_engine/metric_stats_test.rb +15 -7
  119. data/test/new_relic/agent/stats_engine_test.rb +4 -3
  120. data/test/new_relic/agent/threading/backtrace_service_test.rb +2 -0
  121. data/test/new_relic/agent/threading/thread_profile_test.rb +19 -0
  122. data/test/new_relic/agent/transaction/developer_mode_sample_buffer_test.rb +4 -4
  123. data/test/new_relic/agent/transaction/force_persist_sample_buffer_test.rb +1 -1
  124. data/test/new_relic/agent/transaction_sampler_test.rb +60 -45
  125. data/test/new_relic/fake_collector.rb +37 -2
  126. data/test/new_relic/http_client_test_cases.rb +26 -1
  127. data/test/new_relic/language_support_test.rb +12 -31
  128. data/test/new_relic/local_environment_test.rb +6 -2
  129. data/test/new_relic/multiverse_helpers.rb +2 -5
  130. data/test/new_relic/transaction_sample_test.rb +57 -36
  131. data/test/performance/suites/config.rb +76 -0
  132. data/test/rum/no_html_and_no_header.result.html +3 -0
  133. data/test/rum/no_html_and_no_header.source.html +3 -0
  134. data/test/script/ci.sh +0 -2
  135. data/test/test_helper.rb +5 -0
  136. metadata +43 -26
  137. metadata.gz.sig +0 -0
@@ -10,6 +10,8 @@ module NewRelic
10
10
  module Agent
11
11
  # This module contains support for Real User Monitoring - the
12
12
  # javascript generation and configuration
13
+ #
14
+ # @api public
13
15
  module BrowserMonitoring
14
16
  class DummyTransaction
15
17
 
@@ -47,6 +49,9 @@ module NewRelic
47
49
  # This is the header string - it should be placed as high in the
48
50
  # page as is reasonably possible - that is, before any style or
49
51
  # javascript inclusions, but after any header-related meta tags
52
+ #
53
+ # @api public
54
+ #
50
55
  def browser_timing_header
51
56
  insert_js? ? header_js_string : ""
52
57
  end
@@ -59,6 +64,9 @@ module NewRelic
59
64
  #
60
65
  # This is the footer string - it should be placed as low in the
61
66
  # page as is reasonably possible.
67
+ #
68
+ # @api public
69
+ #
62
70
  def browser_timing_footer
63
71
  if insert_js?
64
72
  NewRelic::Agent::Transaction.freeze_name
@@ -154,7 +162,7 @@ module NewRelic
154
162
  end
155
163
 
156
164
  def use_beta_js_agent?
157
- return Agent.config[:js_errors_beta] && Agent.config[:js_agent_loader]
165
+ return Agent.config[:js_errors_beta] && !Agent.config[:js_agent_loader].to_s.empty?
158
166
  end
159
167
 
160
168
  # NOTE: This method may be overridden for internal prototyping, so should
@@ -520,6 +520,18 @@ module NewRelic
520
520
  :type => Boolean,
521
521
  :description => 'Enable or disable capturing and attachment of HTTP request parameters to transaction traces and traced errors.'
522
522
  },
523
+ :'sidekiq.capture_params' => {
524
+ :default => false,
525
+ :public => true,
526
+ :type => Boolean,
527
+ :description => 'Enable or disable capturing job arguments for transaction traces and traced errors in Sidekiq.'
528
+ },
529
+ :'resque.capture_params' => {
530
+ :default => false,
531
+ :public => true,
532
+ :type => Boolean,
533
+ :description => 'Enable or disable capturing job arguments for transaction traces and traced errors in Resque.'
534
+ },
523
535
  :capture_memcache_keys => {
524
536
  :default => false,
525
537
  :public => true,
@@ -298,20 +298,27 @@ module NewRelic
298
298
  NewRelic::Agent.logger.info("Unable to capture internal agent error due to an exception:", e)
299
299
  end
300
300
 
301
+ def merge!(errors)
302
+ errors.each do |error|
303
+ add_to_error_queue(error)
304
+ end
305
+ end
306
+
301
307
  # Get the errors currently queued up. Unsent errors are left
302
308
  # over from a previous unsuccessful attempt to send them to the server.
303
- def harvest_errors(unsent_errors)
309
+ def harvest_errors
304
310
  @lock.synchronize do
305
311
  errors = @errors
306
312
  @errors = []
307
-
308
- if unsent_errors && !unsent_errors.empty?
309
- errors = unsent_errors + errors
310
- end
311
-
312
313
  errors
313
314
  end
314
315
  end
316
+
317
+ def reset!
318
+ @lock.synchronize do
319
+ @errors = []
320
+ end
321
+ end
315
322
  end
316
323
  end
317
324
  end
@@ -65,6 +65,7 @@ module NewRelic
65
65
  :scoped => true)
66
66
 
67
67
  other_metrics = ActiveRecordHelper.rollup_metrics_for(base)
68
+
68
69
  if config = active_record_config_for_event(event)
69
70
  other_metrics << ActiveRecordHelper.remote_service_metric(config[:adapter], config[:host])
70
71
  end
@@ -82,12 +83,11 @@ module NewRelic
82
83
  end
83
84
 
84
85
  def active_record_config_for_event(event)
85
- return unless event.payload[:connection_id] && NewRelic::LanguageSupport.object_space_enabled?
86
+ return unless event.payload[:connection_id]
87
+
88
+ connections = ::ActiveRecord::Base.connection_handler.connection_pool_list.map { |handler| handler.connections }.flatten
89
+ connection = connections.detect { |connection| connection.object_id == event.payload[:connection_id] }
86
90
 
87
- # TODO: This will not work for JRuby and in any case we want
88
- # this to be part of the event meta data so it doesn't have
89
- # to be dug out of an ivar.
90
- connection = ObjectSpace._id2ref(event.payload[:connection_id])
91
91
  connection.instance_variable_get(:@config) if connection
92
92
  end
93
93
  end
@@ -6,6 +6,7 @@ require 'new_relic/agent/transaction'
6
6
  require 'new_relic/agent/instrumentation/queue_time'
7
7
  module NewRelic
8
8
  module Agent
9
+ # @api public
9
10
  module Instrumentation
10
11
  # == NewRelic instrumentation for controller actions and tasks
11
12
  #
@@ -20,6 +21,8 @@ module NewRelic
20
21
  # ClassMethods#add_transaction_tracer and
21
22
  # #perform_action_with_newrelic_trace
22
23
  #
24
+ # @api public
25
+ #
23
26
  module ControllerInstrumentation
24
27
 
25
28
  def self.included(clazz) # :nodoc:
@@ -45,16 +48,23 @@ module NewRelic
45
48
  module ClassMethods
46
49
  # Have NewRelic ignore actions in this controller. Specify the actions as hash options
47
50
  # using :except and :only. If no actions are specified, all actions are ignored.
51
+ #
52
+ # @api public
53
+ #
48
54
  def newrelic_ignore(specifiers={})
49
55
  newrelic_ignore_aspect('do_not_trace', specifiers)
50
56
  end
51
57
  # Have NewRelic omit apdex measurements on the given actions. Typically used for
52
58
  # actions that are not user facing or that skew your overall apdex measurement.
53
59
  # Accepts :except and :only options, as with #newrelic_ignore.
60
+ #
61
+ # @api public
62
+ #
54
63
  def newrelic_ignore_apdex(specifiers={})
55
64
  newrelic_ignore_aspect('ignore_apdex', specifiers)
56
65
  end
57
66
 
67
+ # @api public
58
68
  def newrelic_ignore_enduser(specifiers={})
59
69
  newrelic_ignore_aspect('ignore_enduser', specifiers)
60
70
  end
@@ -131,6 +141,8 @@ module NewRelic
131
141
  # See NewRelic::Agent::Instrumentation::ControllerInstrumentation#perform_action_with_newrelic_trace
132
142
  # for the full list of available options.
133
143
  #
144
+ # @api public
145
+ #
134
146
  def add_transaction_tracer(method, options={})
135
147
  # The metric path:
136
148
  options[:name] ||= method.to_s
@@ -294,6 +306,9 @@ module NewRelic
294
306
  #
295
307
  # If a single argument is passed in, it is treated as a metric
296
308
  # path. This form is deprecated.
309
+ #
310
+ # @api public
311
+ #
297
312
  def perform_action_with_newrelic_trace(*args, &block)
298
313
  request = newrelic_request(args)
299
314
  NewRelic::Agent::TransactionState.reset(request)
@@ -44,9 +44,9 @@ DependencyDetection.defer do
44
44
  alias_method :http_post_without_newrelic, :http_post
45
45
  alias_method :http_post, :http_post_with_newrelic
46
46
 
47
- def http_put_with_newrelic(url, data, &blk)
47
+ def http_put_with_newrelic(*args, &blk)
48
48
  self._nr_http_verb = :PUT
49
- http_put_with_newrelic(url, data, &blk)
49
+ http_put_without_newrelic(*args, &blk)
50
50
  end
51
51
  alias_method :http_put_without_newrelic, :http_put
52
52
  alias_method :http_put, :http_put_with_newrelic
@@ -10,9 +10,9 @@ module NewRelic
10
10
  #
11
11
  # This class is deprecated and will be removed in a future agent version.
12
12
  #
13
- # This class is not part of the public API. Avoid making calls on it directly.
13
+ # @api public
14
+ # @deprecated in favor of the +Transaction+ class
14
15
  #
15
- # @deprecated
16
16
  class MetricFrame
17
17
 
18
18
  # @deprecated
@@ -68,6 +68,8 @@ module NewRelic
68
68
  # add_transaction_tracer :call, :category => :rack, :name => 'my app'
69
69
  # end
70
70
  #
71
+ # @api public
72
+ #
71
73
  module Rack
72
74
  def newrelic_request_headers
73
75
  @newrelic_request.env
@@ -28,9 +28,15 @@ DependencyDetection.defer do
28
28
 
29
29
  def around_perform_with_monitoring(*args)
30
30
  begin
31
- perform_action_with_newrelic_trace(:name => 'perform',
32
- :class_name => self.name,
33
- :category => 'OtherTransaction/ResqueJob') do
31
+ perform_action_with_newrelic_trace(
32
+ :name => 'perform',
33
+ :class_name => self.name,
34
+ :category => 'OtherTransaction/ResqueJob') do
35
+
36
+ if NewRelic::Agent.config[:'resque.capture_params']
37
+ NewRelic::Agent.add_custom_parameters(:job_arguments => args)
38
+ end
39
+
34
40
  yield(*args)
35
41
  end
36
42
  ensure
@@ -22,6 +22,11 @@ DependencyDetection.defer do
22
22
  :name => 'perform',
23
23
  :class_name => msg['class'],
24
24
  :category => 'OtherTransaction/SidekiqJob') do
25
+
26
+ if NewRelic::Agent.config[:'sidekiq.capture_params']
27
+ NewRelic::Agent.add_custom_parameters(:job_arguments => msg['args'])
28
+ end
29
+
25
30
  yield
26
31
  end
27
32
  end
@@ -36,19 +36,25 @@ module NewRelic
36
36
  # add_method_tracer :process
37
37
  # end
38
38
  # end
39
+ #
40
+ # @api public
41
+ #
39
42
 
40
43
  module MethodTracer
41
-
42
- def self.included clazz #:nodoc:
44
+ def self.included clazz
43
45
  clazz.extend ClassMethods
44
46
  end
45
47
 
46
- def self.extended clazz #:nodoc:
48
+ def self.extended clazz
47
49
  clazz.extend ClassMethods
48
50
  end
49
51
 
50
52
  # Deprecated: original method preserved for API backward compatibility.
51
53
  # Use either #trace_execution_scoped or #trace_execution_unscoped
54
+ #
55
+ # @api public
56
+ # @deprecated
57
+ #
52
58
  def trace_method_execution(metric_names, push_scope, produce_metric, deduct_call_time_from_parent, &block) #:nodoc:
53
59
  if push_scope
54
60
  trace_execution_scoped(metric_names, :metric => produce_metric,
@@ -66,6 +72,8 @@ module NewRelic
66
72
  # * <tt>:force => true</tt> will force the metric to be captured even when
67
73
  # tracing is disabled with NewRelic::Agent#disable_all_tracing
68
74
  #
75
+ # @api public
76
+ #
69
77
  def trace_execution_unscoped(metric_names, options={})
70
78
  return yield unless NewRelic::Agent.is_execution_traced?
71
79
  t0 = Time.now
@@ -80,6 +88,9 @@ module NewRelic
80
88
  end
81
89
 
82
90
  # Deprecated. Use #trace_execution_scoped, a version with an options hash.
91
+ #
92
+ # @deprecated
93
+ #
83
94
  def trace_method_execution_with_scope(metric_names, produce_metric, deduct_call_time_from_parent, scoped_metric_only=false, &block) #:nodoc:
84
95
  trace_execution_scoped(metric_names,
85
96
  :metric => produce_metric,
@@ -120,6 +131,7 @@ module NewRelic
120
131
  def get_stats_scoped(first_name, scoped_metric_only)
121
132
  stat_engine.get_stats(first_name, true, scoped_metric_only)
122
133
  end
134
+
123
135
  # Shorthand method to get stats from the stat engine
124
136
  def get_stats_unscoped(name)
125
137
  stat_engine.get_stats_no_scope(name)
@@ -238,35 +250,37 @@ module NewRelic
238
250
  end
239
251
  end
240
252
  end
241
-
242
- # Trace a given block with stats and keep track of the caller.
243
- # See NewRelic::Agent::MethodTracer::ClassMethods#add_method_tracer for a description of the arguments.
244
- # +metric_names+ is either a single name or an array of metric names.
245
- # If more than one metric is passed, the +produce_metric+ option only applies to the first. The
246
- # others are always recorded. Only the first metric is pushed onto the scope stack.
247
- #
248
- # Generally you pass an array of metric names if you want to record the metric under additional
249
- # categories, but generally this *should never ever be done*. Most of the time you can aggregate
250
- # on the server.
251
- def trace_execution_scoped(metric_names, options={})
252
- return yield if trace_disabled?(options)
253
- set_if_nil(options, :metric)
254
- set_if_nil(options, :deduct_call_time_from_parent)
255
- metric_names = Array(metric_names)
256
- first_name = metric_names.shift
257
- start_time, expected_scope = trace_execution_scoped_header(options)
258
- begin
259
- yield
260
- ensure
261
- trace_execution_scoped_footer(start_time, first_name, metric_names, expected_scope, options)
262
- end
263
- end
264
-
265
253
  end
266
254
  include TraceExecutionScoped
267
255
 
256
+ # Trace a given block with stats and keep track of the caller.
257
+ # See NewRelic::Agent::MethodTracer::ClassMethods#add_method_tracer for a description of the arguments.
258
+ # +metric_names+ is either a single name or an array of metric names.
259
+ # If more than one metric is passed, the +produce_metric+ option only applies to the first. The
260
+ # others are always recorded. Only the first metric is pushed onto the scope stack.
261
+ #
262
+ # Generally you pass an array of metric names if you want to record the metric under additional
263
+ # categories, but generally this *should never ever be done*. Most of the time you can aggregate
264
+ # on the server.
265
+ #
266
+ # @api public
267
+ #
268
+ def trace_execution_scoped(metric_names, options={})
269
+ return yield if trace_disabled?(options)
270
+ set_if_nil(options, :metric)
271
+ set_if_nil(options, :deduct_call_time_from_parent)
272
+ metric_names = Array(metric_names)
273
+ first_name = metric_names.shift
274
+ start_time, expected_scope = trace_execution_scoped_header(options)
275
+ begin
276
+ yield
277
+ ensure
278
+ trace_execution_scoped_footer(start_time, first_name, metric_names, expected_scope, options)
279
+ end
280
+ end
268
281
 
269
282
  # Defines methods used at the class level, for adding instrumentation
283
+ # @api public
270
284
  module ClassMethods
271
285
  # contains methods refactored out of the #add_method_tracer method
272
286
  module AddMethodTracer
@@ -489,6 +503,8 @@ module NewRelic
489
503
  # add_method_tracer :foo, 'Custom/People/fetch'
490
504
  # end
491
505
  #
506
+ # @api public
507
+ #
492
508
  def add_method_tracer(method_name, metric_name_code=nil, options = {})
493
509
  return unless newrelic_method_exists?(method_name)
494
510
  metric_name_code ||= default_metric_name_code(method_name)
@@ -542,6 +558,8 @@ module NewRelic
542
558
  name.to_s.tr_s('^a-zA-Z0-9', '_')
543
559
  end
544
560
  end
561
+
562
+ # @!parse extend ClassMethods
545
563
  end
546
564
  end
547
565
  end
@@ -23,13 +23,14 @@ module NewRelic
23
23
  # 534: v2 (shows up in 2.1.0, our first tag)
24
24
 
25
25
  attr_accessor :request_timeout, :agent_id
26
- attr_reader :collector, :marshaller, :metric_id_cache
26
+ attr_reader :collector, :marshaller, :metric_id_cache, :last_metric_harvest_time
27
27
 
28
28
  def initialize(license_key=nil, collector=control.server)
29
29
  @license_key = license_key || Agent.config[:license_key]
30
30
  @collector = collector
31
31
  @request_timeout = Agent.config[:timeout]
32
32
  @metric_id_cache = {}
33
+ @last_metric_harvest_time = Time.now
33
34
 
34
35
  @audit_logger = ::NewRelic::Agent::AuditLogger.new(Agent.config)
35
36
  Agent.config.register_callback(:'audit_log.enabled') do |enabled|
@@ -109,11 +110,18 @@ module NewRelic
109
110
  metric_data_array
110
111
  end
111
112
 
112
- def metric_data(last_harvest_time, now, unsent_timeslice_data)
113
- metric_data_array = build_metric_data_array(unsent_timeslice_data)
114
- result = invoke_remote(:metric_data, @agent_id, last_harvest_time, now,
115
- metric_data_array)
113
+ def metric_data(stats_hash)
114
+ harvest_time = stats_hash.harvested_at || Time.now
115
+ metric_data_array = build_metric_data_array(stats_hash)
116
+ result = invoke_remote(
117
+ :metric_data,
118
+ @agent_id,
119
+ @last_metric_harvest_time.to_f,
120
+ harvest_time.to_f,
121
+ metric_data_array
122
+ )
116
123
  fill_metric_id_cache(result)
124
+ @last_metric_harvest_time = harvest_time
117
125
  result
118
126
  end
119
127
 
@@ -513,7 +521,7 @@ module NewRelic
513
521
  end
514
522
 
515
523
  def self.is_supported?
516
- RUBY_VERSION >= '1.9.2'
524
+ NewRelic::LanguageSupport.stdlib_json_usable?
517
525
  end
518
526
 
519
527
  def self.human_readable?
@@ -32,7 +32,7 @@ module NewRelic
32
32
  nil
33
33
  end
34
34
 
35
- def metric_data(last_harvest_time, now, unsent_timeslice_data)
35
+ def metric_data(unsent_timeslice_data)
36
36
  write_to_pipe(:stats => unsent_timeslice_data)
37
37
  {}
38
38
  end
@@ -47,9 +47,7 @@ class NewRelic::Agent::RequestSampler
47
47
  return self.synchronize { @samples.to_a }
48
48
  end
49
49
 
50
- # Clear any existing samples, reset the last sample time, and return the
51
- # previous set of samples. (Synchronized)
52
- def harvest
50
+ def reset!
53
51
  NewRelic::Agent.logger.debug "Resetting RequestSampler"
54
52
 
55
53
  sample_count, request_count = 0
@@ -63,15 +61,20 @@ class NewRelic::Agent::RequestSampler
63
61
  @notified_full = false
64
62
  end
65
63
 
64
+ [old_samples, sample_count, request_count]
65
+ end
66
+
67
+ # Clear any existing samples, reset the last sample time, and return the
68
+ # previous set of samples. (Synchronized)
69
+ def harvest
70
+ old_samples, sample_count, request_count = reset!
66
71
  record_sampling_rate(request_count, sample_count) if @enabled
67
72
  old_samples
68
73
  end
69
74
 
70
- alias_method :reset, :harvest
71
-
72
75
  # Merge samples back into the buffer, for example after a failed
73
76
  # transmission to the collector. (Synchronized)
74
- def merge(old_samples)
77
+ def merge!(old_samples)
75
78
  self.synchronize do
76
79
  old_samples.each { |s| @samples.append(s) }
77
80
  end
@@ -98,7 +101,7 @@ class NewRelic::Agent::RequestSampler
98
101
  NewRelic::Agent.config.register_callback(MAX_SAMPLES_KEY) do |max_samples|
99
102
  NewRelic::Agent.logger.debug "RequestSampler max_samples set to #{max_samples}"
100
103
  self.synchronize { @samples.capacity = max_samples }
101
- self.reset
104
+ self.reset!
102
105
  end
103
106
 
104
107
  NewRelic::Agent.config.register_callback(ENABLED_KEY) do |enabled|