newrelic_rpm 3.3.5 → 3.4.0.beta1

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.

Files changed (41) hide show
  1. data/CHANGELOG +8 -5
  2. data/lib/new_relic/agent.rb +11 -3
  3. data/lib/new_relic/agent/agent.rb +68 -223
  4. data/lib/new_relic/agent/error_collector.rb +1 -1
  5. data/lib/new_relic/agent/instrumentation/resque.rb +80 -0
  6. data/lib/new_relic/agent/instrumentation/sinatra.rb +2 -0
  7. data/lib/new_relic/agent/new_relic_service.rb +221 -0
  8. data/lib/new_relic/agent/pipe_channel_manager.rb +151 -0
  9. data/lib/new_relic/agent/pipe_service.rb +57 -0
  10. data/lib/new_relic/agent/samplers/delayed_job_sampler.rb +4 -34
  11. data/lib/new_relic/agent/sql_sampler.rb +1 -5
  12. data/lib/new_relic/agent/stats_engine/transactions.rb +2 -2
  13. data/lib/new_relic/agent/transaction_sampler.rb +0 -2
  14. data/lib/new_relic/control/configuration.rb +1 -1
  15. data/lib/new_relic/control/instance_methods.rb +2 -1
  16. data/lib/new_relic/language_support.rb +26 -0
  17. data/lib/new_relic/transaction_sample.rb +2 -6
  18. data/lib/new_relic/version.rb +3 -3
  19. data/newrelic_rpm.gemspec +16 -5
  20. data/test/new_relic/agent/agent/connect_test.rb +39 -23
  21. data/test/new_relic/agent/agent_test.rb +25 -4
  22. data/test/new_relic/agent/database_test.rb +12 -0
  23. data/test/new_relic/agent/new_relic_service_test.rb +151 -0
  24. data/test/new_relic/agent/pipe_channel_manager_test.rb +114 -0
  25. data/test/new_relic/agent/pipe_service_test.rb +113 -0
  26. data/test/new_relic/agent/rpm_agent_test.rb +3 -30
  27. data/test/new_relic/agent/transaction_sample_builder_test.rb +0 -1
  28. data/test/new_relic/agent/transaction_sampler_test.rb +6 -6
  29. data/test/new_relic/agent/worker_loop_test.rb +2 -2
  30. data/test/new_relic/agent_test.rb +73 -3
  31. data/test/new_relic/control/configuration_test.rb +0 -7
  32. data/test/new_relic/control_test.rb +3 -3
  33. data/test/new_relic/delayed_job_injection_test.rb +6 -1
  34. data/test/new_relic/fake_collector.rb +210 -0
  35. data/test/new_relic/fake_service.rb +44 -0
  36. data/test/script/ci.sh +6 -6
  37. data/test/script/ci_agent-tests_runner.sh +82 -0
  38. data/test/script/ci_multiverse_runner.sh +35 -0
  39. data/test/test_contexts.rb +1 -0
  40. data/test/test_helper.rb +3 -1
  41. metadata +359 -324
data/CHANGELOG CHANGED
@@ -1,12 +1,15 @@
1
+ v3.4.0
2
+ * Major refactor of data transmission mechanism. This enabled child processes to send data to parent processes, which then send the data to the New Relic service. This should only affect Resque users, dramatically improving their experience.
3
+ * Moved Resque instrumentation from rpm_contrib to main agent. Resque users should discontinue use of rpm_contrib or upgrade to 2.1.11.
4
+
1
5
  v3.3.5
2
- * [FIX] Allow tracing of methods ending in ! and ?
6
+ * [FIX] Allow tracing of ! and ? methods
3
7
  * [PERF] Give up after scanning first 50k of the response in RUM
4
8
  auto-instrumentation.
