newrelic_rpm 3.4.2.1 → 3.5.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of newrelic_rpm might be problematic. Click here for more details.
- data/CHANGELOG +47 -2
- data/lib/new_relic/agent.rb +5 -5
- data/lib/new_relic/agent/agent.rb +88 -177
- data/lib/new_relic/agent/beacon_configuration.rb +33 -47
- data/lib/new_relic/agent/browser_monitoring.rb +26 -33
- data/lib/new_relic/agent/configuration/defaults.rb +21 -13
- data/lib/new_relic/agent/configuration/manager.rb +28 -14
- data/lib/new_relic/agent/configuration/server_source.rb +8 -5
- data/lib/new_relic/agent/database.rb +37 -22
- data/lib/new_relic/agent/error_collector.rb +32 -31
- data/lib/new_relic/agent/instrumentation/unicorn_instrumentation.rb +4 -3
- data/lib/new_relic/agent/new_relic_service.rb +21 -19
- data/lib/new_relic/agent/pipe_channel_manager.rb +13 -13
- data/lib/new_relic/agent/sql_sampler.rb +9 -28
- data/lib/new_relic/agent/stats_engine/gc_profiler.rb +21 -24
- data/lib/new_relic/agent/stats_engine/transactions.rb +20 -12
- data/lib/new_relic/agent/transaction_sample_builder.rb +5 -3
- data/lib/new_relic/agent/transaction_sampler.rb +43 -47
- data/lib/new_relic/control/frameworks/rails.rb +9 -4
- data/lib/new_relic/control/frameworks/rails3.rb +10 -0
- data/lib/new_relic/noticed_error.rb +18 -8
- data/lib/new_relic/rack.rb +4 -0
- data/lib/new_relic/rack/browser_monitoring.rb +2 -0
- data/lib/new_relic/rack/error_collector.rb +56 -0
- data/lib/new_relic/version.rb +3 -3
- data/newrelic.yml +0 -12
- data/newrelic_rpm.gemspec +6 -3
- data/test/new_relic/agent/agent/connect_test.rb +78 -113
- data/test/new_relic/agent/agent/start_test.rb +2 -2
- data/test/new_relic/agent/agent/start_worker_thread_test.rb +6 -33
- data/test/new_relic/agent/agent_test.rb +20 -6
- data/test/new_relic/agent/agent_test_controller_test.rb +7 -5
- data/test/new_relic/agent/beacon_configuration_test.rb +54 -60
- data/test/new_relic/agent/browser_monitoring_test.rb +88 -74
- data/test/new_relic/agent/configuration/manager_test.rb +21 -21
- data/test/new_relic/agent/configuration/server_source_test.rb +21 -4
- data/test/new_relic/agent/instrumentation/task_instrumentation_test.rb +2 -2
- data/test/new_relic/agent/mock_scope_listener.rb +3 -0
- data/test/new_relic/agent/new_relic_service_test.rb +56 -17
- data/test/new_relic/agent/pipe_channel_manager_test.rb +4 -1
- data/test/new_relic/agent/rpm_agent_test.rb +1 -0
- data/test/new_relic/agent/stats_engine_test.rb +12 -7
- data/test/new_relic/agent/transaction_sampler_test.rb +106 -102
- data/test/new_relic/agent_test.rb +10 -9
- data/test/new_relic/control_test.rb +1 -17
- data/test/new_relic/rack/browser_monitoring_test.rb +11 -5
- data/test/new_relic/rack/error_collector_test.rb +74 -0
- data/test/test_helper.rb +1 -1
- metadata +9 -7
data/CHANGELOG
CHANGED
@@ -2,9 +2,55 @@
|
|
2
2
|
# New Relic Ruby Agent Release Notes #
|
3
3
|
|
4
4
|
### Next Up ###
|
5
|
-
## v3.
|
5
|
+
## v3.5.1 ##
|
6
6
|
|
7
7
|
### current version ###
|
8
|
+
## v3.5.0 ##
|
9
|
+
|
10
|
+
* (Fix) RUM Stops Working After 3.4.2.1 Agent Upgrade
|
11
|
+
|
12
|
+
v3.4.2.1 introduced a bug that caused the browser monitor auto instrumentation
|
13
|
+
(for RUM) default to be false. The correct value of true is now used
|
14
|
+
|
15
|
+
* When the Ruby Agent detects Unicorn as the dispatcher it creates an INFO level log message
|
16
|
+
with additional information
|
17
|
+
|
18
|
+
To help customers using Unicorn, if the agent detects it (Unicorn) is being used as the
|
19
|
+
dispatcher an INFO level log message it created that includes a link to New Relic
|
20
|
+
online doc that has additional steps that may be required to get performance data reporting.
|
21
|
+
|
22
|
+
* (Fix) In version 3.4.2 of the Ruby Agent the server side value for Apdex T was disgregarded
|
23
|
+
|
24
|
+
With version 3.4.2 of the agent, the value set in the newrelic.yml file took precedence over the
|
25
|
+
value set in the New Relic UI. As of version 3.5.0 only the value for Apdex T set in the
|
26
|
+
New Relic UI will be used. Any setting in the yaml file will be ignored.
|
27
|
+
|
28
|
+
* Improved Error Detection/Reporting capabilities for Rails 3 apps
|
29
|
+
|
30
|
+
Some errors are missed by the agent's exception reporting handlers because they are
|
31
|
+
generated in the rails stack, outside of the instrumented controller action. A Rack
|
32
|
+
middleware is now included that can detect these errors as they bubble out of the middleware stack.
|
33
|
+
Note that this does not include Routing Errors.
|
34
|
+
|
35
|
+
* The Ruby Agent now logs certain information it receives from the New Relic servers
|
36
|
+
|
37
|
+
After connecting to the New Relic servers the agent logs the New Relic URL
|
38
|
+
of the app it is reporting to.
|
39
|
+
|
40
|
+
* GC profiling overhead for Ruby 1.9 reduced
|
41
|
+
|
42
|
+
For Ruby 1.9 the amount of time spent in GC profiling has been reduced.
|
43
|
+
|
44
|
+
* Know issue with Ruby 1.8.7-p334, sqlite3-ruby 1.3.0 or older, and resque 1.23.0
|
45
|
+
|
46
|
+
The Ruby Agent will not work in conjunction with Ruby 1.8.7-p334, sqlite3-ruby 1.3.3
|
47
|
+
or earlier, and resque 1.23.0. Your app will likely stop functioning. This is a known problem
|
48
|
+
with Ruby versions up to 1.8.7-p334. Upgrading to the last release of Ruby 1.8.7
|
49
|
+
is recommended. This issue has been present in every version of the agent we've tested
|
50
|
+
going back for a year.
|
51
|
+
|
52
|
+
|
53
|
+
### previous versions ###
|
8
54
|
## v3.4.2.1 ##
|
9
55
|
|
10
56
|
* Fix issue when app_name is nil
|
@@ -14,7 +60,6 @@
|
|
14
60
|
NEW_RELIC_APP_NAME environment variable set. A nil app_name is now detected and an
|
15
61
|
error logged specifying remediation.
|
16
62
|
|
17
|
-
### previous versions ###
|
18
63
|
## v3.4.2 ##
|
19
64
|
|
20
65
|
* The RUM NRAGENT tk value gets more robustly sanitized to prevent potential XSS vulnerabilities
|
data/lib/new_relic/agent.rb
CHANGED
@@ -101,9 +101,9 @@ module NewRelic
|
|
101
101
|
require 'set'
|
102
102
|
require 'thread'
|
103
103
|
require 'resolv'
|
104
|
-
|
104
|
+
|
105
105
|
extend NewRelic::Agent::Configuration::Instance
|
106
|
-
|
106
|
+
|
107
107
|
# An exception that is thrown by the server if the agent license is invalid.
|
108
108
|
class LicenseException < StandardError; end
|
109
109
|
|
@@ -117,9 +117,9 @@ module NewRelic
|
|
117
117
|
# failures.
|
118
118
|
class ServerConnectionException < StandardError; end
|
119
119
|
|
120
|
-
#
|
121
|
-
#
|
122
|
-
class
|
120
|
+
# When a post is either too large or poorly formatted we should
|
121
|
+
# drop it and not try to resend
|
122
|
+
class UnrecoverableServerException < ServerConnectionException; end
|
123
123
|
|
124
124
|
# Reserved for future use. Meant to represent a problem on the server side.
|
125
125
|
class ServerError < StandardError; end
|
@@ -7,6 +7,7 @@ require 'stringio'
|
|
7
7
|
require 'new_relic/agent/new_relic_service'
|
8
8
|
require 'new_relic/agent/pipe_service'
|
9
9
|
require 'new_relic/agent/configuration/manager'
|
10
|
+
require 'new_relic/agent/database'
|
10
11
|
|
11
12
|
module NewRelic
|
12
13
|
module Agent
|
@@ -17,7 +18,7 @@ module NewRelic
|
|
17
18
|
# data to the NewRelic server.
|
18
19
|
class Agent
|
19
20
|
extend NewRelic::Agent::Configuration::Instance
|
20
|
-
|
21
|
+
|
21
22
|
def initialize
|
22
23
|
@launch_time = Time.now
|
23
24
|
|
@@ -25,7 +26,6 @@ module NewRelic
|
|
25
26
|
@stats_engine = NewRelic::Agent::StatsEngine.new
|
26
27
|
@transaction_sampler = NewRelic::Agent::TransactionSampler.new
|
27
28
|
@sql_sampler = NewRelic::Agent::SqlSampler.new
|
28
|
-
@stats_engine.transaction_sampler = @transaction_sampler
|
29
29
|
@error_collector = NewRelic::Agent::ErrorCollector.new
|
30
30
|
@connect_attempts = 0
|
31
31
|
|
@@ -37,6 +37,17 @@ module NewRelic
|
|
37
37
|
if Agent.config[:monitor_mode]
|
38
38
|
@service = NewRelic::Agent::NewRelicService.new
|
39
39
|
end
|
40
|
+
|
41
|
+
txn_tracer_enabler = Proc.new do
|
42
|
+
if NewRelic::Agent.config[:'transaction_tracer.enabled'] ||
|
43
|
+
NewRelic::Agent.config[:developer_mode]
|
44
|
+
@stats_engine.transaction_sampler = @transaction_sampler
|
45
|
+
else
|
46
|
+
@stats_engine.transaction_sampler = nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
Agent.config.register_callback(:'transaction_tracer.enabled', &txn_tracer_enabler)
|
50
|
+
Agent.config.register_callback(:developer_mode, &txn_tracer_enabler)
|
40
51
|
end
|
41
52
|
|
42
53
|
# contains all the class-level methods for NewRelic::Agent::Agent
|
@@ -47,11 +58,11 @@ module NewRelic
|
|
47
58
|
@instance ||= self.new
|
48
59
|
end
|
49
60
|
end
|
50
|
-
|
61
|
+
|
51
62
|
# Holds all the methods defined on NewRelic::Agent::Agent
|
52
63
|
# instances
|
53
64
|
module InstanceMethods
|
54
|
-
|
65
|
+
|
55
66
|
# holds a proc that is used to obfuscate sql statements
|
56
67
|
attr_reader :obfuscator
|
57
68
|
# the statistics engine that holds all the timeslice data
|
@@ -75,19 +86,19 @@ module NewRelic
|
|
75
86
|
# into pages
|
76
87
|
attr_reader :beacon_configuration
|
77
88
|
attr_accessor :service
|
78
|
-
|
89
|
+
|
79
90
|
# Returns the length of the unsent errors array, if it exists,
|
80
91
|
# otherwise nil
|
81
92
|
def unsent_errors_size
|
82
93
|
@unsent_errors.length if @unsent_errors
|
83
94
|
end
|
84
|
-
|
95
|
+
|
85
96
|
# Returns the length of the traces array, if it exists,
|
86
97
|
# otherwise nil
|
87
98
|
def unsent_traces_size
|
88
99
|
@traces.length if @traces
|
89
100
|
end
|
90
|
-
|
101
|
+
|
91
102
|
# Initializes the unsent timeslice data hash, if needed, and
|
92
103
|
# returns the number of keys it contains
|
93
104
|
def unsent_timeslice_data
|
@@ -98,7 +109,7 @@ module NewRelic
|
|
98
109
|
# fakes out a transaction that did not happen in this process
|
99
110
|
# by creating apdex, summary metrics, and recording statistics
|
100
111
|
# for the transaction
|
101
|
-
#
|
112
|
+
#
|
102
113
|
# This method is *deprecated* - it may be removed in future
|
103
114
|
# versions of the agent
|
104
115
|
def record_transaction(duration_seconds, options={})
|
@@ -153,23 +164,25 @@ module NewRelic
|
|
153
164
|
# quickly if there is some kind of latency with the server.
|
154
165
|
def after_fork(options={})
|
155
166
|
@forked = true
|
167
|
+
Agent.config.apply_config(NewRelic::Agent::Configuration::ManualSource.new(options), 1)
|
168
|
+
|
156
169
|
# @connected gets false after we fail to connect or have an error
|
157
170
|
# connecting. @connected has nil if we haven't finished trying to connect.
|
158
171
|
# or we didn't attempt a connection because this is the master process
|
159
|
-
|
172
|
+
|
160
173
|
if channel_id = options[:report_to_channel]
|
161
174
|
@service = NewRelic::Agent::PipeService.new(channel_id)
|
162
175
|
@connected_pid = $$
|
163
176
|
@metric_ids = {}
|
164
177
|
end
|
165
|
-
|
178
|
+
|
166
179
|
# log.debug "Agent received after_fork notice in #$$: [#{control.agent_enabled?}; monitor=#{control.monitor_mode?}; connected: #{@connected.inspect}; thread=#{@worker_thread.inspect}]"
|
167
180
|
return if !Agent.config[:agent_enabled] ||
|
168
181
|
!Agent.config[:monitor_mode] ||
|
169
182
|
@connected == false ||
|
170
183
|
@worker_thread && @worker_thread.alive?
|
171
184
|
|
172
|
-
log.info "Starting the worker thread in
|
185
|
+
log.info "Starting the worker thread in #{$$} after forking."
|
173
186
|
|
174
187
|
# Clear out stats that are left over from parent process
|
175
188
|
reset_stats
|
@@ -179,11 +192,11 @@ module NewRelic
|
|
179
192
|
start_worker_thread(options)
|
180
193
|
@stats_engine.start_sampler_thread
|
181
194
|
end
|
182
|
-
|
195
|
+
|
183
196
|
def forked?
|
184
197
|
@forked
|
185
198
|
end
|
186
|
-
|
199
|
+
|
187
200
|
# True if we have initialized and completed 'start'
|
188
201
|
def started?
|
189
202
|
@started
|
@@ -322,7 +335,7 @@ module NewRelic
|
|
322
335
|
log.error 'Unable to determine application name. Please set the application name in your newrelic.yml or in a NEW_RELIC_APP_NAME environment variable.'
|
323
336
|
end
|
324
337
|
end
|
325
|
-
|
338
|
+
|
326
339
|
# Connecting in the foreground blocks further startup of the
|
327
340
|
# agent until we have a connection - useful in cases where
|
328
341
|
# you're trying to log a very-short-running process and want
|
@@ -392,13 +405,15 @@ module NewRelic
|
|
392
405
|
# Warn the user if they have configured their agent not to
|
393
406
|
# send data, that way we can see this clearly in the log file
|
394
407
|
def monitoring?
|
395
|
-
log_unless(Agent.config[:monitor_mode], :warn,
|
408
|
+
log_unless(Agent.config[:monitor_mode], :warn,
|
409
|
+
"Agent configured not to send data in this environment.")
|
396
410
|
end
|
397
411
|
|
398
412
|
# Tell the user when the license key is missing so they can
|
399
413
|
# fix it by adding it to the file
|
400
414
|
def has_license_key?
|
401
|
-
log_unless(Agent.config[:license_key], :
|
415
|
+
log_unless(Agent.config[:license_key], :warn,
|
416
|
+
"No license key found in newrelic.yml config.")
|
402
417
|
end
|
403
418
|
|
404
419
|
# A correct license key exists and is of the proper length
|
@@ -442,7 +457,6 @@ module NewRelic
|
|
442
457
|
@local_host = determine_host
|
443
458
|
log_dispatcher
|
444
459
|
log_app_names
|
445
|
-
config_transaction_tracer
|
446
460
|
check_config_and_start_agent
|
447
461
|
log_version_and_pid
|
448
462
|
notify_log_file_location
|
@@ -460,36 +474,15 @@ module NewRelic
|
|
460
474
|
end
|
461
475
|
|
462
476
|
private
|
463
|
-
|
477
|
+
|
464
478
|
# All of this module used to be contained in the
|
465
479
|
# start_worker_thread method - this is an artifact of
|
466
480
|
# refactoring and can be moved, renamed, etc at will
|
467
481
|
module StartWorkerThread
|
468
|
-
|
469
|
-
# disable transaction sampling if disabled by the server
|
470
|
-
# and we're not in dev mode
|
471
|
-
def check_transaction_sampler_status
|
472
|
-
if Agent.config[:developer_mode] || @should_send_samples
|
473
|
-
@transaction_sampler.enable
|
474
|
-
else
|
475
|
-
@transaction_sampler.disable
|
476
|
-
end
|
477
|
-
end
|
478
|
-
|
479
|
-
def check_sql_sampler_status
|
480
|
-
# disable sql sampling if disabled by the server
|
481
|
-
# and we're not in dev mode
|
482
|
-
if Agent.config[:'slow_sql.enabled'] && ['raw', 'obfuscated'].include?(Agent.config[:'slow_sql.record_sql']) && Agent.config[:'transaction_tracer.enabled']
|
483
|
-
@sql_sampler.enable
|
484
|
-
else
|
485
|
-
@sql_sampler.disable
|
486
|
-
end
|
487
|
-
end
|
488
|
-
|
489
482
|
# logs info about the worker loop so users can see when the
|
490
483
|
# agent actually begins running in the background
|
491
484
|
def log_worker_loop_start
|
492
|
-
log.info "Reporting performance data every #{
|
485
|
+
log.info "Reporting performance data every #{Agent.config[:data_report_period]} seconds."
|
493
486
|
log.debug "Running worker loop"
|
494
487
|
end
|
495
488
|
|
@@ -497,7 +490,7 @@ module NewRelic
|
|
497
490
|
# it should run every @report_period seconds
|
498
491
|
def create_and_run_worker_loop
|
499
492
|
@worker_loop = WorkerLoop.new
|
500
|
-
@worker_loop.run(
|
493
|
+
@worker_loop.run(Agent.config[:data_report_period]) do
|
501
494
|
transmit_data
|
502
495
|
end
|
503
496
|
end
|
@@ -570,8 +563,6 @@ module NewRelic
|
|
570
563
|
# that means it didn't try to connect because we're in the master.
|
571
564
|
connect(connection_options)
|
572
565
|
if @connected
|
573
|
-
check_transaction_sampler_status
|
574
|
-
check_sql_sampler_status
|
575
566
|
log_worker_loop_start
|
576
567
|
create_and_run_worker_loop
|
577
568
|
# never reaches here unless there is a problem or
|
@@ -600,7 +591,7 @@ module NewRelic
|
|
600
591
|
def control
|
601
592
|
NewRelic::Control.instance
|
602
593
|
end
|
603
|
-
|
594
|
+
|
604
595
|
# This module is an artifact of a refactoring of the connect
|
605
596
|
# method - all of its methods are used in that context, so it
|
606
597
|
# can be refactored at will. It should be fully tested
|
@@ -731,106 +722,11 @@ module NewRelic
|
|
731
722
|
@service.connect(connect_settings)
|
732
723
|
end
|
733
724
|
|
734
|
-
# Configures the error collector if the server says that we
|
735
|
-
# are allowed to send errors. Pretty simple, and logs at
|
736
|
-
# debug whether errors will or will not be sent.
|
737
|
-
def configure_error_collector!(server_enabled)
|
738
|
-
# Reinitialize the error collector
|
739
|
-
@error_collector = NewRelic::Agent::ErrorCollector.new
|
740
|
-
# Ask for permission to collect error data
|
741
|
-
enabled = if error_collector.config_enabled && server_enabled
|
742
|
-
error_collector.enabled = true
|
743
|
-
else
|
744
|
-
error_collector.enabled = false
|
745
|
-
end
|
746
|
-
log.debug "Errors will #{enabled ? '' : 'not '}be sent to the New Relic service."
|
747
|
-
end
|
748
|
-
|
749
|
-
# Random sampling is enabled based on a sample rate, which
|
750
|
-
# is the n in "every 1/n transactions is added regardless of
|
751
|
-
# its length".
|
752
|
-
#
|
753
|
-
# uses a sane default for sampling rate if the sampling rate
|
754
|
-
# is zero, since the collector currently sends '0' as a
|
755
|
-
# sampling rate for all accounts, which is probably for
|
756
|
-
# legacy reasons
|
757
|
-
def enable_random_samples!(sample_rate)
|
758
|
-
sample_rate = 10 unless sample_rate.to_i > 0
|
759
|
-
@transaction_sampler.random_sampling = true
|
760
|
-
@transaction_sampler.sampling_rate = sample_rate
|
761
|
-
log.info "Transaction sampling enabled, rate = #{@transaction_sampler.sampling_rate}"
|
762
|
-
end
|
763
|
-
|
764
|
-
# this entire method should be done on the transaction
|
765
|
-
# sampler object, rather than here. We should pass in the
|
766
|
-
# sampler config.
|
767
|
-
def config_transaction_tracer
|
768
|
-
# Reconfigure the transaction tracer
|
769
|
-
@transaction_sampler.configure!
|
770
|
-
@sql_sampler.configure!
|
771
|
-
@should_send_samples = @config_should_send_samples = Agent.config[:'transaction_tracer.enabled']
|
772
|
-
@should_send_random_samples = Agent.config[:'transaction_tracer.random_sample']
|
773
|
-
set_sql_recording!
|
774
|
-
|
775
|
-
# default to 2.0, string 'apdex_f' will turn into your
|
776
|
-
# apdex * 4
|
777
|
-
@slowest_transaction_threshold = Agent.config[:'transaction_tracer.transaction_threshold']
|
778
|
-
end
|
779
|
-
|
780
|
-
# Enables or disables the transaction tracer and sets its
|
781
|
-
# options based on the options provided to the
|
782
|
-
# method.
|
783
|
-
def configure_transaction_tracer!(server_enabled, sample_rate)
|
784
|
-
# Ask the server for permission to send transaction samples.
|
785
|
-
# determined by subscription license.
|
786
|
-
@sql_sampler.configure!
|
787
|
-
@should_send_samples = @config_should_send_samples && server_enabled
|
788
|
-
|
789
|
-
if @should_send_samples
|
790
|
-
# I don't think this is ever true, but...
|
791
|
-
enable_random_samples!(sample_rate) if @should_send_random_samples
|
792
|
-
|
793
|
-
@transaction_sampler.slow_capture_threshold = @slowest_transaction_threshold
|
794
|
-
|
795
|
-
log.debug "Transaction tracing threshold is #{@slowest_transaction_threshold} seconds."
|
796
|
-
else
|
797
|
-
log.debug "Transaction traces will not be sent to the New Relic service."
|
798
|
-
end
|
799
|
-
end
|
800
|
-
|
801
725
|
# apdex_f is always 4 times the apdex_t
|
802
726
|
def apdex_f
|
803
727
|
(4 * Agent.config[:apdex_t]).to_f
|
804
728
|
end
|
805
729
|
|
806
|
-
# Sets the sql recording configuration by trying to detect
|
807
|
-
# any attempt to disable the sql collection - 'off',
|
808
|
-
# 'false', 'none', and friends. Otherwise, we accept 'raw',
|
809
|
-
# and unrecognized values default to 'obfuscated'
|
810
|
-
def set_sql_recording!
|
811
|
-
record_sql_config = Agent.config[:'transaction_tracer.record_sql']
|
812
|
-
case record_sql_config.to_s
|
813
|
-
when 'off'
|
814
|
-
@record_sql = :off
|
815
|
-
when 'none'
|
816
|
-
@record_sql = :off
|
817
|
-
when 'false'
|
818
|
-
@record_sql = :off
|
819
|
-
when 'raw'
|
820
|
-
@record_sql = :raw
|
821
|
-
else
|
822
|
-
@record_sql = :obfuscated
|
823
|
-
end
|
824
|
-
|
825
|
-
log_sql_transmission_warning?
|
826
|
-
end
|
827
|
-
|
828
|
-
# Warn the user when we are sending raw sql across the wire
|
829
|
-
# - they should probably be using ssl when this is true
|
830
|
-
def log_sql_transmission_warning?
|
831
|
-
log.warn("Agent is configured to send raw SQL to the service") if @record_sql == :raw
|
832
|
-
end
|
833
|
-
|
834
730
|
# Sets the collector host and connects to the server, then
|
835
731
|
# invokes the final configuration with the returned data
|
836
732
|
def query_server_for_configuration
|
@@ -846,31 +742,36 @@ module NewRelic
|
|
846
742
|
# ignored unless we say to do something with it here.
|
847
743
|
def finish_setup(config_data)
|
848
744
|
return if config_data == nil
|
849
|
-
|
745
|
+
|
850
746
|
@service.agent_id = config_data['agent_run_id'] if @service
|
851
|
-
@report_period = config_data['data_report_period']
|
852
|
-
@url_rules = config_data['url_rules']
|
853
|
-
@beacon_configuration = BeaconConfiguration.new(config_data)
|
854
747
|
|
855
|
-
if config_data['
|
748
|
+
if config_data['agent_config']
|
856
749
|
log.info "Using config from server"
|
857
|
-
log.debug "Server provided config: #{config_data.inspect}"
|
858
|
-
server_config = NewRelic::Agent::Configuration::ServerSource.new(config_data)
|
859
|
-
Agent.config.apply_config(server_config, 1)
|
860
750
|
end
|
861
751
|
|
862
|
-
|
752
|
+
log.debug "Server provided config: #{config_data.inspect}"
|
753
|
+
server_config = NewRelic::Agent::Configuration::ServerSource.new(config_data)
|
754
|
+
Agent.config.apply_config(server_config, 1)
|
863
755
|
log_connection!(config_data) if @service
|
864
|
-
|
865
|
-
|
756
|
+
|
757
|
+
@beacon_configuration = BeaconConfiguration.new
|
866
758
|
end
|
867
|
-
|
759
|
+
|
868
760
|
# Logs when we connect to the server, for debugging purposes
|
869
761
|
# - makes sure we know if an agent has not connected
|
870
762
|
def log_connection!(config_data)
|
871
|
-
|
763
|
+
log.info "Connected to NewRelic Service at #{@service.collector.name}"
|
872
764
|
log.debug "Agent Run = #{@service.agent_id}."
|
873
765
|
log.debug "Connection data = #{config_data.inspect}"
|
766
|
+
if config_data['messages'] && config_data['messages'].any?
|
767
|
+
log_collector_messages(config_data['messages'])
|
768
|
+
end
|
769
|
+
end
|
770
|
+
|
771
|
+
def log_collector_messages(messages)
|
772
|
+
messages.each do |message|
|
773
|
+
log.send(message['level'].downcase.to_sym, message['message'])
|
774
|
+
end
|
874
775
|
end
|
875
776
|
end
|
876
777
|
include Connect
|
@@ -1005,11 +906,16 @@ module NewRelic
|
|
1005
906
|
NewRelic::Agent.instance.stats_engine.get_stats_no_scope('Supportability/invoke_remote').record_data_point(0.0)
|
1006
907
|
NewRelic::Agent.instance.stats_engine.get_stats_no_scope('Supportability/invoke_remote/metric_data').record_data_point(0.0)
|
1007
908
|
harvest_timeslice_data(now)
|
1008
|
-
# In this version of the protocol
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
909
|
+
# In this version of the protocol
|
910
|
+
# we get back an assoc array of spec to id.
|
911
|
+
metric_specs_and_ids = []
|
912
|
+
begin
|
913
|
+
metric_specs_and_ids = @service.metric_data(@last_harvest_time.to_f,
|
914
|
+
now.to_f,
|
915
|
+
@unsent_timeslice_data.values)
|
916
|
+
rescue UnrecoverableServerException => e
|
917
|
+
log.debug e.message
|
918
|
+
end
|
1013
919
|
fill_metric_id_cache(metric_specs_and_ids)
|
1014
920
|
|
1015
921
|
log.debug "#{now}: sent #{@unsent_timeslice_data.length} timeslices (#{@service.agent_id}) in #{Time.now - now} seconds"
|
@@ -1023,7 +929,7 @@ module NewRelic
|
|
1023
929
|
# the transaction sampler, subject to the setting for slowest
|
1024
930
|
# transaction threshold
|
1025
931
|
def harvest_transaction_traces
|
1026
|
-
@traces = @transaction_sampler.harvest(@traces
|
932
|
+
@traces = @transaction_sampler.harvest(@traces)
|
1027
933
|
@traces
|
1028
934
|
end
|
1029
935
|
|
@@ -1034,8 +940,11 @@ module NewRelic
|
|
1034
940
|
log.debug "Sending (#{sql_traces.size}) sql traces"
|
1035
941
|
begin
|
1036
942
|
@service.sql_trace_data(sql_traces)
|
1037
|
-
rescue
|
1038
|
-
|
943
|
+
rescue UnrecoverableServerException => e
|
944
|
+
log.debug e.message
|
945
|
+
rescue => e
|
946
|
+
log.debug "Remerging SQL traces after #{e.class.name}: #{e.message}"
|
947
|
+
@sql_sampler.merge sql_traces
|
1039
948
|
end
|
1040
949
|
end
|
1041
950
|
end
|
@@ -1051,22 +960,21 @@ module NewRelic
|
|
1051
960
|
unless @traces.empty?
|
1052
961
|
now = Time.now
|
1053
962
|
log.debug "Sending (#{@traces.length}) transaction traces"
|
1054
|
-
|
963
|
+
|
1055
964
|
begin
|
1056
965
|
options = { :keep_backtraces => true }
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
966
|
+
if !(NewRelic::Agent::Database.record_sql_method == :off)
|
967
|
+
options[:record_sql] = NewRelic::Agent::Database.record_sql_method
|
968
|
+
end
|
969
|
+
if Agent.config[:'transaction_tracer.explain_enabled']
|
970
|
+
options[:explain_sql] = Agent.config[:'transaction_tracer.explain_threshold']
|
1060
971
|
end
|
1061
972
|
traces = @traces.collect {|trace| trace.prepare_to_send(options)}
|
1062
973
|
@service.transaction_sample_data(traces)
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
retry if @traces.shift
|
974
|
+
log.debug "Sent slowest sample (#{@service.agent_id}) in #{Time.now - now} seconds"
|
975
|
+
rescue UnrecoverableServerException => e
|
976
|
+
log.debug e.message
|
1067
977
|
end
|
1068
|
-
|
1069
|
-
log.debug "Sent slowest sample (#{@service.agent_id}) in #{Time.now - now} seconds"
|
1070
978
|
end
|
1071
979
|
|
1072
980
|
# if we succeed sending this sample, then we don't need to keep
|
@@ -1093,9 +1001,8 @@ module NewRelic
|
|
1093
1001
|
log.debug "Sending #{@unsent_errors.length} errors"
|
1094
1002
|
begin
|
1095
1003
|
@service.error_data(@unsent_errors)
|
1096
|
-
rescue
|
1097
|
-
|
1098
|
-
retry
|
1004
|
+
rescue UnrecoverableServerException => e
|
1005
|
+
log.debug e.message
|
1099
1006
|
end
|
1100
1007
|
# if the remote invocation fails, then we never clear
|
1101
1008
|
# @unsent_errors, and therefore we can re-attempt to send on
|
@@ -1104,7 +1011,7 @@ module NewRelic
|
|
1104
1011
|
@unsent_errors = []
|
1105
1012
|
end
|
1106
1013
|
end
|
1107
|
-
|
1014
|
+
|
1108
1015
|
def transmit_data
|
1109
1016
|
log.debug "Sending data to New Relic Service"
|
1110
1017
|
harvest_and_send_errors
|
@@ -1114,7 +1021,10 @@ module NewRelic
|
|
1114
1021
|
rescue => e
|
1115
1022
|
retry_count ||= 0
|
1116
1023
|
retry_count += 1
|
1117
|
-
|
1024
|
+
if retry_count <= 1
|
1025
|
+
log.debug "retrying transmit_data after #{e}"
|
1026
|
+
retry
|
1027
|
+
end
|
1118
1028
|
raise e
|
1119
1029
|
ensure
|
1120
1030
|
NewRelic::Agent::Database.close_connections unless forked?
|
@@ -1139,14 +1049,15 @@ module NewRelic
|
|
1139
1049
|
log.debug "This agent connected from parent process #{@connected_pid}--not sending shutdown"
|
1140
1050
|
end
|
1141
1051
|
log.debug "Graceful disconnect complete"
|
1142
|
-
rescue Timeout::Error, StandardError
|
1052
|
+
rescue Timeout::Error, StandardError => e
|
1053
|
+
log.debug "Error when disconnecting #{e.class.name}: #{e.message}"
|
1143
1054
|
end
|
1144
1055
|
else
|
1145
1056
|
log.debug "Bypassing graceful disconnect - agent not connected"
|
1146
1057
|
end
|
1147
1058
|
end
|
1148
1059
|
end
|
1149
|
-
|
1060
|
+
|
1150
1061
|
extend ClassMethods
|
1151
1062
|
include InstanceMethods
|
1152
1063
|
include BrowserMonitoring
|