newrelic_rpm 2.10.8 → 2.11.0.beta

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 (212) hide show
  1. data/CHANGELOG +15 -3
  2. data/lib/new_relic/agent.rb +17 -6
  3. data/lib/new_relic/agent/agent.rb +98 -77
  4. data/lib/new_relic/agent/busy_calculator.rb +1 -1
  5. data/lib/new_relic/agent/error_collector.rb +6 -3
  6. data/lib/new_relic/agent/instrumentation/active_record_instrumentation.rb +1 -0
  7. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +0 -2
  8. data/lib/new_relic/agent/instrumentation/memcache.rb +0 -1
  9. data/lib/new_relic/agent/instrumentation/metric_frame.rb +8 -2
  10. data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +3 -3
  11. data/lib/new_relic/agent/instrumentation/unicorn_instrumentation.rb +10 -0
  12. data/lib/new_relic/agent/method_tracer.rb +1 -1
  13. data/lib/new_relic/agent/shim_agent.rb +1 -1
  14. data/lib/new_relic/agent/stats_engine.rb +1 -1
  15. data/lib/new_relic/agent/stats_engine/samplers.rb +2 -2
  16. data/lib/new_relic/control.rb +6 -3
  17. data/lib/new_relic/rack/metric_app.rb +4 -4
  18. data/lib/new_relic/version.rb +3 -3
  19. data/newrelic.yml +3 -3
  20. data/newrelic_rpm.gemspec +4 -192
  21. data/test/new_relic/agent/rpm_agent_test.rb +15 -2
  22. data/test/new_relic/agent/task_instrumentation_test.rb +3 -2
  23. metadata +12 -197
  24. data/rdoc/classes/NewRelic.html +0 -293
  25. data/rdoc/classes/NewRelic/Agent.html +0 -810
  26. data/rdoc/classes/NewRelic/Agent/Agent.html +0 -742
  27. data/rdoc/classes/NewRelic/Agent/BackgroundLoadingError.html +0 -111
  28. data/rdoc/classes/NewRelic/Agent/BusyCalculator.html +0 -309
  29. data/rdoc/classes/NewRelic/Agent/CollectionHelper.html +0 -196
  30. data/rdoc/classes/NewRelic/Agent/ErrorCollector.html +0 -378
  31. data/rdoc/classes/NewRelic/Agent/ForceDisconnectException.html +0 -118
  32. data/rdoc/classes/NewRelic/Agent/ForceRestartException.html +0 -117
  33. data/rdoc/classes/NewRelic/Agent/IgnoreSilentlyException.html +0 -118
  34. data/rdoc/classes/NewRelic/Agent/Instrumentation.html +0 -174
  35. data/rdoc/classes/NewRelic/Agent/Instrumentation/ActiveRecordInstrumentation.html +0 -221
  36. data/rdoc/classes/NewRelic/Agent/Instrumentation/ControllerInstrumentation.html +0 -349
  37. data/rdoc/classes/NewRelic/Agent/Instrumentation/ControllerInstrumentation/ClassMethods.html +0 -277
  38. data/rdoc/classes/NewRelic/Agent/Instrumentation/DelayedJobInstrumentation.html +0 -112
  39. data/rdoc/classes/NewRelic/Agent/Instrumentation/MetricFrame.html +0 -1007
  40. data/rdoc/classes/NewRelic/Agent/Instrumentation/Rack.html +0 -321
  41. data/rdoc/classes/NewRelic/Agent/Instrumentation/Sinatra.html +0 -176
  42. data/rdoc/classes/NewRelic/Agent/LicenseException.html +0 -117
  43. data/rdoc/classes/NewRelic/Agent/MethodTracer.html +0 -150
  44. data/rdoc/classes/NewRelic/Agent/MethodTracer/ClassMethods.html +0 -295
  45. data/rdoc/classes/NewRelic/Agent/MethodTracer/InstanceMethods.html +0 -284
  46. data/rdoc/classes/NewRelic/Agent/PostTooBigException.html +0 -120
  47. data/rdoc/classes/NewRelic/Agent/Sampler.html +0 -314
  48. data/rdoc/classes/NewRelic/Agent/Sampler/Unsupported.html +0 -117
  49. data/rdoc/classes/NewRelic/Agent/Samplers.html +0 -126
  50. data/rdoc/classes/NewRelic/Agent/Samplers/CpuSampler.html +0 -327
  51. data/rdoc/classes/NewRelic/Agent/Samplers/DelayedJobLockSampler.html +0 -296
  52. data/rdoc/classes/NewRelic/Agent/Samplers/MemorySampler.html +0 -321
  53. data/rdoc/classes/NewRelic/Agent/Samplers/MemorySampler/Base.html +0 -186
  54. data/rdoc/classes/NewRelic/Agent/Samplers/MemorySampler/JavaHeapSampler.html +0 -173
  55. data/rdoc/classes/NewRelic/Agent/Samplers/MemorySampler/ProcStatus.html +0 -216
  56. data/rdoc/classes/NewRelic/Agent/Samplers/MemorySampler/ShellPS.html +0 -207
  57. data/rdoc/classes/NewRelic/Agent/Samplers/ObjectSampler.html +0 -222
  58. data/rdoc/classes/NewRelic/Agent/ServerError.html +0 -117
  59. data/rdoc/classes/NewRelic/Agent/ShimAgent.html +0 -297
  60. data/rdoc/classes/NewRelic/Agent/StatsEngine.html +0 -204
  61. data/rdoc/classes/NewRelic/Agent/StatsEngine/MetricStats.html +0 -441
  62. data/rdoc/classes/NewRelic/Agent/StatsEngine/Samplers.html +0 -237
  63. data/rdoc/classes/NewRelic/Agent/StatsEngine/ScopeStackElement.html +0 -178
  64. data/rdoc/classes/NewRelic/Agent/StatsEngine/Transactions.html +0 -385
  65. data/rdoc/classes/NewRelic/Agent/TransactionSampleBuilder.html +0 -505
  66. data/rdoc/classes/NewRelic/Agent/TransactionSampler.html +0 -690
  67. data/rdoc/classes/NewRelic/Agent/WorkerLoop.html +0 -305
  68. data/rdoc/classes/NewRelic/Agent/WorkerLoop/LoopTask.html +0 -224
  69. data/rdoc/classes/NewRelic/ApdexStats.html +0 -196
  70. data/rdoc/classes/NewRelic/BasicStats.html +0 -113
  71. data/rdoc/classes/NewRelic/ChainedCall.html +0 -180
  72. data/rdoc/classes/NewRelic/Commands.html +0 -112
  73. data/rdoc/classes/NewRelic/Commands/CommandFailure.html +0 -167
  74. data/rdoc/classes/NewRelic/Commands/Deployments.html +0 -285
  75. data/rdoc/classes/NewRelic/Control.html +0 -1760
  76. data/rdoc/classes/NewRelic/Control/External.html +0 -148
  77. data/rdoc/classes/NewRelic/Control/Merb.html +0 -227
  78. data/rdoc/classes/NewRelic/Control/Rails.html +0 -542
  79. data/rdoc/classes/NewRelic/Control/Ruby.html +0 -266
  80. data/rdoc/classes/NewRelic/Control/Sinatra.html +0 -178
  81. data/rdoc/classes/NewRelic/DelayedJobInjection.html +0 -118
  82. data/rdoc/classes/NewRelic/Histogram.html +0 -226
  83. data/rdoc/classes/NewRelic/Histogram/Bucket.html +0 -319
  84. data/rdoc/classes/NewRelic/Histogram/Shim.html +0 -144
  85. data/rdoc/classes/NewRelic/LocalEnvironment.html +0 -572
  86. data/rdoc/classes/NewRelic/MerbBootLoader.html +0 -146
  87. data/rdoc/classes/NewRelic/MethodTraceStats.html +0 -250
  88. data/rdoc/classes/NewRelic/MetricData.html +0 -347
  89. data/rdoc/classes/NewRelic/MetricParser.html +0 -747
  90. data/rdoc/classes/NewRelic/MetricParser/ActionMailer.html +0 -170
  91. data/rdoc/classes/NewRelic/MetricParser/ActiveMerchant.html +0 -267
  92. data/rdoc/classes/NewRelic/MetricParser/ActiveRecord.html +0 -250
  93. data/rdoc/classes/NewRelic/MetricParser/Controller.html +0 -363
  94. data/rdoc/classes/NewRelic/MetricParser/ControllerCPU.html +0 -319
  95. data/rdoc/classes/NewRelic/MetricParser/Errors.html +0 -170
  96. data/rdoc/classes/NewRelic/MetricParser/External.html +0 -339
  97. data/rdoc/classes/NewRelic/MetricParser/MemCache.html +0 -340
  98. data/rdoc/classes/NewRelic/MetricParser/OtherTransaction.html +0 -205
  99. data/rdoc/classes/NewRelic/MetricParser/View.html +0 -381
  100. data/rdoc/classes/NewRelic/MetricParser/WebFrontend.html +0 -182
  101. data/rdoc/classes/NewRelic/MetricParser/WebService.html +0 -172
  102. data/rdoc/classes/NewRelic/MetricSpec.html +0 -406
  103. data/rdoc/classes/NewRelic/Metrics.html +0 -138
  104. data/rdoc/classes/NewRelic/NoticedError.html +0 -200
  105. data/rdoc/classes/NewRelic/Rack.html +0 -112
  106. data/rdoc/classes/NewRelic/Rack/MetricApp.html +0 -193
  107. data/rdoc/classes/NewRelic/Rack/Status.html +0 -165
  108. data/rdoc/classes/NewRelic/ScopedMethodTraceStats.html +0 -225
  109. data/rdoc/classes/NewRelic/Stats.html +0 -917
  110. data/rdoc/classes/NewRelic/StatsBase.html +0 -346
  111. data/rdoc/classes/NewRelic/TransactionAnalysis.html +0 -269
  112. data/rdoc/classes/NewRelic/TransactionAnalysis/SegmentSummary.html +0 -338
  113. data/rdoc/classes/NewRelic/TransactionSample.html +0 -766
  114. data/rdoc/classes/NewRelic/TransactionSample/CompositeSegment.html +0 -195
  115. data/rdoc/classes/NewRelic/TransactionSample/FakeSegment.html +0 -113
  116. data/rdoc/classes/NewRelic/TransactionSample/IDGenerator.html +0 -178
  117. data/rdoc/classes/NewRelic/TransactionSample/Segment.html +0 -920
  118. data/rdoc/classes/NewRelic/TransactionSample/SummarySegment.html +0 -180
  119. data/rdoc/classes/NewRelic/VersionNumber.html +0 -338
  120. data/rdoc/classes/NewRelicApi.html +0 -270
  121. data/rdoc/classes/NewRelicApi/Account.html +0 -178
  122. data/rdoc/classes/NewRelicApi/Account/AccountUsage.html +0 -111
  123. data/rdoc/classes/NewRelicApi/Account/AccountView.html +0 -146
  124. data/rdoc/classes/NewRelicApi/Application.html +0 -139
  125. data/rdoc/classes/NewRelicApi/Application/Agent.html +0 -119
  126. data/rdoc/classes/NewRelicApi/Deployment.html +0 -123
  127. data/rdoc/classes/NewRelicApi/Subscription.html +0 -111
  128. data/rdoc/classes/NewRelicApi/ThresholdValue.html +0 -174
  129. data/rdoc/classes/NewRelicApi/User.html +0 -111
  130. data/rdoc/created.rid +0 -1
  131. data/rdoc/files/CHANGELOG.html +0 -649
  132. data/rdoc/files/LICENSE.html +0 -143
  133. data/rdoc/files/lib/new_relic/agent/agent_rb.html +0 -113
  134. data/rdoc/files/lib/new_relic/agent/busy_calculator_rb.html +0 -115
  135. data/rdoc/files/lib/new_relic/agent/chained_call_rb.html +0 -107
  136. data/rdoc/files/lib/new_relic/agent/collection_helper_rb.html +0 -101
  137. data/rdoc/files/lib/new_relic/agent/error_collector_rb.html +0 -101
  138. data/rdoc/files/lib/new_relic/agent/instrumentation/active_merchant_rb.html +0 -107
  139. data/rdoc/files/lib/new_relic/agent/instrumentation/active_record_instrumentation_rb.html +0 -108
  140. data/rdoc/files/lib/new_relic/agent/instrumentation/authlogic_rb.html +0 -101
  141. data/rdoc/files/lib/new_relic/agent/instrumentation/controller_instrumentation_rb.html +0 -108
  142. data/rdoc/files/lib/new_relic/agent/instrumentation/data_mapper_rb.html +0 -191
  143. data/rdoc/files/lib/new_relic/agent/instrumentation/delayed_job_instrumentation_rb.html +0 -109
  144. data/rdoc/files/lib/new_relic/agent/instrumentation/memcache_rb.html +0 -152
  145. data/rdoc/files/lib/new_relic/agent/instrumentation/merb/controller_rb.html +0 -155
  146. data/rdoc/files/lib/new_relic/agent/instrumentation/merb/errors_rb.html +0 -107
  147. data/rdoc/files/lib/new_relic/agent/instrumentation/metric_frame_rb.html +0 -113
  148. data/rdoc/files/lib/new_relic/agent/instrumentation/net_rb.html +0 -172
  149. data/rdoc/files/lib/new_relic/agent/instrumentation/passenger_instrumentation_rb.html +0 -101
  150. data/rdoc/files/lib/new_relic/agent/instrumentation/rack_rb.html +0 -108
  151. data/rdoc/files/lib/new_relic/agent/instrumentation/rails/action_controller_rb.html +0 -152
  152. data/rdoc/files/lib/new_relic/agent/instrumentation/rails/action_web_service_rb.html +0 -108
  153. data/rdoc/files/lib/new_relic/agent/instrumentation/rails/errors_rb.html +0 -167
  154. data/rdoc/files/lib/new_relic/agent/instrumentation/sinatra_rb.html +0 -108
  155. data/rdoc/files/lib/new_relic/agent/method_tracer_rb.html +0 -108
  156. data/rdoc/files/lib/new_relic/agent/sampler_rb.html +0 -116
  157. data/rdoc/files/lib/new_relic/agent/samplers/cpu_sampler_rb.html +0 -101
  158. data/rdoc/files/lib/new_relic/agent/samplers/delayed_job_lock_sampler_rb.html +0 -101
  159. data/rdoc/files/lib/new_relic/agent/samplers/memory_sampler_rb.html +0 -101
  160. data/rdoc/files/lib/new_relic/agent/samplers/object_sampler_rb.html +0 -101
  161. data/rdoc/files/lib/new_relic/agent/shim_agent_rb.html +0 -108
  162. data/rdoc/files/lib/new_relic/agent/stats_engine/metric_stats_rb.html +0 -101
  163. data/rdoc/files/lib/new_relic/agent/stats_engine/samplers_rb.html +0 -101
  164. data/rdoc/files/lib/new_relic/agent/stats_engine/transactions_rb.html +0 -101
  165. data/rdoc/files/lib/new_relic/agent/stats_engine_rb.html +0 -110
  166. data/rdoc/files/lib/new_relic/agent/transaction_sampler_rb.html +0 -101
  167. data/rdoc/files/lib/new_relic/agent/worker_loop_rb.html +0 -101
  168. data/rdoc/files/lib/new_relic/agent_rb.html +0 -204
  169. data/rdoc/files/lib/new_relic/commands/deployments_rb.html +0 -119
  170. data/rdoc/files/lib/new_relic/commands/new_relic_commands_rb.html +0 -108
  171. data/rdoc/files/lib/new_relic/control/external_rb.html +0 -117
  172. data/rdoc/files/lib/new_relic/control/merb_rb.html +0 -101
  173. data/rdoc/files/lib/new_relic/control/rails_rb.html +0 -108
  174. data/rdoc/files/lib/new_relic/control/ruby_rb.html +0 -110
  175. data/rdoc/files/lib/new_relic/control/sinatra_rb.html +0 -108
  176. data/rdoc/files/lib/new_relic/control_rb.html +0 -116
  177. data/rdoc/files/lib/new_relic/delayed_job_injection_rb.html +0 -180
  178. data/rdoc/files/lib/new_relic/histogram_rb.html +0 -114
  179. data/rdoc/files/lib/new_relic/local_environment_rb.html +0 -111
  180. data/rdoc/files/lib/new_relic/merbtasks_rb.html +0 -101
  181. data/rdoc/files/lib/new_relic/metric_data_rb.html +0 -101
  182. data/rdoc/files/lib/new_relic/metric_parser/action_mailer_rb.html +0 -101
  183. data/rdoc/files/lib/new_relic/metric_parser/active_merchant_rb.html +0 -101
  184. data/rdoc/files/lib/new_relic/metric_parser/active_record_rb.html +0 -101
  185. data/rdoc/files/lib/new_relic/metric_parser/controller_cpu_rb.html +0 -101
  186. data/rdoc/files/lib/new_relic/metric_parser/controller_rb.html +0 -101
  187. data/rdoc/files/lib/new_relic/metric_parser/errors_rb.html +0 -101
  188. data/rdoc/files/lib/new_relic/metric_parser/external_rb.html +0 -101
  189. data/rdoc/files/lib/new_relic/metric_parser/mem_cache_rb.html +0 -101
  190. data/rdoc/files/lib/new_relic/metric_parser/other_transaction_rb.html +0 -108
  191. data/rdoc/files/lib/new_relic/metric_parser/view_rb.html +0 -101
  192. data/rdoc/files/lib/new_relic/metric_parser/web_frontend_rb.html +0 -107
  193. data/rdoc/files/lib/new_relic/metric_parser/web_service_rb.html +0 -101
  194. data/rdoc/files/lib/new_relic/metric_parser_rb.html +0 -101
  195. data/rdoc/files/lib/new_relic/metric_spec_rb.html +0 -108
  196. data/rdoc/files/lib/new_relic/metrics_rb.html +0 -101
  197. data/rdoc/files/lib/new_relic/noticed_error_rb.html +0 -107
  198. data/rdoc/files/lib/new_relic/rack/metric_app_rb.html +0 -108
  199. data/rdoc/files/lib/new_relic/rack_app_rb.html +0 -110
  200. data/rdoc/files/lib/new_relic/recipes_rb.html +0 -128
  201. data/rdoc/files/lib/new_relic/stats_rb.html +0 -101
  202. data/rdoc/files/lib/new_relic/transaction_analysis_rb.html +0 -108
  203. data/rdoc/files/lib/new_relic/transaction_sample_rb.html +0 -101
  204. data/rdoc/files/lib/new_relic/version_rb.html +0 -101
  205. data/rdoc/files/lib/new_relic_api_rb.html +0 -145
  206. data/rdoc/files/lib/newrelic_rpm_rb.html +0 -147
  207. data/rdoc/files/lib/tasks/all_rb.html +0 -107
  208. data/rdoc/fr_class_index.html +0 -134
  209. data/rdoc/fr_file_index.html +0 -103
  210. data/rdoc/fr_method_index.html +0 -568
  211. data/rdoc/index.html +0 -24
  212. data/rdoc/rdoc-style.css +0 -208
