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
data.tar.gz.sig CHANGED
Binary file
data/.gitignore CHANGED
@@ -22,3 +22,4 @@ lib/new_relic/build.rb
22
22
  .pryrc
23
23
  .tm_properties
24
24
  .bundle
25
+ .yardoc
@@ -0,0 +1,17 @@
1
+ --non-transitive-tag api
2
+ --api public
3
+ lib/new_relic/agent.rb
4
+ lib/new_relic/agent/method_tracer.rb
5
+ lib/new_relic/agent/instrumentation/controller_instrumentation.rb
6
+ lib/new_relic/agent/instrumentation/rack.rb
7
+ lib/new_relic/agent/instrumentation/metric_frame.rb
8
+ lib/new_relic/agent/transaction.rb
9
+ lib/new_relic/rack/developer_mode.rb
10
+ lib/new_relic/rack/agent_hooks.rb
11
+ lib/new_relic/rack/browser_monitoring.rb
12
+ lib/new_relic/rack/error_collector.rb
13
+ lib/new_relic/rack.rb
14
+ -
15
+ LICENSE
16
+ CHANGELOG
17
+ GUIDELINES_FOR_CONTRIBUTING.md
data/CHANGELOG CHANGED
@@ -1,5 +1,48 @@
1
1
  # New Relic Ruby Agent Release Notes #
2
2
 
3
+ ## v3.6.9 ##
4
+
5
+ * Experimental Rubinius 2.x support
6
+
7
+ The agent is now being tested against the latest version of Rubinius. While
8
+ support is still considered experimental, you can track the progress at
9
+ http://docs.newrelic.com/docs/ruby/rubinius for up to date status.
10
+
11
+ * Capture arguments for Resque and Sidekiq jobs
12
+
13
+ The agent can optionally record arguments for your Resque and Sidekiq jobs on
14
+ transaction traces and traced errors. This is disabled by default, but may be
15
+ enabled by setting resque.capture_params or sidekiq.capture_params.
16
+
17
+ Thanks to Juan Ignacio Pumarino, Ken Mayer, Paul Henry, and Eric Saxby for
18
+ their help with this feature!
19
+
20
+ * Supported versions rake task and documentation
21
+
22
+ We've improved our documentation for what Ruby and gem versions we support.
23
+ Run `rake newrelic:supported_versions` or see the latest agent's versions at
24
+ https://docs.newrelic.com/docs/ruby/supported-frameworks.
25
+
26
+ * ActiveRecord 4.0 explain plans for JRuby and Rubinius
27
+
28
+ The agent's ActiveRecord 4.0 instrumentation could not gather SQL explain
29
+ plans on JRuby by default because of a dependency on ObjectSpace, which isn't
30
+ avialable by default. This has been fixed.
31
+
32
+ * Fix for Curb http_put_with_newrelic
33
+
34
+ A bug in the agent caused PUT calls in the Curb gem to crash. This has been
35
+ fixed. Thanks to Michael D'Auria and Kirk Diggler for the contributions!
36
+
37
+ * Fix for head position on RUM injection
38
+
39
+ Certain unusual HTML documents resulted in browser monitoring injecting
40
+ incorrect content. Thanks Alex McHale for the contribution!
41
+
42
+ * Specify the Content-Type header in developer mode
43
+
44
+ Thanks Jared Ning for the contribution!
45
+
3
46
  ## v3.6.8 ##
4
47
 
5
48
  * X-Ray Sessions support
@@ -8,6 +51,11 @@
8
51
  profiling for web transactions. For full details see our X-Ray sessions
9
52
  documentation at https://newrelic.com/docs/site/xray-sessions.
10
53
 
54
+ * Percentiles and Histograms
55
+
56
+ The Ruby Agent now captures data that provides percentile and histogram views
57
+ in the New Relic UI.
58
+
11
59
  * CPU metrics re-enabled for JRuby >= 1.7.0
12
60
 
13
61
  To work around a JRuby bug, the Ruby agent stopped gathering CPU metrics on