5
- * [FIX] Don't raise when extracting metrics from SQL queries with non UTF-8 bytes.
6
- * Replaced "Custom/DJ Locked Jobs" metric with new metrics for
9
+ * [FIX] Don't raise when extracting metrics from SQL queries with non UTF-8
10
+ * bytes. Replaced "Custom/DJ Locked Jobs" metric with three new metrics for
7
11
  monitoring DelayedJob: queue_length, failed_jobs, and locked_jobs, all under
8
- Workers/DelayedJob. queue_length is also broken out by queue name or priority
9
- depending on the version of DelayedJob deployed.
12
+ Workers/DelayedJob
10
13
 
11
14
  v3.3.4.1
12
15
  * Bug fix when rendering empty collection in Rails 3.1+
@@ -1,5 +1,7 @@
1
+ require 'forwardable'
1
2
  require 'new_relic/control'
2
3
  require 'new_relic/data_serialization'
4
+
3
5
  # = New Relic Ruby Agent
4
6
  #
5
7
  # New Relic is a performance monitoring application for applications
@@ -58,7 +60,8 @@ module NewRelic
58
60
  # support at New Relic for help.
59
61
  module Agent
60
62
  extend self
61
-
63
+ extend Forwardable
64
+
62
65
  require 'new_relic/version'
63
66
  require 'new_relic/local_environment'
64
67
  require 'new_relic/stats'
@@ -86,6 +89,7 @@ module NewRelic
86
89
  require 'new_relic/agent/busy_calculator'
87
90
  require 'new_relic/agent/sampler'
88
91
  require 'new_relic/agent/database'
92
+ require 'new_relic/agent/pipe_channel_manager'
89
93
  require 'new_relic/agent/transaction_info'
90
94
 
91
95
  require 'new_relic/agent/instrumentation/controller_instrumentation'
@@ -152,7 +156,7 @@ module NewRelic
152
156
  # a standard output logger is returned.
153
157
  def logger
154
158
  control = NewRelic::Control.instance(false)
155
- if control
159
+ if control && control.log
156
160
  control.log
157
161
  else
158
162
  require 'logger'
@@ -177,6 +181,9 @@ module NewRelic
177
181
  #
178
182
  def manual_start(options={})
179
183
  raise "Options must be a hash" unless Hash === options
184
+ if options[:start_channel_listener]
185
+ NewRelic::Agent::PipeChannelManager.listener.start
186
+ end
180
187
  NewRelic::Control.instance.init_plugin({ :agent_enabled => true, :sync_startup => true }.merge(options))
181
188
  end
182
189
 
@@ -462,6 +469,7 @@ module NewRelic
462
469
  def browser_timing_footer
463
470
  agent.browser_timing_footer
464
471
  end
465
-
472
+
473
+ def_delegator :'NewRelic::Agent::PipeChannelManager', :register_report_channel
466
474
  end
467
475
  end
@@ -5,6 +5,8 @@ require 'logger'
5
5
  require 'zlib'
6
6
  require 'stringio'
7
7
  require 'new_relic/data_serialization'
8
+ require 'new_relic/agent/new_relic_service'
9
+ require 'new_relic/agent/pipe_service'
8
10
 
9
11
  module NewRelic
10
12
  module Agent
@@ -14,22 +16,7 @@ module NewRelic
14
16
  # in realtime as the application runs, and periodically sends that
15
17
  # data to the NewRelic server.
16
18
  class Agent
17
-
18
- # Specifies the version of the agent's communication protocol with
19
- # the NewRelic hosted site.
20
-
21
- PROTOCOL_VERSION = 8
22
- # 14105: v8 (tag 2.10.3)
23
- # (no v7)
24
- # 10379: v6 (not tagged)
25
- # 4078: v5 (tag 2.5.4)
26
- # 2292: v4 (tag 2.3.6)
27
- # 1754: v3 (tag 2.3.0)
28
- # 534: v2 (shows up in 2.1.0, our first tag)
29
-
30
-
31
19
  def initialize
32
-
33
20
  @launch_time = Time.now
34
21
 
35
22
  @metric_ids = {}
@@ -40,12 +27,13 @@ module NewRelic
40
27
  @error_collector = NewRelic::Agent::ErrorCollector.new