data/CHANGELOG CHANGED
@@ -1,16 +1,28 @@
1
- v2.10.8
1
+ v2.11.0
2
+ * rails3 instrumentation (no developer mode support yet)
3
+ * removed the ensure_worker_thread started and instead defined an after_fork
4
+ handler that will set up the agent properly in forked processes.
5
+ * change at_exit handler so the shutdown always goes after other shutdown
6
+ handlers
7
+ * add visibility to active record db transactions in the rpm transaction
8
+ traces (thanks to jeremy kemper)
9
+ * fix regression in merb support which caused merb apps not to start
2
10
  * fix bug in delayed_job instrumentation that caused the job queue sampler
3
11
  to run in the wrong place
4
12
  * change startup sequence and code that restarts the worker loop
5
13
  thread
6
- * detect the unicorn master and dont start the agent
14
+ * detect the unicorn master and dont start the agent; hook in after_fork
7
15
  * fix problem with the Authlogic metric names which caused errors in
8
16
  developer mode. Authlogic metrics now adhere to the convention of
9
17
  prefixing the name with 'Custom'
10
18
  * allow more correct overriding of transaction trace settings in the
11
19
  call to #manual_start
12
20
  * simplify WorkerLoop and add better protection for concurrency
13
- * preliminary support for rails3
21
+ * added NewRelic::Agent.logger to the public api to write to the agent
22
+ log file.
23
+ * optimizations to background thread, controller instrumentation, memory
24
+ usage
25
+ * add logger method to public_api
14
26
 
