wd_newrelic_rpm 3.5.5 → 3.5.6
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/CHANGELOG +60 -0
- data/Rakefile +14 -18
- data/gem-public_cert.pem +20 -0
- data/lib/new_relic/agent.rb +3 -0
- data/lib/new_relic/agent/agent.rb +86 -97
- data/lib/new_relic/agent/agent_logger.rb +9 -1
- data/lib/new_relic/agent/busy_calculator.rb +5 -0
- data/lib/new_relic/agent/configuration/defaults.rb +3 -3
- data/lib/new_relic/agent/configuration/manager.rb +12 -0
- data/lib/new_relic/agent/configuration/mask_defaults.rb +1 -0
- data/lib/new_relic/agent/configuration/yaml_source.rb +5 -1
- data/lib/new_relic/agent/cross_process_monitoring.rb +164 -20
- data/lib/new_relic/agent/error_collector.rb +13 -2
- data/lib/new_relic/agent/event_listener.rb +39 -0
- data/lib/new_relic/agent/instrumentation/browser_monitoring_timings.rb +18 -8
- data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +1 -1
- data/lib/new_relic/agent/instrumentation/sinatra.rb +8 -1
- data/lib/new_relic/agent/new_relic_service.rb +90 -10
- data/lib/new_relic/agent/pipe_service.rb +9 -0
- data/lib/new_relic/agent/sql_sampler.rb +10 -3
- data/lib/new_relic/agent/stats_engine/transactions.rb +1 -0
- data/lib/new_relic/agent/thread_profiler.rb +20 -7
- data/lib/new_relic/agent/worker_loop.rb +2 -1
- data/lib/new_relic/coerce.rb +37 -0
- data/lib/new_relic/commands/deployments.rb +1 -1
- data/lib/new_relic/control/frameworks/rails.rb +29 -5
- data/lib/new_relic/control/frameworks/rails3.rb +2 -11
- data/lib/new_relic/control/instance_methods.rb +11 -7
- data/lib/new_relic/control/server_methods.rb +5 -37
- data/lib/new_relic/latest_changes.rb +31 -0
- data/lib/new_relic/local_environment.rb +1 -1
- data/lib/new_relic/metric_data.rb +13 -2
- data/lib/new_relic/noticed_error.rb +8 -1
- data/lib/new_relic/rack/agent_hooks.rb +20 -0
- data/lib/new_relic/rack/error_collector.rb +11 -1
- data/lib/new_relic/recipes.rb +32 -10
- data/lib/new_relic/transaction_sample.rb +12 -3
- data/lib/new_relic/transaction_sample/segment.rb +6 -3
- data/lib/new_relic/version.rb +10 -15
- data/newrelic.yml +12 -19
- data/newrelic_rpm.gemspec +22 -464
- data/test/multiverse/.gitignore +1 -0
- data/test/multiverse/lib/multiverse/environment.rb +1 -1
- data/test/multiverse/lib/multiverse/suite.rb +2 -0
- data/test/multiverse/suites/active_record/Envfile +3 -3
- data/test/multiverse/suites/active_record/ar_method_aliasing.rb +1 -1
- data/test/multiverse/suites/active_record/config/newrelic.yml +2 -2
- data/test/multiverse/suites/agent_only/Envfile +2 -1
- data/test/multiverse/suites/agent_only/config/newrelic.yml +3 -1
- data/test/multiverse/suites/agent_only/cross_process_test.rb +56 -0
- data/test/multiverse/suites/{logging → agent_only}/logging_test.rb +42 -22
- data/test/multiverse/suites/agent_only/no_dns_resolv.rb +17 -0
- data/test/multiverse/suites/{rum_auto_instrumentation/sanity_test.rb → agent_only/rum_instrumentation_test.rb} +25 -46
- data/test/multiverse/suites/agent_only/service_timeout_test.rb +6 -3
- data/test/multiverse/suites/agent_only/ssl_test.rb +22 -0
- data/test/multiverse/suites/{no_load → agent_only}/start_up_test.rb +9 -2
- data/test/multiverse/suites/agent_only/testing_app.rb +17 -0
- data/test/multiverse/suites/agent_only/thread_profiling_test.rb +6 -5
- data/test/multiverse/suites/datamapper/config/newrelic.yml +1 -1
- data/test/multiverse/suites/{rails_3_queue_time → rails}/Envfile +3 -0
- data/test/multiverse/suites/rails/app.rb +49 -0
- data/test/multiverse/suites/{rails_3_views → rails}/app/views/foos/_foo.html.haml +0 -0
- data/test/multiverse/suites/{rails_3_views/app/views/test → rails/app/views/views}/_a_partial.html.erb +0 -0
- data/test/multiverse/suites/{rails_3_views/app/views/test → rails/app/views/views}/_mid_partial.html.erb +0 -0
- data/test/multiverse/suites/{rails_3_views/app/views/test → rails/app/views/views}/_top_partial.html.erb +0 -0
- data/test/multiverse/suites/{rails_3_views/app/views/test → rails/app/views/views}/deep_partial.html.erb +0 -0
- data/test/multiverse/suites/{rails_3_views/app/views/test → rails/app/views/views}/haml_view.html.haml +0 -0
- data/test/multiverse/suites/{rails_3_views/app/views/test → rails/app/views/views}/index.html.erb +0 -0
- data/test/multiverse/suites/rails/config/newrelic.yml +32 -0
- data/test/multiverse/suites/{rails_3_error_tracing → rails}/error_tracing_test.rb +51 -88
- data/test/multiverse/suites/rails/gc_instrumentation_test.rb +79 -0
- data/test/multiverse/suites/{rails_3_queue_time → rails}/queue_time_test.rb +3 -23
- data/test/multiverse/suites/{rails_3_views → rails}/view_instrumentation_test.rb +21 -61
- data/test/multiverse/suites/resque/Envfile +7 -4
- data/test/multiverse/suites/resque/Rakefile +8 -0
- data/test/multiverse/suites/resque/config/newrelic.yml +1 -1
- data/test/multiverse/suites/resque/instrumentation_test.rb +118 -41
- data/test/multiverse/suites/resque/resque_setup.rb +15 -0
- data/test/multiverse/suites/sinatra/config/newrelic.yml +1 -2
- data/test/multiverse/suites/sinatra/sinatra_error_tracing_test.rb +38 -0
- data/test/multiverse/suites/sinatra/sinatra_test.rb +17 -0
- data/test/multiverse/test/suite_examples/one/a/config/newrelic.yml +1 -1
- data/test/multiverse/test/suite_examples/one/b/config/newrelic.yml +1 -1
- data/test/new_relic/agent/agent/connect_test.rb +24 -100
- data/test/new_relic/agent/agent/start_worker_thread_test.rb +3 -3
- data/test/new_relic/agent/agent_test.rb +126 -31
- data/test/new_relic/agent/browser_monitoring_test.rb +1 -1
- data/test/new_relic/agent/busy_calculator_test.rb +8 -0
- data/test/new_relic/agent/configuration/manager_test.rb +28 -0
- data/test/new_relic/agent/configuration/yaml_source_test.rb +12 -2
- data/test/new_relic/agent/cross_process_monitoring_test.rb +144 -31
- data/test/new_relic/agent/error_collector_test.rb +16 -0
- data/test/new_relic/agent/event_listener_test.rb +46 -0
- data/test/new_relic/agent/instrumentation/browser_monitoring_timings_test.rb +57 -30
- data/test/new_relic/agent/instrumentation/task_instrumentation_test.rb +1 -0
- data/test/new_relic/agent/new_relic_service_test.rb +95 -2
- data/test/new_relic/agent/pipe_channel_manager_test.rb +3 -3
- data/test/new_relic/agent/pipe_service_test.rb +21 -1
- data/test/new_relic/agent/rpm_agent_test.rb +1 -1
- data/test/new_relic/agent/sql_sampler_test.rb +20 -0
- data/test/new_relic/agent/thread_profiler_test.rb +53 -8
- data/test/new_relic/agent/worker_loop_test.rb +19 -16
- data/test/new_relic/agent_test.rb +1 -2
- data/test/new_relic/coerce_test.rb +65 -0
- data/test/new_relic/command/deployments_test.rb +1 -1
- data/test/new_relic/control_test.rb +23 -44
- data/test/new_relic/fake_collector.rb +34 -6
- data/test/new_relic/local_environment_test.rb +1 -1
- data/test/new_relic/metric_data_test.rb +29 -0
- data/test/new_relic/noticed_error_test.rb +8 -0
- data/test/new_relic/rack/agent_hooks_test.rb +30 -0
- data/test/new_relic/rack/error_collector_test.rb +16 -0
- data/test/new_relic/transaction_sample/segment_test.rb +7 -0
- data/test/new_relic/transaction_sample_test.rb +36 -8
- data/test/new_relic/version_number_test.rb +6 -30
- data/test/script/ci.sh +6 -5
- data/test/test_contexts.rb +2 -1
- data/test/test_helper.rb +23 -6
- data/ui/helpers/google_pie_chart.rb +1 -0
- metadata +68 -67
- data/newrelic_rpm.gemspec.erb +0 -54
- data/test/fixtures/gemspec_no_build.rb +0 -442
- data/test/fixtures/gemspec_with_build.rb +0 -442
- data/test/fixtures/gemspec_with_build_and_stage.rb +0 -442
- data/test/multiverse/suites/logging/Envfile +0 -4
- data/test/multiverse/suites/logging/config/newrelic.yml +0 -22
- data/test/multiverse/suites/monitor_mode_false/Envfile +0 -2
- data/test/multiverse/suites/monitor_mode_false/config/newrelic.yml +0 -25
- data/test/multiverse/suites/monitor_mode_false/no_dns_resolv.rb +0 -29
- data/test/multiverse/suites/no_load/Envfile +0 -2
- data/test/multiverse/suites/no_load/config/newrelic.yml +0 -22
- data/test/multiverse/suites/rails_3_error_tracing/Envfile +0 -15
- data/test/multiverse/suites/rails_3_error_tracing/config/newrelic.yml +0 -165
- data/test/multiverse/suites/rails_3_gc/Envfile +0 -8
- data/test/multiverse/suites/rails_3_gc/config/newrelic.yml +0 -167
- data/test/multiverse/suites/rails_3_gc/instrumentation_test.rb +0 -92
- data/test/multiverse/suites/rails_3_queue_time/config/newrelic.yml +0 -165
- data/test/multiverse/suites/rails_3_views/.gitignore +0 -3
- data/test/multiverse/suites/rails_3_views/Envfile +0 -16
- data/test/multiverse/suites/rails_3_views/config/newrelic.yml +0 -164
- data/test/multiverse/suites/resque/dump.rdb +0 -0
- data/test/multiverse/suites/rum_auto_instrumentation/Envfile +0 -4
- data/test/multiverse/suites/rum_auto_instrumentation/config/newrelic.yml +0 -24
- data/test/multiverse/suites/rum_auto_instrumentation/responses/worst_case_small.html +0 -5000
- data/test/new_relic/fake_service.rb +0 -53
data/.gitignore
CHANGED
data/CHANGELOG
CHANGED
@@ -1,6 +1,66 @@
|
|
1
1
|
|
2
2
|
# New Relic Ruby Agent Release Notes #
|
3
3
|
|
4
|
+
## v3.5.6 ##
|
5
|
+
|
6
|
+
* Use HTTPS by default
|
7
|
+
|
8
|
+
The agent now defaults to using SSL when it communicates with New Relic's
|
9
|
+
servers. By defaults already configured, New Relic does not transmit any
|
10
|
+
sensitive information (e.g. SQL parameters are masked), but SSL adds
|
11
|
+
another layer of security. Upgrading customers may need to remove the
|
12
|
+
"ssl: false" directive from their newrelic.yml to enable ssl. Customers on
|
13
|
+
Jruby may need to install the jruby-openssl gem to take advantage of this
|
14
|
+
feature.
|
15
|
+
|
16
|
+
* Fix two Resque-related issues
|
17
|
+
|
18
|
+
Fixes a possible hang on exit of an instrumented Resque master process
|
19
|
+
(https://github.com/defunkt/resque/issues/578), as well as a file descriptor
|
20
|
+
leak that could occur during startup of the Resque master process.
|
21
|
+
|
22
|
+
* Fix for error graph over 100%
|
23
|
+
|
24
|
+
Some errors were double counted toward the overall error total. This
|
25
|
+
resulted in graphs with error percentages over 100%. This duplication did
|
26
|
+
not impact the specific error traces captured, only the total metric.
|
27
|
+
|
28
|
+
* Notice gracefully handled errors in Sinatra
|
29
|
+
|
30
|
+
When show_exceptions was set to false in Sinatra, errors weren't caught
|
31
|
+
by New Relic's error collector. Now handled errors also have the chance
|
32
|
+
to get reported back.
|
33
|
+
|
34
|
+
* Ruby 2.0 compatibility fixes
|
35
|
+
|
36
|
+
Ruby 2.0 no longer finds protected methods by default, but will with a flag.
|
37
|
+
http://tenderlovemaking.com/2012/09/07/protected-methods-and-ruby-2-0.html
|
38
|
+
|
39
|
+
Thanks Ravil Bayramgalin and Charlie Somerville for the fixes.
|
40
|
+
|
41
|
+
* Auto-detect Trinidad as dispatcher
|
42
|
+
|
43
|
+
Code already existing for detecting Trinidad as a dispatcher, but was only
|
44
|
+
accessible via an ENV variable. This now auto-detects on startup. Thanks
|
45
|
+
Robert Rasmussen for catching that.
|
46
|
+
|
47
|
+
* Coercion of types in collector communication
|
48
|
+
|
49
|
+
Certain metrics can be recorded with a Ruby Rational type, which JSON
|
50
|
+
serializes as a string rather than a floating point value. We now treat
|
51
|
+
coerce each outgoing value, and log issues before sending the data.
|
52
|
+
|
53
|
+
* Developer mode fix for chart error
|
54
|
+
|
55
|
+
Added require to fix a NameError in developer mode for summary page. Thanks
|
56
|
+
to Ryan B. Harvey.
|
57
|
+
|
58
|
+
* Don't touch deprecated RAILS_ROOT if on Rails 3
|
59
|
+
|
60
|
+
Under some odd startup conditions, we would look for the RAILS_ROOT constant
|
61
|
+
after failing to find the ::Rails.root in a Rails 3 app, causing deprecation
|
62
|
+
warnings. Thanks for Adrian Irving-Beer for the fix.
|
63
|
+
|
4
64
|
## v3.5.5 ##
|
5
65
|
|
6
66
|
* Add thread profiling support
|
data/Rakefile
CHANGED
@@ -5,7 +5,7 @@ require "#{File.dirname(__FILE__)}/lib/tasks/all.rb"
|
|
5
5
|
|
6
6
|
task :default => :test
|
7
7
|
|
8
|
-
task :test => [
|
8
|
+
task :test => ['test:newrelic']
|
9
9
|
|
10
10
|
namespace :test do
|
11
11
|
desc "Run all tests"
|
@@ -14,7 +14,7 @@ namespace :test do
|
|
14
14
|
agent_home = File.expand_path(File.dirname(__FILE__))
|
15
15
|
|
16
16
|
desc "Run functional test suite for newrelic"
|
17
|
-
task :multiverse, [:suite, :mode] => [
|
17
|
+
task :multiverse, [:suite, :mode] => [] do |t, args|
|
18
18
|
args.with_defaults(:suite => "", :mode => "")
|
19
19
|
if args.mode == "run_one"
|
20
20
|
puts `#{agent_home}/test/multiverse/script/run_one #{args.suite}`
|
@@ -24,7 +24,7 @@ namespace :test do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
desc "Test the multiverse testing framework by executing tests in test/multiverse/test. Get meta with it."
|
27
|
-
task 'multiverse:self', [:suite, :mode] => [
|
27
|
+
task 'multiverse:self', [:suite, :mode] => [] do |t, args|
|
28
28
|
args.with_defaults(:suite => "", :mode => "")
|
29
29
|
puts ("Testing the multiverse testing framework...")
|
30
30
|
test_files = FileList['test/multiverse/test/*_test.rb']
|
@@ -43,20 +43,16 @@ namespace :test do
|
|
43
43
|
|
44
44
|
end
|
45
45
|
|
46
|
-
desc '
|
47
|
-
task :
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
template = ERB.new(File.read('newrelic_rpm.gemspec.erb'))
|
59
|
-
File.open('newrelic_rpm.gemspec', 'w') do |gemspec|
|
60
|
-
gemspec.write(template.result(binding))
|
46
|
+
desc 'Record build number and stage'
|
47
|
+
task :record_build, [ :build_number, :stage ] do |t, args|
|
48
|
+
build_string = args.build_number
|
49
|
+
build_string << ".#{args.stage}" if args.stage
|
50
|
+
|
51
|
+
gitsha = File.exists?(".git") ? `git rev-parse HEAD` : "Unknown"
|
52
|
+
gitsha.chomp!
|
53
|
+
|
54
|
+
File.open("lib/new_relic/build.rb", "w") do |f|
|
55
|
+
f.write("# GITSHA: #{gitsha}\n")
|
56
|
+
f.write("module NewRelic; module VERSION; BUILD='#{build_string}'; end; end\n")
|
61
57
|
end
|
62
58
|
end
|
data/gem-public_cert.pem
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIDODCCAiCgAwIBAgIBADANBgkqhkiG9w0BAQUFADBCMREwDwYDVQQDDAhzZWN1
|
3
|
+
cml0eTEYMBYGCgmSJomT8ixkARkWCG5ld3JlbGljMRMwEQYKCZImiZPyLGQBGRYD
|
4
|
+
Y29tMB4XDTEzMDIxMjE5MDcwN1oXDTE0MDIxMjE5MDcwN1owQjERMA8GA1UEAwwI
|
5
|
+
c2VjdXJpdHkxGDAWBgoJkiaJk/IsZAEZFghuZXdyZWxpYzETMBEGCgmSJomT8ixk
|
6
|
+
ARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJyYRvlk1XUo
|
7
|
+
8JhWQcE/v6RmpK//JbeKvTKnmWVUKz5oTDSOg/LKEhzChpJJVSOMJHCxd4OoxkIN
|
8
|
+
pjQF5U2af1m5ONeN1j4p4MujbwNeqxsJmixGLK/BZ9xTnbpYAa6xCRN1UfEcu3O9
|
9
|
+
jjLHX3c63ghldwRBn/c2ZD6anMtDeq3C5MLiycFs9h7JXOa3cTTHLZknkYIoHMKN
|
10
|
+
EFri5zlks50lbeaVvFRm4IMrYWRsEwzLZWaMOy68BVZe0UlBBKSMnzJfWkbdRRcm
|
11
|
+
xqu7viu4hrrCGjUmdHKnl6tf7BY7wqQyKjj+O5DhayKmKRuQcEX8QVnsM+ayqiVU
|
12
|
+
EtMiwNScUnsCAwEAAaM5MDcwCQYDVR0TBAIwADAdBgNVHQ4EFgQUOauaMsU0Elp6
|
13
|
+
hiUisj4l63ZunSUwCwYDVR0PBAQDAgSwMA0GCSqGSIb3DQEBBQUAA4IBAQAuwrHh
|
14
|
+
jOjIfAQoEbGakiwHTeImqmC1EjBEWb1+U+rC2OcsSQ3+2Q0mGq2u3lAphAeLa6i5
|
15
|
+
WXb5OdQqZY2aI7NgMxRG98/+TcIlAT8tDR0e6/+QBlBuDXP3YI5Nuhp5U4LEvghr
|
16
|
+
jEPaEo0AFPc1JpSO/zKmktU+e9VRAE+q55gLthP8fe0uZvtGUn0KgDbXJyOuGlHF
|
17
|
+
J93N937OcyA2rD8gR1qkr3/0/we1dwLZnL6kN4p8nGzPgXZgOHsmTdYZ2ryYowtb
|
18
|
+
Kc9+v+QxnbZYpu2IaPXOvm3T8G4O6qZvhnLh/Uien++Dj8eFBecTPoM8pVjK3ph5
|
19
|
+
n/EwuZCcE6ghtCCM
|
20
|
+
-----END CERTIFICATE-----
|
data/lib/new_relic/agent.rb
CHANGED
@@ -123,6 +123,9 @@ module NewRelic
|
|
123
123
|
# drop it and not try to resend
|
124
124
|
class UnrecoverableServerException < ServerConnectionException; end
|
125
125
|
|
126
|
+
# An unrecoverable client-side error that prevents the agent from continuing
|
127
|
+
class UnrecoverableAgentException < ServerConnectionException; end
|
128
|
+
|
126
129
|
# Reserved for future use. Meant to represent a problem on the server side.
|
127
130
|
class ServerError < StandardError; end
|
128
131
|
|
@@ -24,11 +24,15 @@ module NewRelic
|
|
24
24
|
@launch_time = Time.now
|
25
25
|
|
26
26
|
@metric_ids = {}
|
27
|
+
@events = NewRelic::Agent::EventListener.new
|
27
28
|
@stats_engine = NewRelic::Agent::StatsEngine.new
|
28
29
|
@transaction_sampler = NewRelic::Agent::TransactionSampler.new
|
29
30
|
@sql_sampler = NewRelic::Agent::SqlSampler.new
|
30
31
|
@thread_profiler = NewRelic::Agent::ThreadProfiler.new
|
32
|
+
@cross_process_monitor = NewRelic::Agent::CrossProcessMonitor.new(@events)
|
31
33
|
@error_collector = NewRelic::Agent::ErrorCollector.new
|
34
|
+
|
35
|
+
@connect_state = :pending
|
32
36
|
@connect_attempts = 0
|
33
37
|
|
34
38
|
@last_harvest_time = Time.now
|
@@ -94,6 +98,10 @@ module NewRelic
|
|
94
98
|
attr_reader :cross_process_encoding_bytes
|
95
99
|
# service for communicating with collector
|
96
100
|
attr_accessor :service
|
101
|
+
# Global events dispatcher. This will provides our primary mechanism
|
102
|
+
# for agent-wide events, such as finishing configuration, error notification
|
103
|
+
# and request before/after from Rack.
|
104
|
+
attr_reader :events
|
97
105
|
|
98
106
|
|
99
107
|
# Returns the length of the unsent errors array, if it exists,
|
@@ -175,19 +183,21 @@ module NewRelic
|
|
175
183
|
@forked = true
|
176
184
|
Agent.config.apply_config(NewRelic::Agent::Configuration::ManualSource.new(options), 1)
|
177
185
|
|
178
|
-
# @connected gets false after we fail to connect or have an error
|
179
|
-
# connecting. @connected has nil if we haven't finished trying to connect.
|
180
|
-
# or we didn't attempt a connection because this is the master process
|
181
|
-
|
182
186
|
if channel_id = options[:report_to_channel]
|
183
187
|
@service = NewRelic::Agent::PipeService.new(channel_id)
|
184
|
-
|
185
|
-
|
188
|
+
if connected?
|
189
|
+
@connected_pid = $$
|
190
|
+
@metric_ids = {}
|
191
|
+
else
|
192
|
+
::NewRelic::Agent.logger.debug("Child process #{$$} not reporting to non-connected parent.")
|
193
|
+
@service.shutdown(Time.now)
|
194
|
+
disconnect
|
195
|
+
end
|
186
196
|
end
|
187
197
|
|
188
198
|
return if !Agent.config[:agent_enabled] ||
|
189
199
|
!Agent.config[:monitor_mode] ||
|
190
|
-
|
200
|
+
disconnected? ||
|
191
201
|
@worker_thread && @worker_thread.alive?
|
192
202
|
|
193
203
|
::NewRelic::Agent.logger.debug "Starting the worker thread in #{$$} after forking."
|
@@ -210,18 +220,11 @@ module NewRelic
|
|
210
220
|
@started
|
211
221
|
end
|
212
222
|
|
213
|
-
# Return nil if not yet connected, true if successfully started
|
214
|
-
# and false if we failed to start.
|
215
|
-
def connected?
|
216
|
-
@connected
|
217
|
-
end
|
218
|
-
|
219
223
|
# Attempt a graceful shutdown of the agent, running the worker
|
220
224
|
# loop if it exists and is running.
|
221
225
|
#
|
222
226
|
# Options:
|
223
|
-
# :force_send
|
224
|
-
# before shutting down
|
227
|
+
# :force_send => (true/false) # force the agent to send data
|
225
228
|
def shutdown(options={})
|
226
229
|
run_loop_before_exit = Agent.config[:force_send]
|
227
230
|
return if not started?
|
@@ -234,7 +237,6 @@ module NewRelic
|
|
234
237
|
|
235
238
|
# if litespeed, then ignore all future SIGUSR1 - it's
|
236
239
|
# litespeed trying to shut us down
|
237
|
-
|
238
240
|
if Agent.config[:dispatcher] == :litespeed
|
239
241
|
Signal.trap("SIGUSR1", "IGNORE")
|
240
242
|
Signal.trap("SIGTERM", "IGNORE")
|
@@ -454,6 +456,14 @@ module NewRelic
|
|
454
456
|
:info, "Connecting workers after forking.")
|
455
457
|
end
|
456
458
|
|
459
|
+
# Return true if we're using resque and it hasn't had a chance to (potentially)
|
460
|
+
# daemonize itself. This avoids hanging when there's a Thread started
|
461
|
+
# before Resque calls Process.daemon (Jira RUBY-857)
|
462
|
+
def defer_for_resque?
|
463
|
+
NewRelic::Agent.config[:dispatcher] == :resque &&
|
464
|
+
!NewRelic::Agent::PipeChannelManager.listener.started?
|
465
|
+
end
|
466
|
+
|
457
467
|
# Sanity-check the agent configuration and start the agent,
|
458
468
|
# setting up the worker thread and the exit handler to shut
|
459
469
|
# down the agent
|
@@ -471,6 +481,12 @@ module NewRelic
|
|
471
481
|
# Logs a bunch of data and starts the agent, if needed
|
472
482
|
def start
|
473
483
|
return if already_started? || disabled?
|
484
|
+
|
485
|
+
if defer_for_resque?
|
486
|
+
::NewRelic::Agent.logger.debug "Deferring startup for Resque in case it daemonizes"
|
487
|
+
return
|
488
|
+
end
|
489
|
+
|
474
490
|
@started = true
|
475
491
|
@local_host = determine_host
|
476
492
|
log_startup
|
@@ -518,7 +534,7 @@ module NewRelic
|
|
518
534
|
::NewRelic::Agent.logger.debug error.message
|
519
535
|
reset_stats
|
520
536
|
@metric_ids = {}
|
521
|
-
@
|
537
|
+
@connect_state = :pending
|
522
538
|
sleep 30
|
523
539
|
end
|
524
540
|
|
@@ -577,7 +593,7 @@ module NewRelic
|
|
577
593
|
# just exit the thread. If it returns nil
|
578
594
|
# that means it didn't try to connect because we're in the master.
|
579
595
|
connect(connection_options)
|
580
|
-
if
|
596
|
+
if connected?
|
581
597
|
log_worker_loop_start
|
582
598
|
create_and_run_worker_loop
|
583
599
|
# never reaches here unless there is a problem or
|
@@ -610,60 +626,41 @@ module NewRelic
|
|
610
626
|
# method - all of its methods are used in that context, so it
|
611
627
|
# can be refactored at will. It should be fully tested
|
612
628
|
module Connect
|
613
|
-
# the frequency with which we should try to connect to the
|
614
|
-
# server at the moment.
|
615
|
-
attr_accessor :connect_retry_period
|
616
629
|
# number of attempts we've made to contact the server
|
617
630
|
attr_accessor :connect_attempts
|
618
631
|
|
619
632
|
# Disconnect just sets connected to false, which prevents
|
620
633
|
# the agent from trying to connect again
|
621
634
|
def disconnect
|
622
|
-
@
|
635
|
+
@connect_state = :disconnected
|
623
636
|
true
|
624
637
|
end
|
625
638
|
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
639
|
+
def connected?
|
640
|
+
@connect_state == :connected
|
641
|
+
end
|
642
|
+
|
643
|
+
def disconnected?
|
644
|
+
@connect_state == :disconnected
|
631
645
|
end
|
632
646
|
|
633
|
-
#
|
634
|
-
#
|
635
|
-
|
636
|
-
|
647
|
+
# Don't connect if we're already connected, or if we tried to connect
|
648
|
+
# and were rejected with prejudice because of a license issue, unless
|
649
|
+
# we're forced to by force_reconnect.
|
650
|
+
def should_connect?(force=false)
|
651
|
+
force || (!connected? && !disconnected?)
|
637
652
|
end
|
638
653
|
|
639
654
|
# Retry period is a minute for each failed attempt that
|
640
655
|
# we've made. This should probably do some sort of sane TCP
|
641
656
|
# backoff to prevent hammering the server, but a minute for
|
642
657
|
# each attempt seems to work reasonably well.
|
643
|
-
def
|
644
|
-
|
645
|
-
connect_attempts * 60
|
646
|
-
end
|
647
|
-
|
648
|
-
def increment_retry_period! #:nodoc:
|
649
|
-
self.connect_retry_period=(get_retry_period)
|
658
|
+
def connect_retry_period
|
659
|
+
[600, connect_attempts * 60].min
|
650
660
|
end
|
651
661
|
|
652
|
-
|
653
|
-
|
654
|
-
# connect attempts and the retry period, to prevent constant
|
655
|
-
# connection attempts, and tell the user what we're doing by
|
656
|
-
# logging.
|
657
|
-
def should_retry?
|
658
|
-
if @keep_retrying
|
659
|
-
self.connect_attempts=(connect_attempts + 1)
|
660
|
-
increment_retry_period!
|
661
|
-
::NewRelic::Agent.logger.warn "Will re-attempt in #{connect_retry_period} seconds"
|
662
|
-
true
|
663
|
-
else
|
664
|
-
disconnect
|
665
|
-
false
|
666
|
-
end
|
662
|
+
def note_connect_failure
|
663
|
+
self.connect_attempts += 1
|
667
664
|
end
|
668
665
|
|
669
666
|
# When we have a problem connecting to the server, we need
|
@@ -687,6 +684,12 @@ module NewRelic
|
|
687
684
|
disconnect
|
688
685
|
end
|
689
686
|
|
687
|
+
def handle_unrecoverable_agent_error(error)
|
688
|
+
::NewRelic::Agent.logger.error(error.message)
|
689
|
+
disconnect
|
690
|
+
shutdown
|
691
|
+
end
|
692
|
+
|
690
693
|
# Checks whether we should send environment info, and if so,
|
691
694
|
# returns the snapshot from the local environment
|
692
695
|
def environment_for_connect
|
@@ -744,24 +747,12 @@ module NewRelic
|
|
744
747
|
Agent.config.apply_config(server_config, 1)
|
745
748
|
log_connection!(config_data) if @service
|
746
749
|
|
747
|
-
|
748
|
-
|
749
|
-
@cross_process_encoding_bytes = get_bytes(@cross_process_encoding_key) unless @cross_process_encoding_key.nil?
|
750
|
+
# If you're adding something else here to respond to the server-side config,
|
751
|
+
# use Agent.instance.events.subscribe(:finished_configuring) callback instead!
|
750
752
|
|
751
753
|
@beacon_configuration = BeaconConfiguration.new
|
752
754
|
end
|
753
755
|
|
754
|
-
# Ruby 1.8.6 doesn't support the bytes method on strings.
|
755
|
-
def get_bytes(value)
|
756
|
-
return [] if value.nil?
|
757
|
-
|
758
|
-
bytes = []
|
759
|
-
value.each_byte do |b|
|
760
|
-
bytes << b
|
761
|
-
end
|
762
|
-
bytes
|
763
|
-
end
|
764
|
-
|
765
756
|
# Logs when we connect to the server, for debugging purposes
|
766
757
|
# - makes sure we know if an agent has not connected
|
767
758
|
def log_connection!(config_data)
|
@@ -813,11 +804,9 @@ module NewRelic
|
|
813
804
|
@traces = transaction_traces
|
814
805
|
end
|
815
806
|
end
|
816
|
-
if errors && errors.respond_to?(:
|
817
|
-
|
818
|
-
@
|
819
|
-
else
|
820
|
-
@unsent_errors = errors
|
807
|
+
if errors && errors.respond_to?(:each)
|
808
|
+
errors.each do |err|
|
809
|
+
@error_collector.add_to_error_queue(err)
|
821
810
|
end
|
822
811
|
end
|
823
812
|
end
|
@@ -825,7 +814,7 @@ module NewRelic
|
|
825
814
|
public :merge_data_from
|
826
815
|
|
827
816
|
# Connect to the server and validate the license. If successful,
|
828
|
-
#
|
817
|
+
# connected? returns true when finished. If not successful, you can
|
829
818
|
# keep calling this. Return false if we could not establish a
|
830
819
|
# connection with the server and we should not retry, such as if
|
831
820
|
# there's a bad license key.
|
@@ -840,25 +829,29 @@ module NewRelic
|
|
840
829
|
# * <tt>force_reconnect => true</tt> if you want to establish a new connection
|
841
830
|
# to the server before running the worker loop. This means you get a separate
|
842
831
|
# agent run and New Relic sees it as a separate instance (default is false).
|
843
|
-
def connect(options)
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
832
|
+
def connect(options={})
|
833
|
+
defaults = {
|
834
|
+
:keep_retrying => true,
|
835
|
+
:force_reconnect => false
|
836
|
+
}
|
837
|
+
opts = defaults.merge(options)
|
848
838
|
|
849
|
-
|
850
|
-
@connect_retry_period = should_keep_retrying?(options) ? 10 : 0
|
839
|
+
return unless should_connect?(opts[:force_reconnect])
|
851
840
|
|
852
|
-
sleep connect_retry_period
|
853
841
|
::NewRelic::Agent.logger.debug "Connecting Process to New Relic: #$0"
|
854
842
|
query_server_for_configuration
|
855
843
|
@connected_pid = $$
|
856
|
-
@
|
844
|
+
@connect_state = :connected
|
857
845
|
rescue NewRelic::Agent::LicenseException => e
|
858
846
|
handle_license_error(e)
|
847
|
+
rescue NewRelic::Agent::UnrecoverableAgentException => e
|
848
|
+
handle_unrecoverable_agent_error(e)
|
859
849
|
rescue Timeout::Error, StandardError => e
|
860
850
|
log_error(e)
|
861
|
-
if
|
851
|
+
if opts[:keep_retrying]
|
852
|
+
note_connect_failure
|
853
|
+
::NewRelic::Agent.logger.warn "Will re-attempt in #{connect_retry_period} seconds"
|
854
|
+
sleep connect_retry_period
|
862
855
|
retry
|
863
856
|
else
|
864
857
|
disconnect
|
@@ -876,13 +869,6 @@ module NewRelic
|
|
876
869
|
control.root
|
877
870
|
end
|
878
871
|
|
879
|
-
# Checks whether this process is a Passenger or Unicorn
|
880
|
-
# spawning server - if so, we probably don't intend to report
|
881
|
-
# statistics from this process
|
882
|
-
def is_application_spawner?
|
883
|
-
$0 =~ /ApplicationSpawner|^unicorn\S* master/
|
884
|
-
end
|
885
|
-
|
886
872
|
# calls the busy harvester and collects timeslice data to
|
887
873
|
# send later
|
888
874
|
def harvest_timeslice_data(time=Time.now)
|
@@ -1042,13 +1028,16 @@ module NewRelic
|
|
1042
1028
|
def transmit_data(disconnecting=false)
|
1043
1029
|
now = Time.now
|
1044
1030
|
::NewRelic::Agent.logger.debug "Sending data to New Relic Service"
|
1045
|
-
harvest_and_send_errors
|
1046
|
-
harvest_and_send_slowest_sample
|
1047
|
-
harvest_and_send_slowest_sql
|
1048
|
-
harvest_and_send_timeslice_data
|
1049
|
-
harvest_and_send_thread_profile(disconnecting)
|
1050
1031
|
|
1051
|
-
|
1032
|
+
@service.session do # use http keep-alive
|
1033
|
+
harvest_and_send_errors
|
1034
|
+
harvest_and_send_slowest_sample
|
1035
|
+
harvest_and_send_slowest_sql
|
1036
|
+
harvest_and_send_timeslice_data
|
1037
|
+
harvest_and_send_thread_profile(disconnecting)
|
1038
|
+
|
1039
|
+
check_for_agent_commands
|
1040
|
+
end
|
1052
1041
|
rescue => e
|
1053
1042
|
retry_count ||= 0
|
1054
1043
|
retry_count += 1
|
@@ -1071,7 +1060,7 @@ module NewRelic
|
|
1071
1060
|
# If this process comes from a parent process, it will not
|
1072
1061
|
# disconnect, so that the parent process can continue to send data
|
1073
1062
|
def graceful_disconnect
|
1074
|
-
if
|
1063
|
+
if connected?
|
1075
1064
|
begin
|
1076
1065
|
@service.request_timeout = 10
|
1077
1066
|
transmit_data(true)
|