41
28
  @connect_attempts = 0
42
29
 
43
- @request_timeout = NewRelic::Control.instance.fetch('timeout', 2 * 60)
44
-
45
30
  @last_harvest_time = Time.now
46
31
  @obfuscator = lambda {|sql| NewRelic::Agent::Database.default_sql_obfuscator(sql) }
32
+ @forked = false
33
+
34
+ @service = NewRelic::Agent::NewRelicService.new(control.license_key, control.server)
47
35
  end
48
-
36
+
49
37
  # contains all the class-level methods for NewRelic::Agent::Agent
50
38
  module ClassMethods
51
39
  # Should only be called by NewRelic::Control - returns a
@@ -81,6 +69,7 @@ module NewRelic
81
69
  # handles things like static setup of the header for inclusion
82
70
  # into pages
83
71
  attr_reader :beacon_configuration
72
+ attr_accessor :service
84
73
 
85
74
  # Returns the length of the unsent errors array, if it exists,
86
75
  # otherwise nil
@@ -158,11 +147,16 @@ module NewRelic
158
147
  # connection, this tells me to only try it once so this method returns
159
148
  # quickly if there is some kind of latency with the server.
160
149
  def after_fork(options={})
161
-
150
+ @forked = true
162
151
  # @connected gets false after we fail to connect or have an error
163
152
  # connecting. @connected has nil if we haven't finished trying to connect.
164
153
  # or we didn't attempt a connection because this is the master process
165
-
154
+
155
+ if channel_id = options[:report_to_channel]
156
+ @service = NewRelic::Agent::PipeService.new(channel_id)
157
+ @connected_pid = $$
158
+ end
159
+
166
160
  # log.debug "Agent received after_fork notice in #$$: [#{control.agent_enabled?}; monitor=#{control.monitor_mode?}; connected: #{@connected.inspect}; thread=#{@worker_thread.inspect}]"
167
161
  return if !control.agent_enabled? or
168
162
  !control.monitor_mode? or
@@ -179,7 +173,11 @@ module NewRelic
179
173
  start_worker_thread(options)
180
174
  @stats_engine.start_sampler_thread
181
175
  end
182
-
176
+
177
+ def forked?
178
+ @forked
179
+ end
180
+
183
181
  # True if we have initialized and completed 'start'
184
182
  def started?
185
183
  @started
@@ -203,25 +201,25 @@ module NewRelic
203
201
  if @worker_loop
204
202
  @worker_loop.run_task if run_loop_before_exit
205
203
  @worker_loop.stop
204
+ end
206
205
 
207
- log.debug "Starting Agent shutdown"
206
+ log.debug "Starting Agent shutdown"
208
207
 
209
- # if litespeed, then ignore all future SIGUSR1 - it's
210
- # litespeed trying to shut us down
208
+ # if litespeed, then ignore all future SIGUSR1 - it's
209
+ # litespeed trying to shut us down
211
210
 
212
- if control.dispatcher == :litespeed
213
- Signal.trap("SIGUSR1", "IGNORE")
214
- Signal.trap("SIGTERM", "IGNORE")
215
- end
211
+ if control.dispatcher == :litespeed
212
+ Signal.trap("SIGUSR1", "IGNORE")
213
+ Signal.trap("SIGTERM", "IGNORE")
214
+ end
216
215
 
217
- begin
218
- NewRelic::Agent.disable_all_tracing do
219
- graceful_disconnect
220
- end
221
- rescue => e
222
- log.error e
223
- log.error e.backtrace.join("\n")
216
+ begin
217
+ NewRelic::Agent.disable_all_tracing do
218
+ graceful_disconnect
224
219
  end
220
+ rescue => e
221
+ log.error e
222
+ log.error e.backtrace.join("\n")
225
223
  end
226
224
  @started = nil
227
225
  end
@@ -446,9 +444,9 @@ module NewRelic
446
444
  end
447
445
 
448
446
  private