15
27
  v2.10.6
16
28
  * fix missing URL and referer on some traced errors and transactions
@@ -76,7 +76,6 @@ module NewRelic
76
76
  module Agent
77
77
  extend self
78
78
 
79
-
80
79
  require 'new_relic/version'
81
80
  require 'new_relic/local_environment'
82
81
  require 'new_relic/stats'
@@ -163,6 +162,12 @@ module NewRelic
163
162
 
164
163
  alias get_stats_no_scope get_stats
165
164
 
165
+ # Get the logger for the agent. Available after the agent has initialized.
166
+ # This sends output to the agent log file.
167
+ def logger
168
+ NewRelic::Control.instance.log
169
+ end
170
+
166
171
  # Call this to manually start the Agent in situations where the Agent does
167
172
  # not auto-start.
168
173
  #
@@ -179,15 +184,21 @@ module NewRelic
179
184
  #
180
185
  def manual_start(options={})
181
186
  raise unless Hash === options
182
- # Ignore all args but hash options
183
- options.merge! :agent_enabled => true
184
- NewRelic::Control.instance.init_plugin options
187
+ NewRelic::Control.instance.init_plugin({ :agent_enabled => true, :sync_startup => true }.merge(options))
185
188
  end
186
189
 
190
+ # Register this method as a callback for processes that fork
191
+ # jobs. If the master/parent connects to the agent prior to forking
192
+ # the agent in the forked process will use that agent_run.
193
+ # Otherwise the forked process will establish a new connection
194
+ # with the server.
195
+ def after_fork
196
+ agent.after_fork
197
+ end
187
198
  # Shutdown the agent. Call this before exiting. Sends any queued data
