wd_newrelic_rpm 3.5.5 → 3.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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)
|