449
- def collector
450
- @collector ||= control.server
451
- end
447
+ # def collector
448
+ # @collector ||= control.collector
449
+ # end
452
450
 
453
451
  # All of this module used to be contained in the
454
452
  # start_worker_thread method - this is an artifact of
@@ -717,7 +715,7 @@ module NewRelic
717
715
  # connect data passed back from the server
718
716
  def connect_to_server
719
717
  log_seed_token
720
- connect_data = invoke_remote(:connect, connect_settings)
718
+ @service.connect(connect_settings)
721
719
  end
722
720
 
723
721
  # Configures the error collector if the server says that we
@@ -834,18 +832,16 @@ module NewRelic
834
832
  # should be reporting to, and then does the name resolution
835
833
  # on that host so we don't block on DNS during the normal
836
834
  # course of agent processing
837
- def set_collector_host!
838
- host = invoke_remote(:get_redirect_host)
839
- if host
840
- @collector = control.server_from_host(host)
841
- end
842
- end
835
+ # def set_collector_host!
836
+ # host = invoke_remote(:get_redirect_host)
837
+ # if host
838
+ # @collector = control.server_from_host(host)
839
+ # end
840
+ # end
843
841
 
844
842
  # Sets the collector host and connects to the server, then
845
843
  # invokes the final configuration with the returned data
846
844
  def query_server_for_configuration
847
- set_collector_host!
848
-
849
845
  finish_setup(connect_to_server)
850
846
  end
851
847
 
@@ -857,7 +853,8 @@ module NewRelic
857
853
  # Can accommodate most arbitrary data - anything extra is
858
854
  # ignored unless we say to do something with it here.
859
855
  def finish_setup(config_data)
860
- @agent_id = config_data['agent_run_id']
856
+ return if config_data == nil
857
+ @service.agent_id = config_data['agent_run_id']
861
858
  @report_period = config_data['data_report_period']
862
859
  @url_rules = config_data['url_rules']
863
860
  @beacon_configuration = BeaconConfiguration.new(config_data)
@@ -878,8 +875,8 @@ module NewRelic
878
875
  # Logs when we connect to the server, for debugging purposes
879
876
  # - makes sure we know if an agent has not connected
880
877
  def log_connection!(config_data)
881
- control.log! "Connected to NewRelic Service at #{@collector}"
882
- log.debug "Agent Run = #{@agent_id}."
878
+ control.log! "Connected to NewRelic Service at #{@service.collector.name}"
879
+ log.debug "Agent Run = #{@service.agent_id}."
883
880
  log.debug "Connection data = #{config_data.inspect}"
884
881
  end
885
882
  end
@@ -909,14 +906,15 @@ module NewRelic
909
906
  def merge_data_from(data)
910
907
  metrics, transaction_traces, errors = data
911
908
  @stats_engine.merge_data(metrics) if metrics
912
- if transaction_traces
909
+ if transaction_traces && transaction_traces.respond_to?(:any?) &&
910
+ transaction_traces.any?
913
911
  if @traces
914
- @traces = @traces + transaction_traces
912
+ @traces += transaction_traces
915
913
  else
916
914
  @traces = transaction_traces
917
915
  end
918
916
  end
919
- if errors
917
+ if errors && errors.respond_to?(:any?) && errors.any?
920
918
  if @unsent_errors
921
919
  @unsent_errors = @unsent_errors + errors
922
920
  else
@@ -1014,22 +1012,14 @@ module NewRelic
1014
1012
  NewRelic::Agent.instance.stats_engine.get_stats_no_scope('Supportability/invoke_remote').record_data_point(0.0)
1015
1013
  NewRelic::Agent.instance.stats_engine.get_stats_no_scope('Supportability/invoke_remote/metric_data').record_data_point(0.0)
1016
1014
  harvest_timeslice_data(now)