188
199
  # and kills the background thread.
189
200
  def shutdown
190
- @agent.shutdown
201
+ agent.shutdown
191
202
  end
192
203
 
193
204
  # Add instrumentation files to the agent. The argument should be a glob
@@ -278,7 +289,7 @@ module NewRelic
278
289
  #
279
290
  # The block is yielded to with the exception to filter.
280
291
  #
281
- # Do not call return.
292
+ # Return the new block or the existing filter Proc if no block is passed.
282
293
  #
283
294
  def ignore_error_filter(&block)
284
295
  agent.error_collector.ignore_error_filter(&block)
@@ -37,30 +37,33 @@ module NewRelic
37
37
  raise "This method no longer supported. Instead use the class method NewRelic::Agent.manual_start"
38
38
  end
39
39
 
40
- # This method attempts to detect when we're in a forked process and tries
41
- # to re-establish a new agent run. It's important
42
- # for passenger/unicorn/etc where processes are forked and the worker
43
- # loop thread is no longer alive.
40
+ # This method should be called in a forked process after a fork.
41
+ # It assumes the parent process started the agent. It clears any
42
+ # metrics carried over from the parent process, and restarts
43
+ # the worker thread and sampler threads.
44
44
  #
45
- def ensure_worker_thread_started
46
- return if !control.agent_enabled? || @invalid_license
45
+ # In addition, if the parent process had not connected to the server
46
+ # because it was a Passenger or Unicorn spawner, it will
47
+ # initiate the connection and create a new agent run.
48
+ #
49
+ def after_fork
47
50
 