data/README.md CHANGED
@@ -9,27 +9,29 @@ dual-purposed as a either a Rails plugin or a Gem, hosted on
9
9
 
10
10
  The New Relic Ruby Agent runs in one of two modes:
11
11
 
12
- #### Production Mode
13
-
12
+ **Production Mode**
14
13
  Low overhead instrumentation that captures detailed information on
15
14
  your application running in production and transmits them to
16
15
  newrelic.com where you can monitor them in real time.
17
16
 
18
- #### Developer Mode
19
-
17
+ **Developer Mode**
20
18
  A Rack middleware that maps `/newrelic` to an application for showing
21
19
  detailed performance metrics on a page by page basis. Installed
22
20
  automatically in Rails applications.
23
21
 
24
22
  ## Supported Environments
25
23
 
26
- * Ruby 1.8.6, 1.8.7, REE, 1.9.x, 2.0.x
24
+ * Ruby 1.8.7, REE, 1.9.x, 2.0.x
27
25
  * JRuby 1.6 and 1.7
28
- * Rails 2.0 or later for Production Mode
26
+ * Rubinius 2.x (Experimental support only)
27
+ * Rails 2.1 or later for Production Mode
29
28
  * Rails 2.3 or later for Developer Mode
30
29
  * Sinatra
31
30
  * Rack
32
31
 