1017
- begin
1018
- # In this version of the protocol, we get back an assoc array of spec to id.
1019
- metric_specs_and_ids = invoke_remote(:metric_data, @agent_id,
1020
- @last_harvest_time.to_f,
1021
- now.to_f,
1022
- @unsent_timeslice_data.values)
1023
-
1024
- rescue Timeout::Error
1025
- # assume that the data was received. chances are that it
1026
- # was. Also, lol.
1027
- metric_specs_and_ids = []
1028
- end
1029
-
1015
+ # In this version of the protocol, we get back an assoc array of spec to id.
1016
+ metric_specs_and_ids = @service.metric_data(@last_harvest_time.to_f,
1017
+ now.to_f,
1018
+ @unsent_timeslice_data.values)
1019
+ metric_specs_and_ids ||= []
1030
1020
  fill_metric_id_cache(metric_specs_and_ids)
1031
1021
 
1032
- log.debug "#{now}: sent #{@unsent_timeslice_data.length} timeslices (#{@agent_id}) in #{Time.now - now} seconds"
1022
+ log.debug "#{now}: sent #{@unsent_timeslice_data.length} timeslices (#{@service.agent_id}) in #{Time.now - now} seconds"
1033
1023
 
1034
1024
  # if we successfully invoked this web service, then clear the unsent message cache.
1035
1025
  @unsent_timeslice_data = {}
@@ -1050,8 +1040,7 @@ module NewRelic
1050
1040
  unless sql_traces.empty?
1051
1041
  log.debug "Sending (#{sql_traces.size}) sql traces"
1052
1042
  begin
1053
- response = invoke_remote :sql_trace_data, sql_traces
1054
- # log.debug "Sql trace response: #{response}"
1043
+ @service.sql_trace_data(sql_traces)
1055
1044
  rescue
1056
1045
  @sql_sampler.merge sql_traces
1057
1046
  end
@@ -1077,14 +1066,14 @@ module NewRelic
1077
1066
  options[:explain_sql] = @transaction_sampler.explain_threshold
1078
1067
  end
1079
1068
  traces = @traces.collect {|trace| trace.prepare_to_send(options)}
1080
- invoke_remote :transaction_sample_data, @agent_id, traces
1069
+ @service.transaction_sample_data(traces)
1081
1070
  rescue PostTooBigException
1082
1071
  # we tried to send too much data, drop the first trace and
1083
1072
  # try again
1084
1073
  retry if @traces.shift
1085
1074
  end
1086
1075
 
1087
- log.debug "Sent slowest sample (#{@agent_id}) in #{Time.now - now} seconds"
1076
+ log.debug "Sent slowest sample (#{@service.agent_id}) in #{Time.now - now} seconds"
1088
1077
  end
1089
1078
 
1090
1079
  # if we succeed sending this sample, then we don't need to keep
@@ -1110,7 +1099,7 @@ module NewRelic
1110
1099
  if @unsent_errors && @unsent_errors.length > 0
1111
1100
  log.debug "Sending #{@unsent_errors.length} errors"
1112
1101
  begin
1113
- invoke_remote :error_data, @agent_id, @unsent_errors
1102
+ @service.error_data(@unsent_errors)
1114
1103
  rescue PostTooBigException
1115
1104
  @unsent_errors.shift
1116
1105
  retry
@@ -1122,153 +1111,7 @@ module NewRelic
1122
1111
  @unsent_errors = []
1123
1112
  end
1124
1113
  end