48
51
  # @connected gets false after we fail to connect or have an error
49
52
  # connecting. @connected has nil if we haven't finished trying to connect.
50
53
  # or we didn't attempt a connection because this is the master process
51
- return unless @worker_thread && !@worker_thread.alive? && @connected != false
52
-
53
- # This ensures that we don't enter this block again
54
- @worker_thread = nil
55
-
56
- # We got some reports of threading errors in Unicorn with this.
57
- log.debug "Detected that the worker thread is not running in #$$. Restarting." rescue nil
58
- # Assume we've been forked if there's a worker_loop already created.
59
- # Clear out stats that are left over from parent process when we know the parent process
60
- # did not try to establish a connection
61
- reset_stats if @connected.nil?
62
- start_new_run
63
- @stats_engine.spawn_sampler_thread
54
+
55
+ log.debug "Agent received after_fork notice in #$$: [#{control.agent_enabled?}; monitor=#{control.monitor_mode?}; connected: #{@connected.inspect}; thread=#{@worker_thread.inspect}]"
56
+ return if !control.agent_enabled? or
57
+ !control.monitor_mode? or
58
+ @connected == false or
59
+ @worker_thread && @worker_thread.alive?
60
+
61
+ log.debug "Detected that the worker thread is not running in #$$. Restarting."
62
+
63
+ # Clear out stats that are left over from parent process
64
+ reset_stats
65
+ start_worker_thread
66
+ @stats_engine.start_sampler_thread
64
67
  end