32
+ An up to date list of Ruby versions and frameworks for the latest agent
33
+ can be found on [our docs site](http://docs.newrelic.com/docs/ruby/supported-frameworks).
34
+
33
35
  Any Rack based framework should work but may not be tested. Install
34
36
  the Ruby Agent as a gem and add the Developer Mode middleware if
35
37
  desired. Report any problems to support@newrelic.com.
@@ -35,6 +35,8 @@ require 'new_relic/control'
35
35
  # For detailed information on customizing the Ruby Agent
36
36
  # please visit our {support and documentation site}[http://support.newrelic.com].
37
37
  #
38
+ # @api public
39
+ #
38
40
  module NewRelic
39
41
  # == Ruby Agent APIs
40
42
  # This module contains the public API methods for the Ruby Agent.
@@ -61,6 +63,9 @@ module NewRelic
61
63
  # Refer to the online docs at support.newrelic.com to see how to
62
64
  # access the data collected by custom instrumentation, or e-mail
63
65
  # support at New Relic for help.
66
+ #
67
+ # @api public
68
+ #
64
69
  module Agent
65
70
  extend self
66
71
  extend Forwardable
@@ -220,7 +225,12 @@ module NewRelic
220
225
  # Return a NewRelic::Agent::Stats that accepts data
221
226
  # via calls to add_data_point(value).
222
227
  #
228
+ # This method is deprecated in favor of record_metric and increment_metric,
229
+ # and is not thread-safe.
230
+ #
231
+ # @api public
223
232
  # @deprecated
233
+ #
224
234
  def get_stats(metric_name, use_scope=false)
225
235
  agent.stats_engine.get_stats(metric_name, use_scope)
226
236
  end
@@ -242,6 +252,8 @@ module NewRelic
242
252
  # file logger. The setting for the newrelic.yml section to use
243
253
  # (ie, RAILS_ENV) can be overridden with an :env argument.
244
254
  #
255
+ # @api public
256
+ #
245
257
  def manual_start(options={})
246
258
  raise "Options must be a hash" unless Hash === options
247
259
  if options[:start_channel_listener]
@@ -272,6 +284,9 @@ module NewRelic
272
284
  # * <tt>:keep_retrying => false</tt> if we try to initiate a new
273
285
  # connection, this tells me to only try it once so this method returns
274
286
  # quickly if there is some kind of latency with the server.
287
+ #
288
+ # @api public
289
+ #
275
290
  def after_fork(options={})
276
291
  agent.after_fork(options)
277
292
  end
@@ -283,6 +298,9 @@ module NewRelic
283
298
 
284
299
  # Shutdown the agent. Call this before exiting. Sends any queued data
285
300
  # and kills the background thread.
301
+ #
302
+ # @api public
303
+ #
286
304
  def shutdown(options={})
287
305
  agent.shutdown(options)
288
306
  end
@@ -293,6 +311,9 @@ module NewRelic
293
311
  # when the agent is not running it's better to use this method to
294
312
  # register instrumentation than just loading the files directly,
295
313
  # although that probably also works.
314
+ #
315
+ # @api public
316
+ #
296
317
  def add_instrumentation(file_pattern)
297
318
  NewRelic::Control.instance.add_instrumentation file_pattern
298
319
  end
@@ -311,6 +332,8 @@ module NewRelic
311
332
  # my_obfuscator(sql)
312
333
  # end
313
334
  #
335
+ # @api public
336
+ #
314
337
  def set_sql_obfuscator(type = :replace, &block)
315
338
  NewRelic::Agent::Database.set_sql_obfuscator(type, &block)
316
339
  end
@@ -325,6 +348,8 @@ module NewRelic
325
348
  # ...
326
349
  # end
327
350
  #
351
+ # @api public
352
+ #
328
353
  def disable_sql_recording
329
354
  state = agent.set_record_sql(false)
330
355
  begin
@@ -334,25 +359,11 @@ module NewRelic
334
359
  end
335
360
  end
336
361
 
337
-
338
- # Subscribe to events of +event_type+, calling the given +handler+
339
- # when one is sent.
340
- def subscribe(event_type, &handler)
341
- agent.events.subscribe( event_type, &handler )
342
- end
343
-
344
-
345
- # Fire an event of the specified +event_type+, passing it an the given +args+
346
- # to any registered handlers.
347
- def notify(event_type, *args)
348
- agent.events.notify( event_type, *args )
349
- rescue => err
350
- NewRelic::Agent.logger.debug "Ignoring exception during %p event notification" % [event_type]
351
- end
352
-
353
-
354
362
  # This method disables the recording of transaction traces in the given
355
363
  # block. See also #disable_all_tracing
364
+ #
365
+ # @api public
366
+ #
356
367
  def disable_transaction_tracing
357
368
  state = agent.set_record_tt(false)
358
369
  begin
@@ -365,6 +376,9 @@ module NewRelic
365
376
  # Cancel the collection of the current transaction in progress, if
366
377
  # any. Only affects the transaction started on this thread once
367
378
  # it has started and before it has completed.
379
+ #
380
+ # @api public
381
+ #
368
382
  def abort_transaction!
369
383
  Transaction.abort_transaction!
370
384
  end
@@ -374,6 +388,9 @@ module NewRelic
374
388
  # track of the first entry point and turn on tracing again after
375
389
  # leaving that block. This uses the thread local
376
390
  # +newrelic_untrace+
391
+ #
392
+ # @api public
393
+ #
377
394
  def disable_all_tracing
378
395
  agent.push_trace_execution_flag(false)
379
396
  yield
@@ -407,6 +424,8 @@ module NewRelic
407
424
  #
408
425
  # Return the new block or the existing filter Proc if no block is passed.
409
426
  #
427
+ # @api public
428
+ #
410
429
  def ignore_error_filter(&block)
411
430
  agent.error_collector.ignore_error_filter(&block)
412
431
  end
@@ -425,6 +444,8 @@ module NewRelic
425
444
  #
426
445
  # Anything left over is treated as custom params.
427
446
  #
447
+ # @api public
448
+ #
428
449
  def notice_error(exception, options={})
429
450
  Transaction.notice_error(exception, options)
430
451
  nil # don't return a noticed error datastructure. it can only hurt.
@@ -433,6 +454,8 @@ module NewRelic
433
454
  # Add parameters to the current transaction trace (and traced error if any)
434
455
  # on the call stack.
435
456
  #
457
+ # @api public
458
+ #
436
459
  def add_custom_parameters(params)
437
460
  Transaction.add_custom_parameters(params)
438
461
  end
@@ -446,6 +469,8 @@ module NewRelic
446
469
  # * <tt>:account</tt> => account name or ID
447
470
  # * <tt>:product</tt> => product name or level
448
471
  #
472
+ # @api public
473
+ #
449
474
  def set_user_attributes(attributes)
450
475
  Transaction.set_user_attributes(attributes)
451
476
  end
@@ -472,6 +497,7 @@ module NewRelic
472
497
  # The default category is the same as the running transaction.
473
498
  #
474
499
  # @api public
500
+ #
475
501
  def set_transaction_name(name, options={})
476
502
  if Transaction.current
477
503
  namer = Instrumentation::ControllerInstrumentation::TransactionNamer.new(self)
@@ -484,6 +510,7 @@ module NewRelic
484
510
  # want to modify the default name.
485
511
  #
486
512
  # @api public
513
+ #
487
514
  def get_transaction_name
488
515
  if Transaction.current
489
516
  namer = Instrumentation::ControllerInstrumentation::TransactionNamer.new(self)
@@ -503,6 +530,9 @@ module NewRelic
503
530
  # * <tt>model</tt> is the DB model class
504
531
  # * <tt>method</tt> is the name of the finder method or other
505
532
  # method to identify the operation with.
533
+ #
534
+ # @api public
535
+ #
506
536
  def with_database_metric_name(model, method, &block)
507
537
  if txn = Transaction.current
508
538
  txn.with_database_metric_name(model, method, &block)
@@ -537,10 +567,28 @@ module NewRelic
537
567
  # request parameters.
538
568
  # * <tt>'custom_params' => hash</tt> to record extra information in traced errors
539
569
  #
570
+ # @api public
571
+ # @deprecated
572
+ #
540
573
  def record_transaction(response_sec, options = {})
541
574
  agent.record_transaction(response_sec, options)
542
575
  end
543
576
 
577
+ # Subscribe to events of +event_type+, calling the given +handler+
578
+ # when one is sent.
579
+ def subscribe(event_type, &handler)
580
+ agent.events.subscribe( event_type, &handler )
581
+ end
582
+
583
+
584
+ # Fire an event of the specified +event_type+, passing it an the given +args+
585
+ # to any registered handlers.
586
+ def notify(event_type, *args)
587
+ agent.events.notify( event_type, *args )
588
+ rescue => err
589
+ NewRelic::Agent.logger.debug "Ignoring exception during %p event notification" % [event_type]
590
+ end
591
+
544
592
  # Returns a Javascript string which should be injected into the very top of the response body
545
593
  #
546
594
  def browser_timing_header
@@ -48,7 +48,6 @@ module NewRelic
48
48
  @cross_app_monitor = NewRelic::Agent::CrossAppMonitor.new(@events)
49
49
  @error_collector = NewRelic::Agent::ErrorCollector.new
50
50
  @transaction_rules = NewRelic::Agent::RulesEngine.new
51
- @metric_rules = NewRelic::Agent::RulesEngine.new
52
51
  @request_sampler = NewRelic::Agent::RequestSampler.new(@events)
53
52
  @harvest_samplers = NewRelic::Agent::SamplerCollection.new(@events)
54
53
 
@@ -56,7 +55,6 @@ module NewRelic
56
55
  @connect_attempts = 0
57
56
  @environment_report = nil
58
57
 
59
- @last_harvest_time = Time.now
60
58
  @harvest_lock = Mutex.new
61
59
  @obfuscator = lambda {|sql| NewRelic::Agent::Database.default_sql_obfuscator(sql) }
62
60
  end
@@ -106,28 +104,8 @@ module NewRelic
106
104
  # collector on connect. The former are applied during txns,
107
105
  # the latter during harvest.
108
106
  attr_reader :transaction_rules
109
- attr_reader :metric_rules
110
107
  attr_reader :harvest_lock
111
108
 
112
- # Returns the length of the unsent errors array, if it exists,
113
- # otherwise nil
114
- def unsent_errors_size
115
- @unsent_errors.length if @unsent_errors
116
- end
117
-
118
- # Returns the length of the traces array, if it exists,
119
- # otherwise nil
120
- def unsent_traces_size
121
- @traces.length if @traces
122
- end
123
-
124
- # Initializes the unsent timeslice data hash, if needed, and
125
- # returns the number of keys it contains
126
- def unsent_timeslice_data
127
- @unsent_timeslice_data ||= {}
128
- @unsent_timeslice_data.keys.length
129
- end
130
-
131
109
  # fakes out a transaction that did not happen in this process
132
110
  # by creating apdex, summary metrics, and recording statistics
133
111
  # for the transaction
@@ -209,7 +187,7 @@ module NewRelic
209
187
  # Clear out stats that are left over from parent process
210
188
  reset_stats
211
189
 
212
- generate_environment_report
190
+ generate_environment_report unless @service.is_a?(NewRelic::Agent::PipeService)
213
191
  start_worker_thread(options)
214
192
  end
215
193
 
@@ -460,6 +438,7 @@ module NewRelic
460
438
  # before Resque calls Process.daemon (Jira RUBY-857)
461
439
  def defer_for_resque?
462
440
  NewRelic::Agent.config[:dispatcher] == :resque &&
441
+ NewRelic::LanguageSupport.can_fork? &&
463
442
  !NewRelic::Agent::PipeChannelManager.listener.started?
464
443
  end
465
444
 
@@ -524,10 +503,10 @@ module NewRelic
524
503
  # making sure the agent is in a fresh state
525
504
  def reset_stats
526
505
  @stats_engine.reset_stats
527
- @unsent_errors = []
528
- @traces = nil
529
- @unsent_timeslice_data = {}
530
- @last_harvest_time = Time.now
506
+ @error_collector.reset!
507
+ @transaction_sampler.reset!
508
+ @request_sampler.reset!
509
+ @sql_sampler.reset!
531
510
  @launch_time = Time.now
532
511
  end
533
512
 
@@ -810,10 +789,8 @@ module NewRelic
810
789
  Agent.config.apply_config(server_config, 1)
811
790
  log_connection!(config_data) if @service
812
791
 
813
- add_rules_to_engine(config_data['transaction_name_rules'],
814
- NewRelic::Agent.instance.transaction_rules)
815
- add_rules_to_engine(config_data['metric_name_rules'],
816
- NewRelic::Agent.instance.metric_rules)
792
+ @transaction_rules = RulesEngine.from_specs(config_data['transaction_name_rules'])
793
+ @stats_engine.metric_rules = RulesEngine.from_specs(config_data['metric_name_rules'])
817
794
 
818
795
  # If you're adding something else here to respond to the server-side config,
819
796
  # use Agent.instance.events.subscribe(:finished_configuring) callback instead!
@@ -821,13 +798,6 @@ module NewRelic
821
798
  @beacon_configuration = BeaconConfiguration.new
822
799
  end
823
800
 
824
- def add_rules_to_engine(rule_specifications, rules_engine)
825
- return unless rule_specifications && rule_specifications.any?
826
- rule_specifications.each do |rule_spec|
827
- rules_engine << NewRelic::Agent::RulesEngine::Rule.new(rule_spec)
828
- end
829
- end
830
-
831
801
  # Logs when we connect to the server, for debugging purposes
832
802
  # - makes sure we know if an agent has not connected
833
803
  def log_connection!(config_data)
@@ -856,16 +826,10 @@ module NewRelic
856
826
  @stats_engine.merge!(metrics) if metrics
857
827
  if transaction_traces && transaction_traces.respond_to?(:any?) &&
858
828
  transaction_traces.any?
859
- if @traces
860
- @traces += transaction_traces
861
- else
862
- @traces = transaction_traces
863
- end
829
+ @transaction_sampler.merge!(transaction_traces)
864
830
  end
865
831
  if errors && errors.respond_to?(:each)
866
- errors.each do |err|
867
- @error_collector.add_to_error_queue(err)
868
- end
832
+ @error_collector.merge!(errors)
869
833
  end
870
834
  end
871
835
 
@@ -931,44 +895,21 @@ module NewRelic
931
895
 
932
896
  # calls the busy harvester and collects timeslice data to
933
897
  # send later
934
- def harvest_timeslice_data(time=Time.now)
935
- # this creates timeslices that are harvested below
898
+ def harvest_timeslice_data
936
899
  NewRelic::Agent::BusyCalculator.harvest_busy
937
-
938
- @unsent_timeslice_data ||= {}
939
- @unsent_timeslice_data = @stats_engine.harvest_timeslice_data(@unsent_timeslice_data,
940
- @metric_rules)
941
- @unsent_timeslice_data
900
+ @stats_engine.harvest
942
901
  end
943
902
 
944
- # note - exceptions are logged in invoke_remote. If an exception is encountered here,
945
- # then the metric data is downsampled for another
946
- # transmission later
947
903
  def harvest_and_send_timeslice_data
948
- now = Time.now
949
- NewRelic::Agent.record_metric('Supportability/invoke_remote', 0.0)
950
- NewRelic::Agent.record_metric('Supportability/invoke_remote/metric_data', 0.0)
951
- harvest_timeslice_data(now)
904
+ timeslices = harvest_timeslice_data
952
905
  begin
953
- @service.metric_data(@last_harvest_time.to_f,
954
- now.to_f,
955
- @unsent_timeslice_data)
906
+ @service.metric_data(timeslices)
956
907
  rescue UnrecoverableServerException => e
957
908
  ::NewRelic::Agent.logger.debug e.message
909
+ rescue => e
910
+ NewRelic::Agent.logger.info("Failed to send timeslice data, trying again later. Error:", e)
911
+ @stats_engine.merge!(timeslices)
958
912
  end
959
-
960
- ::NewRelic::Agent.logger.debug "#{now}: sent #{@unsent_timeslice_data.length} timeslices (#{@service.agent_id}) in #{Time.now - now} seconds"
961
-
962
- # if we successfully invoked this web service, then clear the unsent message cache.
963
- @unsent_timeslice_data = {}
964
- @last_harvest_time = now
965
- end
966
-
967
- # Fills the traces array with the harvested transactions from
968
- # the transaction sampler, subject to the setting for slowest
969
- # transaction threshold
970
- def harvest_transaction_traces
971
- @traces = @transaction_sampler.harvest(@traces)
972
913
  end
973
914
 
974
915
  def harvest_and_send_slowest_sql
@@ -982,7 +923,7 @@ module NewRelic
982
923
  ::NewRelic::Agent.logger.debug e.message
983
924
  rescue => e
984
925
  ::NewRelic::Agent.logger.debug "Remerging SQL traces after #{e.class.name}: #{e.message}"
985
- @sql_sampler.merge sql_traces
926
+ @sql_sampler.merge!(sql_traces)
986
927
  end
987
928
  end
988
929
  end
@@ -993,28 +934,27 @@ module NewRelic
993
934
  # SQL. note that we explain only the sql statements whose
994
935
  # segments' execution times exceed our threshold (to avoid
995
936
  # unnecessary overhead of running explains on fast queries.)
996
- def harvest_and_send_slowest_sample
997
- harvest_transaction_traces
998
-
999
- unless @traces.empty?
937
+ def harvest_and_send_transaction_traces
938
+ traces = @transaction_sampler.harvest
939
+ unless traces.empty?
1000
940
  begin
1001
- send_slowest_sample
941
+ send_transaction_traces(traces)
1002
942
  rescue UnrecoverableServerException => e
1003
- ::NewRelic::Agent.logger.debug e.message
943
+ # This indicates that there was a problem with the POST body, so
944
+ # we discard the traces rather than trying again later.
945
+ ::NewRelic::Agent.logger.debug("Server rejected transaction traces, discarding. Error: ", e)
946
+ rescue => e
947
+ ::NewRelic::Agent.logger.error("Failed to send transaction traces, will re-attempt next harvest. Error: ", e)
948
+ @transaction_sampler.merge!(traces)
1004
949
  end
1005
950
  end
1006
-
1007
- # if we succeed sending this sample, then we don't need to keep
1008
- # the slowest sample around - it has been sent already and we
1009
- # can clear the collection and move on
1010
- @traces = nil
1011
951
  end
1012
952
 
1013
- def send_slowest_sample
953
+ def send_transaction_traces(traces)
1014
954
  start_time = Time.now
1015
- ::NewRelic::Agent.logger.debug "Sending (#{@traces.length}) transaction traces"
955
+ ::NewRelic::Agent.logger.debug "Sending (#{traces.length}) transaction traces"
1016
956
 
1017
- options = { :keep_backtraces => true }
957
+ options = {}
1018
958
  unless NewRelic::Agent::Database.record_sql_method == :off
1019
959
  options[:record_sql] = NewRelic::Agent::Database.record_sql_method
1020
960
  end
@@ -1023,7 +963,7 @@ module NewRelic
1023
963
  options[:explain_sql] = Agent.config[:'transaction_tracer.explain_threshold']
1024
964
  end
1025
965
 
1026
- traces = @traces.map {|trace| trace.prepare_to_send(options) }
966
+ traces.each { |trace| trace.prepare_to_send!(options) }
1027
967
 
1028
968
  @service.transaction_sample_data(traces)
1029
969
  ::NewRelic::Agent.logger.debug "Sent slowest sample (#{@service.agent_id}) in #{Time.now - start_time} seconds"
@@ -1036,32 +976,21 @@ module NewRelic
1036
976
  end
1037
977
  end
1038
978
 
1039
- # Gets the collection of unsent errors from the error
1040
- # collector. We pass back in an existing array of errors that
1041
- # may be left over from a previous send
1042
- def harvest_errors
1043
- @unsent_errors = @error_collector.harvest_errors(@unsent_errors)
1044
- @unsent_errors
1045
- end
1046
-
1047
979
  # Handles getting the errors from the error collector and
1048
980
  # sending them to the server, and any error cases like trying
1049
- # to send very large errors - we drop the oldest error on the
1050
- # floor and try again
981
+ # to send very large errors
1051
982
  def harvest_and_send_errors
1052
- harvest_errors
1053
- if @unsent_errors && @unsent_errors.length > 0
1054
- ::NewRelic::Agent.logger.debug "Sending #{@unsent_errors.length} errors"
983
+ errors = @error_collector.harvest_errors
984
+ if errors && !errors.empty?
985
+ ::NewRelic::Agent.logger.debug "Sending #{errors.length} errors"
1055
986
  begin
1056
- @service.error_data(@unsent_errors)
987
+ @service.error_data(errors)
1057
988
  rescue UnrecoverableServerException => e
1058
989
  ::NewRelic::Agent.logger.debug e.message
990
+ rescue => e
991
+ ::NewRelic::Agent.logger.debug "Failed to send error traces, will try again later. Error:", e
992
+ @error_collector.merge!(errors)
1059
993
  end
1060
- # if the remote invocation fails, then we never clear
1061
- # @unsent_errors, and therefore we can re-attempt to send on
1062
- # the next heartbeat. Note the error collector maxes out at
1063
- # 20 instances to prevent leakage
1064
- @unsent_errors = []
1065
994
  end
1066
995
  end
1067
996
 
@@ -1071,7 +1000,7 @@ module NewRelic
1071
1000
  begin
1072
1001
  @service.analytic_event_data(samples) unless samples.empty?
1073
1002
  rescue
1074
- @request_sampler.merge(samples)
1003
+ @request_sampler.merge!(samples)
1075
1004
  raise
1076
1005
  end
1077
1006
  end
@@ -1095,7 +1024,7 @@ module NewRelic
1095
1024
  @events.notify(:before_harvest)
1096
1025
  @service.session do # use http keep-alive
1097
1026
  harvest_and_send_errors
1098
- harvest_and_send_slowest_sample
1027
+ harvest_and_send_transaction_traces
1099
1028
  harvest_and_send_slowest_sql
1100
1029
  harvest_and_send_timeslice_data
1101
1030
  harvest_and_send_analytic_event_data