1125
-
1126
- # This method handles the compression of the request body that
1127
- # we are going to send to the server
1128
- #
1129
- # We currently optimize for CPU here since we get roughly a 10x
1130
- # reduction in message size with this, and CPU overhead is at a
1131
- # premium. For extra-large posts, we use the higher compression
1132
- # since otherwise it actually errors out.
1133
- #
1134
- # We do not compress if content is smaller than 64kb. There are
1135
- # problems with bugs in Ruby in some versions that expose us
1136
- # to a risk of segfaults if we compress aggressively.
1137
- #
1138
- # medium payloads get fast compression, to save CPU
1139
- # big payloads get all the compression possible, to stay under
1140
- # the 2,000,000 byte post threshold
1141
- def compress_data(object)
1142
- dump = Marshal.dump(object)
1143
-
1144
- dump_size = dump.size
1145
-
1146
- return [dump, 'identity'] if dump_size < (64*1024)
1147
-
1148
- compressed_dump = Zlib::Deflate.deflate(dump, Zlib::DEFAULT_COMPRESSION)
1149
-
1150
- # this checks to make sure mongrel won't choke on big uploads
1151
- check_post_size(compressed_dump)
1152
-
1153
- [compressed_dump, 'deflate']
1154
- end
1155
-
1156
- # Raises a PostTooBigException if the post_string is longer
1157
- # than the limit configured in the control object
1158
- def check_post_size(post_string)
1159
- # TODO: define this as a config option on the server side
1160
- return if post_string.size < control.post_size_limit
1161
- log.warn "Tried to send too much data: #{post_string.size} bytes"
1162
- raise PostTooBigException
1163
- end
1164
-
1165
- # Posts to the specified server
1166
- #
1167
- # Options:
1168
- # - :uri => the path to request on the server (a misnomer of
1169
- # course)
1170
- # - :encoding => the encoding to pass to the server
1171
- # - :collector => a URI object that responds to the 'name' method
1172
- # and returns the name of the collector to
1173
- # contact
1174
- # - :data => the data to send as the body of the request
1175
- def send_request(opts)
1176
- request = Net::HTTP::Post.new(opts[:uri], 'CONTENT-ENCODING' => opts[:encoding], 'HOST' => opts[:collector].name)
1177
- request['user-agent'] = user_agent
1178
- request.content_type = "application/octet-stream"
1179
- request.body = opts[:data]
1180
-
1181
- log.debug "Connect to #{opts[:collector]}#{opts[:uri]}"
1182
-
1183
- response = nil
1184
- http = control.http_connection(collector)
1185
- http.read_timeout = nil
1186
- begin
1187
- NewRelic::TimerLib.timeout(@request_timeout) do
1188
- response = http.request(request)
1189
- end
1190
- rescue Timeout::Error
1191
- log.warn "Timed out trying to post data to New Relic (timeout = #{@request_timeout} seconds)" unless @request_timeout < 30
1192
- raise
1193
- end
1194
- if response.is_a? Net::HTTPServiceUnavailable
1195
- raise NewRelic::Agent::ServerConnectionException, "Service unavailable (#{response.code}): #{response.message}"
1196
- elsif response.is_a? Net::HTTPGatewayTimeOut
1197
- log.debug("Timed out getting response: #{response.message}")
1198
- raise Timeout::Error, response.message
1199
- elsif response.is_a? Net::HTTPRequestEntityTooLarge
1200
- raise PostTooBigException
1201
- elsif !(response.is_a? Net::HTTPSuccess)
1202
- raise NewRelic::Agent::ServerConnectionException, "Unexpected response from server (#{response.code}): #{response.message}"
1203
- end
1204
- response
1205
- end
1206
-
1207
- # Decompresses the response from the server, if it is gzip
1208
- # encoded, otherwise returns it verbatim
1209
- def decompress_response(response)
1210
- if response['content-encoding'] != 'gzip'
1211
- log.debug "Uncompressed content returned"
1212
- return response.body
1213
- end
1214
- log.debug "Decompressing return value"
1215
- i = Zlib::GzipReader.new(StringIO.new(response.body))
1216
- i.read
1217
- end
1218
-
1219
- # unmarshals the response and raises it if it is an exception,
1220
- # so we can handle it in nonlocally
1221
- def check_for_exception(response)
1222
- dump = decompress_response(response)
1223
- value = Marshal.load(dump)
1224
- raise value if value.is_a? Exception
1225
- value
1226
- end
1227
-
1228
- # The path on the server that we should post our data to
1229
- def remote_method_uri(method)
1230
- uri = "/agent_listener/#{PROTOCOL_VERSION}/#{control.license_key}/#{method}"
1231
- uri << "?run_id=#{@agent_id}" if @agent_id
1232
- uri
1233
- end
1234
-
1235
- # Sets the user agent for connections to the server, to
1236
- # conform with the HTTP spec and allow for debugging. Includes
1237
- # the ruby version and also zlib version if available since
1238
- # that may cause corrupt compression if there is a problem.
1239
- def user_agent
1240
- ruby_description = ''
1241
- # note the trailing space!
1242
- ruby_description << "(ruby #{::RUBY_VERSION} #{::RUBY_PLATFORM}) " if defined?(::RUBY_VERSION) && defined?(::RUBY_PLATFORM)
1243
- zlib_version = ''
1244
- zlib_version << "zlib/#{Zlib.zlib_version}" if defined?(::Zlib) && Zlib.respond_to?(:zlib_version)
1245
- "NewRelic-RubyAgent/#{NewRelic::VERSION::STRING} #{ruby_description}#{zlib_version}"
1246
- end
1247
-
1248
- # send a message via post to the actual server. This attempts
1249
- # to automatically compress the data via zlib if it is large
1250
- # enough to be worth compressing, and handles any errors the
1251
- # server may return
1252
- def invoke_remote(method, *args)
1253
- now = Time.now
1254
- #determines whether to zip the data or send plain
1255
- post_data, encoding = compress_data(args)
1256
-
1257
- response = send_request({:uri => remote_method_uri(method), :encoding => encoding, :collector => collector, :data => post_data})
1258
-
1259
- # raises the right exception if the remote server tells it to die
1260
- return check_for_exception(response)
1261
- rescue NewRelic::Agent::ForceRestartException => e
1262
- log.info e.message
1263
- raise
1264
- rescue SystemCallError, SocketError => e
1265
- # These include Errno connection errors
1266
- raise NewRelic::Agent::ServerConnectionException, "Recoverable error connecting to the server: #{e}"
1267
- ensure
1268
- NewRelic::Agent.instance.stats_engine.get_stats_no_scope('Supportability/invoke_remote').record_data_point((Time.now - now).to_f)
1269
- NewRelic::Agent.instance.stats_engine.get_stats_no_scope('Supportability/invoke_remote/' + method.to_s).record_data_point((Time.now - now).to_f)
1270
- end
1271
-
1114
+
1272
1115
  def save_or_transmit_data