65
68
 
66
69
  # True if we have initialized and completed 'start'
@@ -71,8 +74,8 @@ module NewRelic
71
74
  # Attempt a graceful shutdown of the agent.
72
75
  def shutdown
73
76
  return if not started?
74
- if @task_loop
75
- @task_loop.stop
77
+ if @worker_loop
78
+ @worker_loop.stop
76
79
 
77
80
  log.debug "Starting Agent shutdown"
78
81
 
@@ -138,7 +141,7 @@ module NewRelic
138
141
  end
139
142
 
140
143
  def log
141
- NewRelic::Control.instance.log
144
+ NewRelic::Agent.logger
142
145
  end
143
146
 
144
147
  # Start up the agent. This verifies that the agent_enabled? is
@@ -151,7 +154,7 @@ module NewRelic
151
154
  return
152
155
  end
153
156
  return if !control.agent_enabled?
154
-
157
+ @started = true
155
158
  @local_host = determine_host
156
159
 
157
160
  if control.dispatcher.nil? || control.dispatcher.to_s.empty?
@@ -161,8 +164,6 @@ module NewRelic
161
164
  end
162
165
  log.info "Application: #{control.app_names.join(", ")}" unless control.app_names.empty?
163
166
 
164
- @started = true
165
-
166
167
  sampler_config = control.fetch('transaction_tracer', {})
167
168
  @should_send_samples = sampler_config.fetch('enabled', true)
168
169
  log.info "Transaction tracing not enabled." if not @should_send_samples
@@ -190,19 +191,25 @@ module NewRelic
190
191
 
191
192
  if control.monitor_mode?
192
193
  if !control.license_key
193
- @invalid_license = true
194
194
  control.log! "No license key found. Please edit your newrelic.yml file and insert your license key.", :error
195
195
  elsif control.license_key.length != 40
196
- @invalid_license = true
197
196
  control.log! "Invalid license key: #{control.license_key}", :error
198
197
  else
199
- start_new_run
200
- # When the VM shuts down, attempt to send a message to the
201
- # server that this agent run is stopping, assuming it has
202
- # successfully connected
203
- # This shutdown handler doesn't work if Sinatra is running
204
- # because it executes in the shutdown handler!
205
- at_exit { shutdown } unless [:sinatra, :unicorn].include? NewRelic::Control.instance.dispatcher
198
+ # Do the connect in the foreground if we are in sync mode
199
+ NewRelic::Agent.disable_all_tracing { connect(false) } if control.sync_startup
200
+
201
+ # Start the event loop and initiate connection if necessary
202
+ start_worker_thread
203
+
204
+ # Our shutdown handler needs to run after other shutdown handlers
205
+ # that may be doing things like running the app (hello sinatra).
206
+ if RUBY_VERSION =~ /rubinius/i
207
+ list = at_exit { shutdown }
208
+ # move the shutdown handler to the front of the list, to execute last:
209
+ list.unshift(list.pop)
210
+ elsif !defined?(JRuby) or !defined(Sinatra::Application)
211
+ at_exit { at_exit { shutdown } }
212
+ end
206
213
  end
207
214
  end
208
215
  control.log! "New Relic RPM Agent #{NewRelic::VERSION::STRING} Initialized: pid = #$$"
@@ -215,8 +222,8 @@ module NewRelic
215
222
  end
216
223
 
217
224
  # Try to launch the worker thread and connect to the server
218
- def start_new_run
219
- @task_loop = WorkerLoop.new
225
+ def start_worker_thread
226
+ @worker_loop = WorkerLoop.new
220
227
  log.debug "Creating RPM worker thread."
221
228
  @worker_thread = Thread.new do
222
229
  begin
@@ -225,7 +232,7 @@ module NewRelic
225
232
  # the server rejected us for a licensing reason and we should
226
233
  # just exit the thread. If it returns nil
227
234
  # that means it didn't try to connect because we're in the master
228
- @connected = connect
235
+ connect if not @connected
229
236
  if @connected
230
237
  # disable transaction sampling if disabled by the server and we're not in dev mode
231
238
  if !control.developer_mode? && !@should_send_samples
@@ -235,12 +242,12 @@ module NewRelic
235
242
  log.debug "Running worker loop"
236
243
  # note if the agent attempts to report more frequently than allowed by the server
237
244
  # the server will start dropping data.
238
- @task_loop.run(@report_period) do
245
+ @worker_loop.run(@report_period) do
239
246
  harvest_and_send_timeslice_data
240
247
  harvest_and_send_slowest_sample if @should_send_samples
241
248
  harvest_and_send_errors if error_collector.enabled
242
249
  end
243
- @connected = false
250
+ @connected = true
244
251
  end
245
252
  end
246
253
  rescue NewRelic::Agent::ForceRestartException => e
@@ -248,17 +255,18 @@ module NewRelic
248
255
  # disconnect and start over.
