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.
- data.tar.gz.sig +0 -0
- data/.gitignore +1 -0
- data/.yardopts +17 -0
- data/CHANGELOG +48 -0
- data/README.md +8 -6
- data/lib/new_relic/agent.rb +65 -17
- data/lib/new_relic/agent/agent.rb +42 -113
- data/lib/new_relic/agent/browser_monitoring.rb +9 -1
- data/lib/new_relic/agent/configuration/default_source.rb +12 -0
- data/lib/new_relic/agent/error_collector.rb +13 -6
- data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +5 -5
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +15 -0
- data/lib/new_relic/agent/instrumentation/curb.rb +2 -2
- data/lib/new_relic/agent/instrumentation/metric_frame.rb +2 -2
- data/lib/new_relic/agent/instrumentation/rack.rb +2 -0
- data/lib/new_relic/agent/instrumentation/resque.rb +9 -3
- data/lib/new_relic/agent/instrumentation/sidekiq.rb +5 -0
- data/lib/new_relic/agent/method_tracer.rb +45 -27
- data/lib/new_relic/agent/new_relic_service.rb +14 -6
- data/lib/new_relic/agent/pipe_service.rb +1 -1
- data/lib/new_relic/agent/request_sampler.rb +10 -7
- data/lib/new_relic/agent/rules_engine.rb +5 -0
- data/lib/new_relic/agent/samplers/object_sampler.rb +1 -1
- data/lib/new_relic/agent/sql_sampler.rb +4 -2
- data/lib/new_relic/agent/stats_engine.rb +3 -0
- data/lib/new_relic/agent/stats_engine/gc_profiler.rb +17 -7
- data/lib/new_relic/agent/stats_engine/metric_stats.rb +5 -7
- data/lib/new_relic/agent/stats_engine/stats_hash.rb +2 -0
- data/lib/new_relic/agent/supported_versions.rb +247 -0
- data/lib/new_relic/agent/threading/backtrace_service.rb +1 -1
- data/lib/new_relic/agent/threading/thread_profile.rb +2 -1
- data/lib/new_relic/agent/transaction.rb +7 -6
- data/lib/new_relic/agent/transaction/developer_mode_sample_buffer.rb +11 -5
- data/lib/new_relic/agent/transaction/force_persist_sample_buffer.rb +3 -3
- data/lib/new_relic/agent/transaction/slowest_sample_buffer.rb +3 -3
- data/lib/new_relic/agent/transaction/transaction_sample_buffer.rb +23 -4
- data/lib/new_relic/agent/transaction/xray_sample_buffer.rb +4 -4
- data/lib/new_relic/agent/transaction_sampler.rb +14 -18
- data/lib/new_relic/agent/worker_loop.rb +1 -0
- data/lib/new_relic/control.rb +1 -0
- data/lib/new_relic/control/instance_methods.rb +0 -1
- data/lib/new_relic/helper.rb +1 -2
- data/lib/new_relic/language_support.rb +12 -2
- data/lib/new_relic/local_environment.rb +12 -11
- data/lib/new_relic/rack.rb +9 -0
- data/lib/new_relic/rack/agent_hooks.rb +6 -0
- data/lib/new_relic/rack/browser_monitoring.rb +9 -2
- data/lib/new_relic/rack/developer_mode.rb +15 -1
- data/lib/new_relic/rack/error_collector.rb +7 -0
- data/lib/new_relic/recipes.rb +2 -0
- data/lib/new_relic/transaction_sample.rb +39 -48
- data/lib/new_relic/version.rb +1 -1
- data/lib/tasks/install.rake +44 -2
- data/lib/tasks/versions.html.erb +31 -0
- data/lib/tasks/versions.rake +52 -0
- data/lib/tasks/versions.txt.erb +14 -0
- data/newrelic_rpm.gemspec +4 -2
- data/test/agent_helper.rb +21 -1
- data/test/environments/lib/environments/runner.rb +19 -5
- data/test/environments/norails/Gemfile +4 -1
- data/test/environments/rails21/Gemfile +4 -6
- data/test/environments/rails21/Rakefile +4 -0
- data/test/environments/rails21/config/database.yml +2 -7
- data/test/environments/rails22/Gemfile +6 -13
- data/test/environments/rails22/Rakefile +4 -0
- data/test/environments/rails22/config/database.yml +2 -7
- data/test/environments/rails22/config/environment.rb +1 -1
- data/test/environments/rails23/Gemfile +3 -4
- data/test/environments/rails23/Rakefile +4 -0
- data/test/environments/rails23/config/database.yml +2 -7
- data/test/environments/rails30/Gemfile +2 -4
- data/test/environments/rails30/Rakefile +2 -0
- data/test/environments/rails30/config/database.yml +2 -7
- data/test/environments/rails31/Gemfile +2 -4
- data/test/environments/rails31/Rakefile +2 -0
- data/test/environments/rails31/config/database.yml +2 -7
- data/test/environments/rails32/Gemfile +2 -5
- data/test/environments/rails32/Rakefile +2 -0
- data/test/environments/rails32/config/database.yml +1 -1
- data/test/environments/rails40/Gemfile +7 -4
- data/test/environments/rails40/Rakefile +2 -0
- data/test/environments/rails40/config/database.yml +2 -7
- data/test/helpers/runtime_detection.rb +17 -0
- data/test/multiverse/lib/multiverse/suite.rb +20 -4
- data/test/multiverse/suites/agent_only/key_transactions_test.rb +1 -1
- data/test/multiverse/suites/agent_only/marshaling_test.rb +1 -1
- data/test/multiverse/suites/agent_only/thread_profiling_test.rb +32 -7
- data/test/multiverse/suites/agent_only/xray_sessions_test.rb +1 -0
- data/test/multiverse/suites/config_file_loading/config_file_loading_test.rb +4 -3
- data/test/multiverse/suites/curb/curb_test.rb +8 -0
- data/test/multiverse/suites/excon/excon_test.rb +8 -0
- data/test/multiverse/suites/httpclient/httpclient_test.rb +8 -0
- data/test/multiverse/suites/net_http/net_http_test.rb +8 -0
- data/test/multiverse/suites/padrino/Envfile +3 -2
- data/test/multiverse/suites/rails/gc_instrumentation_test.rb +17 -8
- data/test/multiverse/suites/resque/Envfile +3 -3
- data/test/multiverse/suites/resque/instrumentation_test.rb +47 -5
- data/test/multiverse/suites/sequel/Envfile +0 -3
- data/test/multiverse/suites/sequel/database.rb +53 -0
- data/test/{new_relic/agent/instrumentation/sequel_test.rb → multiverse/suites/sequel/sequel_instrumentation_test.rb} +12 -53
- data/test/multiverse/suites/sequel/{sequel_test.rb → sequel_safety_test.rb} +2 -17
- data/test/multiverse/suites/sidekiq/sidekiq_instrumentation_test.rb +50 -5
- data/test/multiverse/suites/sinatra/sinatra_metric_explosion_test.rb +15 -2
- data/test/multiverse/suites/typhoeus/typhoeus_test.rb +8 -0
- data/test/new_relic/agent/agent/connect_test.rb +3 -2
- data/test/new_relic/agent/agent_test.rb +89 -82
- data/test/new_relic/agent/browser_monitoring_test.rb +44 -1
- data/test/new_relic/agent/error_collector_test.rb +17 -20
- data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +13 -10
- data/test/new_relic/agent/instrumentation/active_record_subscriber_test.rb +16 -1
- data/test/new_relic/agent/instrumentation/task_instrumentation_test.rb +2 -2
- data/test/new_relic/agent/method_tracer/instance_methods/trace_execution_scoped_test.rb +1 -1
- data/test/new_relic/agent/new_relic_service_test.rb +78 -9
- data/test/new_relic/agent/pipe_channel_manager_test.rb +7 -9
- data/test/new_relic/agent/pipe_service_test.rb +4 -4
- data/test/new_relic/agent/request_sampler_test.rb +2 -2
- data/test/new_relic/agent/stats_engine/gc_profiler_test.rb +15 -35
- data/test/new_relic/agent/stats_engine/metric_stats_test.rb +15 -7
- data/test/new_relic/agent/stats_engine_test.rb +4 -3
- data/test/new_relic/agent/threading/backtrace_service_test.rb +2 -0
- data/test/new_relic/agent/threading/thread_profile_test.rb +19 -0
- data/test/new_relic/agent/transaction/developer_mode_sample_buffer_test.rb +4 -4
- data/test/new_relic/agent/transaction/force_persist_sample_buffer_test.rb +1 -1
- data/test/new_relic/agent/transaction_sampler_test.rb +60 -45
- data/test/new_relic/fake_collector.rb +37 -2
- data/test/new_relic/http_client_test_cases.rb +26 -1
- data/test/new_relic/language_support_test.rb +12 -31
- data/test/new_relic/local_environment_test.rb +6 -2
- data/test/new_relic/multiverse_helpers.rb +2 -5
- data/test/new_relic/transaction_sample_test.rb +57 -36
- data/test/performance/suites/config.rb +76 -0
- data/test/rum/no_html_and_no_header.result.html +3 -0
- data/test/rum/no_html_and_no_header.source.html +3 -0
- data/test/script/ci.sh +0 -2
- data/test/test_helper.rb +5 -0
- metadata +43 -26
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/.gitignore
CHANGED
data/.yardopts
ADDED
@@ -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
|
-
|
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
|
-
|
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.
|
24
|
+
* Ruby 1.8.7, REE, 1.9.x, 2.0.x
|
27
25
|
* JRuby 1.6 and 1.7
|
28
|
-
*
|
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.
|
data/lib/new_relic/agent.rb
CHANGED
@@ -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
|
-
@
|
528
|
-
@
|
529
|
-
@
|
530
|
-
@
|
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
|
-
|
814
|
-
|
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
|
-
|
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
|
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
|
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
|
-
|
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(
|
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
|
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
|
997
|
-
|
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
|
-
|
941
|
+
send_transaction_traces(traces)
|
1002
942
|
rescue UnrecoverableServerException => e
|
1003
|
-
|
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
|
953
|
+
def send_transaction_traces(traces)
|
1014
954
|
start_time = Time.now
|
1015
|
-
::NewRelic::Agent.logger.debug "Sending (#{
|
955
|
+
::NewRelic::Agent.logger.debug "Sending (#{traces.length}) transaction traces"
|
1016
956
|
|
1017
|
-
options = {
|
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
|
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
|
1050
|
-
# floor and try again
|
981
|
+
# to send very large errors
|
1051
982
|
def harvest_and_send_errors
|
1052
|
-
harvest_errors
|
1053
|
-
if
|
1054
|
-
::NewRelic::Agent.logger.debug "Sending #{
|
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(
|
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
|
-
|
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
|