newrelic_rpm 3.5.4.35.beta → 3.5.5.38
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +42 -0
- data/GUIDELINES_FOR_CONTRIBUTING.md +3 -0
- data/Rakefile +8 -0
- data/bin/mongrel_rpm +1 -1
- data/init.rb +1 -8
- data/lib/new_relic/agent.rb +11 -13
- data/lib/new_relic/agent/agent.rb +89 -110
- data/lib/new_relic/agent/agent_logger.rb +165 -0
- data/lib/new_relic/agent/audit_logger.rb +72 -0
- data/lib/new_relic/agent/beacon_configuration.rb +4 -4
- data/lib/new_relic/agent/browser_monitoring.rb +13 -7
- data/lib/new_relic/agent/busy_calculator.rb +2 -2
- data/lib/new_relic/agent/configuration.rb +25 -0
- data/lib/new_relic/agent/configuration/defaults.rb +45 -8
- data/lib/new_relic/agent/configuration/environment_source.rb +8 -15
- data/lib/new_relic/agent/configuration/manager.rb +22 -2
- data/lib/new_relic/agent/configuration/mask_defaults.rb +10 -0
- data/lib/new_relic/agent/configuration/yaml_source.rb +4 -2
- data/lib/new_relic/agent/cross_process_monitoring.rb +43 -0
- data/lib/new_relic/agent/database.rb +2 -4
- data/lib/new_relic/agent/error_collector.rb +4 -9
- data/lib/new_relic/agent/instrumentation/active_merchant.rb +1 -1
- data/lib/new_relic/agent/instrumentation/active_record.rb +1 -1
- data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +1 -1
- data/lib/new_relic/agent/instrumentation/authlogic.rb +1 -1
- data/lib/new_relic/agent/instrumentation/browser_monitoring_timings.rb +41 -0
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +7 -7
- data/lib/new_relic/agent/instrumentation/data_mapper.rb +1 -1
- data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +1 -1
- data/lib/new_relic/agent/instrumentation/memcache.rb +4 -4
- data/lib/new_relic/agent/instrumentation/merb/controller.rb +1 -1
- data/lib/new_relic/agent/instrumentation/merb/errors.rb +1 -1
- data/lib/new_relic/agent/instrumentation/metric_frame/pop.rb +1 -1
- data/lib/new_relic/agent/instrumentation/net.rb +1 -1
- data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +2 -2
- data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +4 -4
- data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +1 -1
- data/lib/new_relic/agent/instrumentation/rails/errors.rb +1 -1
- data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +3 -3
- data/lib/new_relic/agent/instrumentation/rails3/errors.rb +1 -1
- data/lib/new_relic/agent/instrumentation/resque.rb +3 -2
- data/lib/new_relic/agent/instrumentation/sinatra.rb +1 -1
- data/lib/new_relic/agent/instrumentation/sunspot.rb +1 -1
- data/lib/new_relic/agent/instrumentation/unicorn_instrumentation.rb +2 -2
- data/lib/new_relic/agent/method_tracer.rb +6 -8
- data/lib/new_relic/agent/new_relic_service.rb +94 -106
- data/lib/new_relic/agent/pipe_channel_manager.rb +1 -1
- data/lib/new_relic/agent/samplers/memory_sampler.rb +4 -6
- data/lib/new_relic/agent/sql_sampler.rb +3 -18
- data/lib/new_relic/agent/stats_engine.rb +0 -5
- data/lib/new_relic/agent/stats_engine/metric_stats.rb +3 -3
- data/lib/new_relic/agent/stats_engine/samplers.rb +2 -4
- data/lib/new_relic/agent/thread.rb +8 -3
- data/lib/new_relic/agent/thread_profiler.rb +38 -27
- data/lib/new_relic/agent/transaction_info.rb +1 -1
- data/lib/new_relic/agent/transaction_sample_builder.rb +2 -3
- data/lib/new_relic/agent/transaction_sampler.rb +3 -7
- data/lib/new_relic/agent/worker_loop.rb +3 -11
- data/lib/new_relic/control.rb +0 -2
- data/lib/new_relic/control/class_methods.rb +8 -2
- data/lib/new_relic/control/frameworks/merb.rb +0 -6
- data/lib/new_relic/control/frameworks/rails.rb +8 -29
- data/lib/new_relic/control/frameworks/rails3.rb +8 -20
- data/lib/new_relic/control/frameworks/rails4.rb +23 -0
- data/lib/new_relic/control/frameworks/ruby.rb +1 -22
- data/lib/new_relic/control/instance_methods.rb +12 -34
- data/lib/new_relic/control/instrumentation.rb +7 -12
- data/lib/new_relic/control/server_methods.rb +5 -8
- data/lib/new_relic/delayed_job_injection.rb +1 -1
- data/lib/new_relic/local_environment.rb +30 -64
- data/lib/new_relic/metric_data.rb +1 -1
- data/lib/new_relic/metric_spec.rb +1 -1
- data/lib/new_relic/noticed_error.rb +1 -1
- data/lib/new_relic/rack/browser_monitoring.rb +5 -5
- data/lib/new_relic/stats.rb +9 -7
- data/lib/new_relic/transaction_sample.rb +2 -7
- data/lib/new_relic/version.rb +1 -1
- data/lib/newrelic_rpm.rb +1 -1
- data/newrelic_rpm.gemspec.erb +15 -17
- data/test/config/newrelic.yml +1 -1
- data/test/config/test_control.rb +18 -18
- data/test/fixtures/gemspec_no_build.rb +0 -2
- data/test/fixtures/gemspec_with_build.rb +0 -2
- data/test/fixtures/gemspec_with_build_and_stage.rb +0 -2
- data/test/multiverse/README.md +3 -8
- data/test/multiverse/suites/agent_only/Envfile +1 -0
- data/test/multiverse/suites/agent_only/audit_log_test.rb +99 -0
- data/test/multiverse/suites/agent_only/marshaling_test.rb +1 -1
- data/test/multiverse/suites/config_file_loading/Envfile +7 -0
- data/test/multiverse/suites/config_file_loading/config_file_loading_test.rb +106 -0
- data/test/multiverse/suites/logging/Envfile +4 -0
- data/test/multiverse/suites/logging/config/newrelic.yml +22 -0
- data/test/multiverse/suites/logging/logging_test.rb +143 -0
- data/test/multiverse/suites/no_load/config/newrelic.yml +1 -2
- data/test/multiverse/suites/rum_auto_instrumentation/sanity_test.rb +0 -13
- data/test/new_relic/agent/agent/connect_test.rb +30 -92
- data/test/new_relic/agent/agent/start_test.rb +4 -84
- data/test/new_relic/agent/agent/start_worker_thread_test.rb +8 -43
- data/test/new_relic/agent/agent_logger_test.rb +153 -0
- data/test/new_relic/agent/agent_test.rb +10 -9
- data/test/new_relic/agent/audit_logger_test.rb +105 -0
- data/test/new_relic/agent/browser_monitoring_test.rb +2 -1
- data/test/new_relic/agent/busy_calculator_test.rb +7 -0
- data/test/new_relic/agent/configuration/environment_source_test.rb +25 -20
- data/test/new_relic/agent/configuration/manager_test.rb +59 -4
- data/test/new_relic/agent/configuration/yaml_source_test.rb +20 -1
- data/test/new_relic/agent/cross_process_monitoring_test.rb +77 -0
- data/test/new_relic/agent/database_test.rb +0 -11
- data/test/new_relic/agent/error_collector/notice_error_test.rb +1 -3
- data/test/new_relic/agent/error_collector_test.rb +11 -7
- data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +39 -19
- data/test/new_relic/agent/instrumentation/browser_monitoring_timings_test.rb +39 -0
- data/test/new_relic/agent/instrumentation/metric_frame/pop_test.rb +1 -1
- data/test/new_relic/agent/method_tracer/class_methods/add_method_tracer_test.rb +0 -6
- data/test/new_relic/agent/method_tracer/instance_methods/trace_execution_scoped_test.rb +3 -15
- data/test/new_relic/agent/new_relic_service_test.rb +48 -8
- data/test/new_relic/agent/pipe_channel_manager_test.rb +1 -1
- data/test/new_relic/agent/sql_sampler_test.rb +1 -1
- data/test/new_relic/agent/thread_profiler_test.rb +46 -45
- data/test/new_relic/agent/thread_test.rb +13 -0
- data/test/new_relic/agent/transaction_sample_builder_test.rb +1 -1
- data/test/new_relic/agent/worker_loop_test.rb +4 -9
- data/test/new_relic/agent_test.rb +6 -9
- data/test/new_relic/control/class_methods_test.rb +0 -18
- data/test/new_relic/control_test.rb +6 -9
- data/test/new_relic/dispatcher_test.rb +54 -0
- data/test/new_relic/fake_collector.rb +15 -14
- data/test/new_relic/fake_service.rb +4 -1
- data/test/new_relic/fakes_sending_data.rb +30 -0
- data/test/new_relic/framework_test.rb +53 -0
- data/test/new_relic/local_environment_test.rb +5 -2
- data/test/new_relic/rack/browser_monitoring_test.rb +2 -1
- data/test/new_relic/rack/developer_mode_test.rb +1 -1
- data/test/new_relic/stats_test.rb +10 -0
- data/test/new_relic/transaction_sample_test.rb +2 -2
- data/test/script/ci.sh +1 -1
- data/test/test_helper.rb +23 -0
- data/ui/views/newrelic/file/images/arrow-close.png +0 -0
- data/ui/views/newrelic/file/images/arrow-open.png +0 -0
- data/ui/views/newrelic/file/images/blue_bar.gif +0 -0
- data/ui/views/newrelic/file/images/file_icon.png +0 -0
- data/ui/views/newrelic/file/images/gray_bar.gif +0 -0
- metadata +47 -41
- data/InstallationNotes.md +0 -15
- data/lib/new_relic/control/logging_methods.rb +0 -125
- data/test/multiverse/Rakefile +0 -17
- data/test/multiverse/suites/rum_auto_instrumentation/problem_response.html +0 -422
- data/test/new_relic/control/logging_methods_test.rb +0 -211
@@ -6,10 +6,10 @@ DependencyDetection.defer do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
executes do
|
9
|
-
NewRelic::Agent.logger.debug "Installing Passenger event hooks."
|
9
|
+
::NewRelic::Agent.logger.debug "Installing Passenger event hooks."
|
10
10
|
|
11
11
|
::PhusionPassenger.on_event(:stopping_worker_process) do
|
12
|
-
NewRelic::Agent.logger.debug "Passenger stopping this process, shutdown the agent."
|
12
|
+
::NewRelic::Agent.logger.debug "Passenger stopping this process, shutdown the agent."
|
13
13
|
NewRelic::Agent.instance.shutdown
|
14
14
|
end
|
15
15
|
|
@@ -8,7 +8,7 @@ DependencyDetection.defer do
|
|
8
8
|
end
|
9
9
|
|
10
10
|
executes do
|
11
|
-
NewRelic::Agent.logger.
|
11
|
+
::NewRelic::Agent.logger.info 'Installing Rails 2.1 View instrumentation'
|
12
12
|
end
|
13
13
|
|
14
14
|
executes do
|
@@ -32,7 +32,7 @@ DependencyDetection.defer do
|
|
32
32
|
end
|
33
33
|
|
34
34
|
executes do
|
35
|
-
NewRelic::Agent.logger.
|
35
|
+
::NewRelic::Agent.logger.info 'Installing Rails 1.* - 2.0 View instrumentation'
|
36
36
|
end
|
37
37
|
|
38
38
|
executes do
|
@@ -53,7 +53,7 @@ DependencyDetection.defer do
|
|
53
53
|
end
|
54
54
|
|
55
55
|
executes do
|
56
|
-
NewRelic::Agent.logger.
|
56
|
+
::NewRelic::Agent.logger.info 'Installing Rails 2.2 - 2.3 View instrumentation'
|
57
57
|
end
|
58
58
|
|
59
59
|
executes do
|
@@ -78,7 +78,7 @@ DependencyDetection.defer do
|
|
78
78
|
end
|
79
79
|
|
80
80
|
executes do
|
81
|
-
NewRelic::Agent.logger.
|
81
|
+
::NewRelic::Agent.logger.info 'Installing Rails 2 Controller instrumentation'
|
82
82
|
end
|
83
83
|
|
84
84
|
executes do
|
@@ -78,7 +78,7 @@ DependencyDetection.defer do
|
|
78
78
|
end
|
79
79
|
|
80
80
|
executes do
|
81
|
-
NewRelic::Agent.logger.
|
81
|
+
::NewRelic::Agent.logger.info 'Installing Rails 3 Controller instrumentation'
|
82
82
|
end
|
83
83
|
|
84
84
|
executes do
|
@@ -100,7 +100,7 @@ DependencyDetection.defer do
|
|
100
100
|
end
|
101
101
|
|
102
102
|
executes do
|
103
|
-
NewRelic::Agent.logger.
|
103
|
+
::NewRelic::Agent.logger.info 'Installing Rails 3.0 view instrumentation'
|
104
104
|
end
|
105
105
|
|
106
106
|
executes do
|
@@ -139,7 +139,7 @@ DependencyDetection.defer do
|
|
139
139
|
end
|
140
140
|
|
141
141
|
executes do
|
142
|
-
NewRelic::Agent.logger.
|
142
|
+
::NewRelic::Agent.logger.info 'Installing Rails 3.1/3.2 view instrumentation'
|
143
143
|
end
|
144
144
|
|
145
145
|
executes do
|
@@ -7,7 +7,7 @@ DependencyDetection.defer do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
executes do
|
10
|
-
NewRelic::Agent.logger.
|
10
|
+
::NewRelic::Agent.logger.info 'Installing Resque instrumentation'
|
11
11
|
end
|
12
12
|
|
13
13
|
executes do
|
@@ -62,7 +62,8 @@ DependencyDetection.defer do
|
|
62
62
|
::Resque.before_first_fork do
|
63
63
|
NewRelic::Agent.manual_start(:dispatcher => :resque,
|
64
64
|
:sync_startup => true,
|
65
|
-
:start_channel_listener => true
|
65
|
+
:start_channel_listener => true,
|
66
|
+
:report_instance_busy => false)
|
66
67
|
end
|
67
68
|
|
68
69
|
::Resque.before_fork do |job|
|
@@ -6,8 +6,8 @@ DependencyDetection.defer do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
executes do
|
9
|
-
NewRelic::Agent.logger.
|
10
|
-
NewRelic::Agent.logger.info 'Detected Unicorn, please see additional documentation: https://newrelic.com/docs/troubleshooting/im-using-unicorn-and-i-dont-see-any-data'
|
9
|
+
::NewRelic::Agent.logger.info 'Installing Unicorn instrumentation'
|
10
|
+
::NewRelic::Agent.logger.info 'Detected Unicorn, please see additional documentation: https://newrelic.com/docs/troubleshooting/im-using-unicorn-and-i-dont-see-any-data'
|
11
11
|
end
|
12
12
|
|
13
13
|
executes do
|
@@ -175,13 +175,11 @@ module NewRelic
|
|
175
175
|
end
|
176
176
|
|
177
177
|
# helper for logging errors to the newrelic_agent.log
|
178
|
-
# properly. Logs the error at error level
|
179
|
-
# backtrace if we're running at debug level
|
178
|
+
# properly. Logs the error at error level
|
180
179
|
def log_errors(code_area, metric)
|
181
180
|
yield
|
182
181
|
rescue => e
|
183
|
-
NewRelic::
|
184
|
-
NewRelic::Control.instance.log.error(e.backtrace.join("\n"))
|
182
|
+
::NewRelic::Agent.logger.error("Caught exception in #{code_area}. Metric name = #{metric}", e)
|
185
183
|
end
|
186
184
|
|
187
185
|
# provides the header for our traced execution scoped
|
@@ -327,7 +325,7 @@ module NewRelic
|
|
327
325
|
# anything if the method doesn't exist.
|
328
326
|
def newrelic_method_exists?(method_name)
|
329
327
|
exists = method_defined?(method_name) || private_method_defined?(method_name)
|
330
|
-
NewRelic::
|
328
|
+
::NewRelic::Agent.logger.error("Did not trace #{self.name}##{method_name} because that method does not exist") unless exists
|
331
329
|
exists
|
332
330
|
end
|
333
331
|
|
@@ -337,7 +335,7 @@ module NewRelic
|
|
337
335
|
# to help with debugging custom instrumentation.
|
338
336
|
def traced_method_exists?(method_name, metric_name_code)
|
339
337
|
exists = method_defined?(_traced_method_name(method_name, metric_name_code))
|
340
|
-
NewRelic::
|
338
|
+
::NewRelic::Agent.logger.error("Attempt to trace a method twice with the same metric: Method = #{method_name}, Metric Name = #{metric_name_code}") if exists
|
341
339
|
exists
|
342
340
|
end
|
343
341
|
|
@@ -488,7 +486,7 @@ module NewRelic
|
|
488
486
|
alias_method method_name, _traced_method_name(method_name, metric_name_code)
|
489
487
|
send visibility, method_name
|
490
488
|
send visibility, _traced_method_name(method_name, metric_name_code)
|
491
|
-
NewRelic::
|
489
|
+
::NewRelic::Agent.logger.debug("Traced method: class = #{self.name},"+
|
492
490
|
"method = #{method_name}, "+
|
493
491
|
"metric = '#{metric_name_code}'")
|
494
492
|
end
|
@@ -501,7 +499,7 @@ module NewRelic
|
|
501
499
|
if method_defined? "#{_traced_method_name(method_name, metric_name_code)}"
|
502
500
|
alias_method method_name, "#{_untraced_method_name(method_name, metric_name_code)}"
|
503
501
|
undef_method "#{_traced_method_name(method_name, metric_name_code)}"
|
504
|
-
NewRelic::
|
502
|
+
::NewRelic::Agent.logger.debug("removed method tracer #{method_name} #{metric_name_code}\n")
|
505
503
|
else
|
506
504
|
raise "No tracer for '#{metric_name_code}' on method '#{method_name}'"
|
507
505
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'zlib'
|
2
|
+
require 'new_relic/agent/audit_logger'
|
2
3
|
|
3
4
|
module NewRelic
|
4
5
|
module Agent
|
@@ -23,18 +24,24 @@ module NewRelic
|
|
23
24
|
@license_key = license_key || Agent.config[:license_key]
|
24
25
|
@collector = collector
|
25
26
|
@request_timeout = Agent.config[:timeout]
|
26
|
-
load_marshaller
|
27
|
-
end
|
28
27
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
28
|
+
@audit_logger = ::NewRelic::Agent::AuditLogger.new(Agent.config)
|
29
|
+
Agent.config.register_callback(:'audit_log.enabled') do |enabled|
|
30
|
+
@audit_logger.enabled = enabled
|
31
|
+
end
|
32
|
+
|
33
|
+
Agent.config.register_callback(:marshaller) do |marshaller|
|
34
|
+
begin
|
35
|
+
if marshaller == 'json'
|
36
|
+
require 'json'
|
37
|
+
@marshaller = JsonMarshaller.new
|
38
|
+
else
|
39
|
+
@marshaller = PrubyMarshaller.new
|
40
|
+
end
|
41
|
+
rescue LoadError
|
42
|
+
@marshaller = PrubyMarshaller.new
|
43
|
+
end
|
35
44
|
end
|
36
|
-
rescue LoadError
|
37
|
-
@marshaller = PrubyMarshaller.new
|
38
45
|
end
|
39
46
|
|
40
47
|
def connect(settings={})
|
@@ -72,7 +79,7 @@ module NewRelic
|
|
72
79
|
end
|
73
80
|
|
74
81
|
def profile_data(profile)
|
75
|
-
invoke_remote(:profile_data, @agent_id, profile
|
82
|
+
invoke_remote(:profile_data, @agent_id, profile) || ''
|
76
83
|
end
|
77
84
|
|
78
85
|
def get_agent_commands
|
@@ -86,6 +93,19 @@ module NewRelic
|
|
86
93
|
invoke_remote(:agent_command_results, @agent_id, { command_id.to_s => results })
|
87
94
|
end
|
88
95
|
|
96
|
+
# We do not compress if content is smaller than 64kb. There are
|
97
|
+
# problems with bugs in Ruby in some versions that expose us
|
98
|
+
# to a risk of segfaults if we compress aggressively.
|
99
|
+
def compress_request_if_needed(data)
|
100
|
+
encoding = 'identity'
|
101
|
+
if data.size > 64 * 1024
|
102
|
+
data = Encoders::Compressed.encode(data)
|
103
|
+
encoding = 'deflate'
|
104
|
+
end
|
105
|
+
check_post_size(data)
|
106
|
+
[data, encoding]
|
107
|
+
end
|
108
|
+
|
89
109
|
private
|
90
110
|
|
91
111
|
# A shorthand for NewRelic::Control.instance
|
@@ -93,11 +113,6 @@ module NewRelic
|
|
93
113
|
NewRelic::Control.instance
|
94
114
|
end
|
95
115
|
|
96
|
-
# Shorthand to the NewRelic::Agent.logger method
|
97
|
-
def log
|
98
|
-
NewRelic::Agent.logger
|
99
|
-
end
|
100
|
-
|
101
116
|
# The path on the server that we should post our data to
|
102
117
|
def remote_method_uri(method, format='ruby')
|
103
118
|
params = {'run_id' => @agent_id, 'marshal_format' => format}
|
@@ -117,15 +132,19 @@ module NewRelic
|
|
117
132
|
now = Time.now
|
118
133
|
|
119
134
|
data = @marshaller.dump(args)
|
120
|
-
|
135
|
+
data, encoding = compress_request_if_needed(data)
|
136
|
+
|
137
|
+
uri = remote_method_uri(method, @marshaller.format)
|
138
|
+
full_uri = "#{@collector}#{uri}"
|
139
|
+
|
140
|
+
@audit_logger.log_request(full_uri, args, @marshaller)
|
121
141
|
response = send_request(:data => data,
|
122
|
-
:uri =>
|
123
|
-
|
124
|
-
:encoding => @marshaller.encoding,
|
142
|
+
:uri => uri,
|
143
|
+
:encoding => encoding,
|
125
144
|
:collector => @collector)
|
126
145
|
@marshaller.load(decompress_response(response))
|
127
146
|
rescue NewRelic::Agent::ForceRestartException => e
|
128
|
-
|
147
|
+
::NewRelic::Agent.logger.debug e.message
|
129
148
|
raise
|
130
149
|
ensure
|
131
150
|
record_supportability_metrics(method, now)
|
@@ -140,48 +159,11 @@ module NewRelic
|
|
140
159
|
record_data_point((Time.now - now).to_f)
|
141
160
|
end
|
142
161
|
|
143
|
-
# This method handles the compression of the request body that
|
144
|
-
# we are going to send to the server
|
145
|
-
#
|
146
|
-
# We currently optimize for CPU here since we get roughly a 10x
|
147
|
-
# reduction in message size with this, and CPU overhead is at a
|
148
|
-
# premium. For extra-large posts, we use the higher compression
|
149
|
-
# since otherwise it actually errors out.
|
150
|
-
#
|
151
|
-
# We do not compress if content is smaller than 64kb. There are
|
152
|
-
# problems with bugs in Ruby in some versions that expose us
|
153
|
-
# to a risk of segfaults if we compress aggressively.
|
154
|
-
#
|
155
|
-
# medium payloads get fast compression, to save CPU
|
156
|
-
# big payloads get all the compression possible, to stay under
|
157
|
-
# the 2,000,000 byte post threshold
|
158
|
-
def compress_data(object)
|
159
|
-
dump = marshal_data(object)
|
160
|
-
|
161
|
-
return [dump, 'identity'] if dump.size < (64*1024)
|
162
|
-
|
163
|
-
compressed_dump = Zlib::Deflate.deflate(dump, Zlib::DEFAULT_COMPRESSION)
|
164
|
-
|
165
|
-
# this checks to make sure mongrel won't choke on big uploads
|
166
|
-
check_post_size(compressed_dump)
|
167
|
-
|
168
|
-
[compressed_dump, 'deflate']
|
169
|
-
end
|
170
|
-
|
171
|
-
def marshal_data(data)
|
172
|
-
NewRelic::LanguageSupport.with_cautious_gc do
|
173
|
-
Marshal.dump(data)
|
174
|
-
end
|
175
|
-
rescue => e
|
176
|
-
log.debug("#{e.class.name} : #{e.message} when marshalling #{object}")
|
177
|
-
raise
|
178
|
-
end
|
179
|
-
|
180
162
|
# Raises an UnrecoverableServerException if the post_string is longer
|
181
163
|
# than the limit configured in the control object
|
182
164
|
def check_post_size(post_string)
|
183
165
|
return if post_string.size < Agent.config[:post_size_limit]
|
184
|
-
|
166
|
+
::NewRelic::Agent.logger.debug "Tried to send too much data: #{post_string.size} bytes"
|
185
167
|
raise UnrecoverableServerException.new('413 Request Entity Too Large')
|
186
168
|
end
|
187
169
|
|
@@ -201,7 +183,7 @@ module NewRelic
|
|
201
183
|
request.content_type = "application/octet-stream"
|
202
184
|
request.body = opts[:data]
|
203
185
|
|
204
|
-
|
186
|
+
::NewRelic::Agent.logger.debug "Connect to #{opts[:collector]}#{opts[:uri]}"
|
205
187
|
|
206
188
|
response = nil
|
207
189
|
http = control.http_connection(@collector)
|
@@ -211,7 +193,7 @@ module NewRelic
|
|
211
193
|
response = http.request(request)
|
212
194
|
end
|
213
195
|
rescue Timeout::Error
|
214
|
-
|
196
|
+
::NewRelic::Agent.logger.warn "Timed out trying to post data to New Relic (timeout = #{@request_timeout} seconds)" unless @request_timeout < 30
|
215
197
|
raise
|
216
198
|
end
|
217
199
|
if response.is_a? Net::HTTPUnauthorized
|
@@ -219,7 +201,7 @@ module NewRelic
|
|
219
201
|
elsif response.is_a? Net::HTTPServiceUnavailable
|
220
202
|
raise ServerConnectionException, "Service unavailable (#{response.code}): #{response.message}"
|
221
203
|
elsif response.is_a? Net::HTTPGatewayTimeOut
|
222
|
-
|
204
|
+
::NewRelic::Agent.logger.warn("Timed out getting response: #{response.message}")
|
223
205
|
raise Timeout::Error, response.message
|
224
206
|
elsif response.is_a? Net::HTTPRequestEntityTooLarge
|
225
207
|
raise UnrecoverableServerException, '413 Request Entity Too Large'
|
@@ -238,10 +220,10 @@ module NewRelic
|
|
238
220
|
# encoded, otherwise returns it verbatim
|
239
221
|
def decompress_response(response)
|
240
222
|
if response['content-encoding'] != 'gzip'
|
241
|
-
|
223
|
+
::NewRelic::Agent.logger.debug "Uncompressed content returned"
|
242
224
|
return response.body
|
243
225
|
end
|
244
|
-
|
226
|
+
::NewRelic::Agent.logger.debug "Decompressing return value"
|
245
227
|
i = Zlib::GzipReader.new(StringIO.new(response.body))
|
246
228
|
i.read
|
247
229
|
end
|
@@ -259,34 +241,27 @@ module NewRelic
|
|
259
241
|
"NewRelic-RubyAgent/#{NewRelic::VERSION::STRING} #{ruby_description}#{zlib_version}"
|
260
242
|
end
|
261
243
|
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
# big payloads get all the compression possible, to stay under
|
279
|
-
# the 2,000,000 byte post threshold
|
280
|
-
def compress(data, opts={})
|
281
|
-
if opts[:force] || data.size > 64 * 1024
|
282
|
-
data = Zlib::Deflate.deflate(data, Zlib::DEFAULT_COMPRESSION)
|
283
|
-
@encoding = 'deflate'
|
284
|
-
else
|
285
|
-
@encoding = 'identity'
|
244
|
+
module Encoders
|
245
|
+
module Identity
|
246
|
+
def self.encode(data)
|
247
|
+
data
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
module Compressed
|
252
|
+
def self.encode(data)
|
253
|
+
Zlib::Deflate.deflate(data, Zlib::DEFAULT_COMPRESSION)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
module Base64CompressedJSON
|
258
|
+
def self.encode(data)
|
259
|
+
Base64.encode64(Compressed.encode(JSON.dump(data)))
|
286
260
|
end
|
287
|
-
data
|
288
261
|
end
|
262
|
+
end
|
289
263
|
|
264
|
+
class Marshaller
|
290
265
|
def parsed_error(error)
|
291
266
|
error_class = error['error_type'].split('::') \
|
292
267
|
.inject(Module) {|mod,const| mod.const_get(const) }
|
@@ -295,18 +270,27 @@ module NewRelic
|
|
295
270
|
CollectorError.new("#{error['error_type']}: #{error['message']}")
|
296
271
|
end
|
297
272
|
|
298
|
-
|
299
|
-
|
300
|
-
def prepare(data)
|
273
|
+
def prepare(data, options={})
|
274
|
+
encoder = options[:encoder] || default_encoder
|
301
275
|
if data.respond_to?(:to_collector_array)
|
302
|
-
data.to_collector_array(
|
276
|
+
data.to_collector_array(encoder)
|
303
277
|
elsif data.kind_of?(Array)
|
304
|
-
data.map {|element| prepare(element) }
|
278
|
+
data.map { |element| prepare(element, options) }
|
305
279
|
else
|
306
280
|
data
|
307
281
|
end
|
308
282
|
end
|
309
283
|
|
284
|
+
def default_encoder
|
285
|
+
Encoders::Identity
|
286
|
+
end
|
287
|
+
|
288
|
+
def self.human_readable?
|
289
|
+
false
|
290
|
+
end
|
291
|
+
|
292
|
+
protected
|
293
|
+
|
310
294
|
def return_value(data)
|
311
295
|
if data.respond_to?(:has_key?)
|
312
296
|
if data.has_key?('exception')
|
@@ -315,7 +299,7 @@ module NewRelic
|
|
315
299
|
return data['return_value']
|
316
300
|
end
|
317
301
|
end
|
318
|
-
NewRelic::Agent.logger.debug("Unexpected response from collector: #{data}")
|
302
|
+
::NewRelic::Agent.logger.debug("Unexpected response from collector: #{data}")
|
319
303
|
nil
|
320
304
|
end
|
321
305
|
end
|
@@ -323,15 +307,15 @@ module NewRelic
|
|
323
307
|
# Primitive Ruby Object Notation which complies JSON format data strutures
|
324
308
|
class PrubyMarshaller < Marshaller
|
325
309
|
def initialize
|
326
|
-
NewRelic::Agent.logger.debug 'Using Pruby marshaller'
|
310
|
+
::NewRelic::Agent.logger.debug 'Using Pruby marshaller'
|
327
311
|
end
|
328
312
|
|
329
|
-
def dump(ruby)
|
313
|
+
def dump(ruby, opts={})
|
330
314
|
NewRelic::LanguageSupport.with_cautious_gc do
|
331
|
-
|
315
|
+
Marshal.dump(prepare(ruby, opts))
|
332
316
|
end
|
333
317
|
rescue => e
|
334
|
-
NewRelic::Agent.logger.debug("#{e.class.name} : #{e.message} when marshalling #{ruby.inspect}")
|
318
|
+
::NewRelic::Agent.logger.debug("#{e.class.name} : #{e.message} when marshalling #{ruby.inspect}")
|
335
319
|
raise
|
336
320
|
end
|
337
321
|
|
@@ -341,7 +325,7 @@ module NewRelic
|
|
341
325
|
return_value(Marshal.load(data))
|
342
326
|
end
|
343
327
|
rescue
|
344
|
-
NewRelic::Agent.logger.debug "Error encountered loading collector response: #{data}"
|
328
|
+
::NewRelic::Agent.logger.debug "Error encountered loading collector response: #{data}"
|
345
329
|
raise
|
346
330
|
end
|
347
331
|
|
@@ -357,23 +341,23 @@ module NewRelic
|
|
357
341
|
# Marshal collector protocol with JSON when available
|
358
342
|
class JsonMarshaller < Marshaller
|
359
343
|
def initialize
|
360
|
-
NewRelic::Agent.logger.debug 'Using JSON marshaller'
|
344
|
+
::NewRelic::Agent.logger.debug 'Using JSON marshaller'
|
361
345
|
end
|
362
346
|
|
363
|
-
def dump(ruby)
|
364
|
-
|
347
|
+
def dump(ruby, opts={})
|
348
|
+
JSON.dump(prepare(ruby, opts))
|
365
349
|
end
|
366
350
|
|
367
351
|
def load(data)
|
368
352
|
return unless data && data != ''
|
369
353
|
return_value(JSON.load(data))
|
370
354
|
rescue
|
371
|
-
NewRelic::Agent.logger.debug "Error encountered loading collector response: #{data}"
|
355
|
+
::NewRelic::Agent.logger.debug "Error encountered loading collector response: #{data}"
|
372
356
|
raise
|
373
357
|
end
|
374
358
|
|
375
|
-
def
|
376
|
-
|
359
|
+
def default_encoder
|
360
|
+
Encoders::Base64CompressedJSON
|
377
361
|
end
|
378
362
|
|
379
363
|
def format
|
@@ -383,6 +367,10 @@ module NewRelic
|
|
383
367
|
def self.is_supported?
|
384
368
|
RUBY_VERSION >= '1.9.2'
|
385
369
|
end
|
370
|
+
|
371
|
+
def self.human_readable?
|
372
|
+
true # for some definitions of 'human'
|
373
|
+
end
|
386
374
|
end
|
387
375
|
|
388
376
|
class CollectorError < StandardError; end
|