1273
1116
  if NewRelic::DataSerialization.should_send_data?
1274
1117
  log.debug "Sending data to New Relic Service"
@@ -1288,6 +1131,8 @@ module NewRelic
1288
1131
  retry_count += 1
1289
1132
  retry unless retry_count > 1
1290
1133
  raise e
1134
+ ensure
1135
+ NewRelic::Agent::Database.close_connections unless forked?
1291
1136
  end
1292
1137
 
1293
1138
  # This method contacts the server to send remaining data and
@@ -1300,11 +1145,11 @@ module NewRelic
1300
1145
  def graceful_disconnect
1301
1146
  if @connected
1302
1147
  begin
1303
- @request_timeout = 10
1148
+ @service.request_timeout = 10
1304
1149
  save_or_transmit_data
1305
- if @connected_pid == $$
1150
+ if @connected_pid == $$ && !@service.kind_of?(NewRelic::Agent::NewRelicService)
1306
1151
  log.debug "Sending New Relic service agent run shutdown message"
1307
- invoke_remote :shutdown, @agent_id, Time.now.to_f
1152
+ @service.shutdown(Time.now.to_f)
1308
1153
  else
1309
1154
  log.debug "This agent connected from parent process #{@connected_pid}--not sending shutdown"
1310
1155
  end
@@ -1316,7 +1161,7 @@ module NewRelic
1316
1161
  end
1317
1162
  end
1318
1163
  end
1319
-
1164
+
1320
1165
  extend ClassMethods
1321
1166
  include InstanceMethods
1322
1167
  include BrowserMonitoring