249
256
  # clear the stats engine
250
257
  reset_stats
258
+ @metric_ids = {}
251
259
  @connected = nil
252
260
  # Wait a short time before trying to reconnect
253
261
  sleep 30
254
262
  retry
255
- rescue ForceDisconnectException => e
263
+ rescue NewRelic::Agent::ForceDisconnectException => e
256
264
  # when a disconnect is requested, stop the current thread, which
257
265
  # is the worker thread that gathers data and talks to the
258
266
  # server.
259
267
  log.error "RPM forced this agent to disconnect (#{e.message})"
260
268
  @connected = false
261
- rescue ServerConnectionException => e
269
+ rescue NewRelic::Agent::ServerConnectionException => e
262
270
  control.log! "Unable to establish connection with the server. Run with log level set to debug for more information."
263
271
  log.debug("#{e.class.name}: #{e.message}\n#{e.backtrace.first}")
264
272
  @connected = false
@@ -275,7 +283,6 @@ module NewRelic
275
283
  end
276
284
 
277
285
  def initialize
278
- @connected = false
279
286
  @launch_time = Time.now
280
287
 
281
288
  @metric_ids = {}
@@ -287,8 +294,6 @@ module NewRelic
287
294
 
288
295
  @request_timeout = NewRelic::Control.instance.fetch('timeout', 2 * 60)
289
296
 
290
- @invalid_license = false
291
-
292
297
  @last_harvest_time = Time.now
293
298
  @obfuscator = method(:default_sql_obfuscator)
294
299
  end
@@ -298,17 +303,29 @@ module NewRelic
298
303
  # keep calling this. Return false if we could not establish a
299
304
  # connection with the server and we should not retry, such as if
300
305
  # there's a bad license key.
301
- def connect
302
- if $0 =~ /ApplicationSpawner|master/
303
- log.debug "Process is master spawner (#$0) -- don't connect to RPM service"
304
- return nil
305
- end
306
+ #
307
+ # Set keep_retrying=false to disable retrying and return asap, such as when
308
+ # invoked in the foreground. Otherwise this runs until a successful
309
+ # connection is made, or the server rejects us.
310
+
311
+ def connect(keep_retrying = true)
312
+ # Don't reconnect if we've already got a connection.
313
+ return if @connected
314
+
306
315
  # wait a few seconds for the web server to boot, necessary in development
307
- connect_retry_period = 5
316
+ connect_retry_period = keep_retrying ? 10 : 0
308
317
  connect_attempts = 0
309
318
  @agent_id = nil
310
319
  begin
311
320
  sleep connect_retry_period.to_i
321
+ # Running in the Passenger or Unicorn spawners?
322
+ if $0 =~ /ApplicationSpawner|master/
323
+ log.debug "Process is master spawner (#$0) -- don't connect to RPM service"
324
+ @connected = nil
325
+ return
326
+ else
327
+ log.debug "Connecting Process to RPM: #$0"
328
+ end
312
329
  environment = control['send_environment_info'] != false ? control.local_env.snapshot : []
313
330
  log.debug "Connecting with validation seed/token: #{control.validate_seed}/#{control.validate_token}" if control.validate_seed
314
331
  @agent_id ||= invoke_remote :start, @local_host, {
@@ -346,32 +363,36 @@ module NewRelic
346
363
  log.info "Transaction traces will be sent to the RPM service." if @should_send_samples
347
364
  log.info "Errors will be sent to the RPM service." if error_collector.enabled
348
365
 
366
+ @connected_pid = $$
349
367
  @connected = true
350
368
 
351
- rescue LicenseException => e
369
+ rescue NewRelic::Agent::LicenseException => e
352
370
  control.log! e.message, :error
353
371
  control.log! "Visit NewRelic.com to obtain a valid license key, or to upgrade your account."
354
- @invalid_license = true
355
- return false
372
+ @connected = false
356
373
 
357
374
  rescue Timeout::Error, StandardError => e
358
375
  log.info "Unable to establish connection with New Relic RPM Service at #{control.server}"
359
- unless e.instance_of? ServerConnectionException
376
+ unless e.instance_of? NewRelic::Agent::ServerConnectionException
360
377
  log.error e.message
361
378
  log.debug e.backtrace.join("\n")
362
379
  end
363
380
  # retry logic
364
- connect_attempts += 1
365
- case connect_attempts
381
+ if keep_retrying
382
+ connect_attempts += 1
383
+ case connect_attempts
366
384
  when 1..2
367
- connect_retry_period, period_msg = 60, "1 minute"
368
- when 3..5 then
369
- connect_retry_period, period_msg = 60 * 2, "2 minutes"
370
- else
371
- connect_retry_period, period_msg = 10 * 60, "10 minutes"
385
+ connect_retry_period, period_msg = 60, "1 minute"
386
+ when 3..5
387
+ connect_retry_period, period_msg = 60 * 2, "2 minutes"
388
+ else
389
+ connect_retry_period, period_msg = 5 * 60, "5 minutes"
390
+ end
391
+ log.info "Will re-attempt in #{period_msg}"
392
+ retry
393
+ else
394
+ @connected = nil
372
395
  end
373
- log.info "Will re-attempt in #{period_msg}"
374
- retry
375
396
  end
376
397
  end
377
398
 
@@ -384,7 +405,6 @@ module NewRelic
384
405
  end
385
406
  def reset_stats
386
407
  @stats_engine.reset_stats
387
- @metric_ids = {}
388
408
  @unsent_errors = []
389
409
  @traces = nil
390
410
  @unsent_timeslice_data = {}
@@ -419,7 +439,6 @@ module NewRelic
419
439
  end if metric_ids
420
440
 
421
441
  log.debug "#{now}: sent #{@unsent_timeslice_data.length} timeslices (#{@agent_id}) in #{Time.now - now} seconds"
422
- puts "#{now}: sent #{@unsent_timeslice_data.length} timeslices (#{@agent_id}) in #{Time.now - now} seconds"
423
442
 
424
443
  # if we successfully invoked this web service, then clear the unsent message cache.
425
444
  @unsent_timeslice_data = {}
@@ -533,12 +552,12 @@ module NewRelic
533
552
  raise
534
553
  end
535
554
  if response.is_a? Net::HTTPServiceUnavailable
536
- raise ServerConnectionException, "Service unavailable: #{response.body || response.message}"
555
+ raise NewRelic::Agent::ServerConnectionException, "Service unavailable: #{response.body || response.message}"
537
556
  elsif response.is_a? Net::HTTPGatewayTimeOut
538
557
  log.debug("Timed out getting response: #{response.message}")
539
558
  raise Timeout::Error, response.message
540
559
  elsif !(response.is_a? Net::HTTPSuccess)
541
- raise ServerConnectionException, "Unexpected response from server: #{response.code}: #{response.message}"
560
+ raise NewRelic::Agent::ServerConnectionException, "Unexpected response from server: #{response.code}: #{response.message}"
542
561
  end
543
562
  response
544
563
  end
@@ -575,12 +594,12 @@ module NewRelic
575
594
 
576
595
  # raises the right exception if the remote server tells it to die
577
596
  return check_for_exception(response)
578
- rescue ForceRestartException => e
597
+ rescue NewRelic::Agent::ForceRestartException => e
579
598
  log.info e.message
580
599
  raise
581
600
  rescue SystemCallError, SocketError => e
582
601
  # These include Errno connection errors
583
- raise ServerConnectionException, "Recoverable error connecting to the server: #{e}"
602
+ raise NewRelic::Agent::ServerConnectionException, "Recoverable error connecting to the server: #{e}"
584
603
  end
585
604
 
586
605
  def graceful_disconnect
@@ -588,18 +607,20 @@ module NewRelic
588
607
  begin
589
608
  log.debug "Sending graceful shutdown message to #{control.server}"
590
609
 
591
- @request_timeout = 5
610
+ @request_timeout = 10
592
611
  log.debug "Flushing unsent metric data to server"
593
- @task_loop.run_task
594
- log.debug "Sending RPM service agent run shutdown message"
595
- invoke_remote :shutdown, @agent_id, Time.now.to_f
596
-
597
- log.debug "Graceful shutdown complete"
598
-
612
+ @worker_loop.run_task
613
+ if @connected_pid == $$
614
+ log.debug "Sending RPM service agent run shutdown message"
615
+ invoke_remote :shutdown, @agent_id, Time.now.to_f
616
+ else
617
+ log.debug "This agent connected from #{@connected_pid}--not sending shutdown"
618
+ end
619
+ log.debug "Graceful disconnect complete"
599
620
  rescue Timeout::Error, StandardError
600
621
  end
601
622
  else
602
- log.debug "Bypassing graceful shutdown - agent not connected"
623
+ log.debug "Bypassing graceful disconnect - agent not connected"
603
624
  end
604
625
  end
605
626
  def default_sql_obfuscator(sql)
@@ -30,7 +30,7 @@ module NewRelic
30
30
  return if callers > 0
31
31
  @lock.synchronize do
32
32
  if @entrypoint_stack.empty?
33
- NewRelic::Control.instance.log.error("Stack underflow tracking dispatcher entry and exit!\n #{caller.join(" \n")}")
33
+ NewRelic::Agent.logger.error("Stack underflow tracking dispatcher entry and exit!\n #{caller.join(" \n")}")
34
34
  else
35
35
  @accumulator += (end_time - @entrypoint_stack.pop)
36
36
  end
@@ -33,10 +33,13 @@ module NewRelic
33
33
  end
34
34
 
35
35
  def ignore_error_filter(&block)
36
- @ignore_filter = block
36
+ if block
37
+ @ignore_filter = block
38
+ else
39
+ @ignore_error_filter
40
+ end
37
41
  end
38
42
 
39
-
40
43
  # errors is an array of Exception Class Names
41
44
  #
42
45
  def ignore(errors)
@@ -118,7 +121,7 @@ module NewRelic
118
121
 
119
122
  private
120
123
  def log
121
- NewRelic::Control.instance.log
124
+ NewRelic::Agent.logger
122
125
  end
123
126
  end
124
127
  end