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.
Files changed (148) hide show
  1. data/CHANGELOG +42 -0
  2. data/GUIDELINES_FOR_CONTRIBUTING.md +3 -0
  3. data/Rakefile +8 -0
  4. data/bin/mongrel_rpm +1 -1
  5. data/init.rb +1 -8
  6. data/lib/new_relic/agent.rb +11 -13
  7. data/lib/new_relic/agent/agent.rb +89 -110
  8. data/lib/new_relic/agent/agent_logger.rb +165 -0
  9. data/lib/new_relic/agent/audit_logger.rb +72 -0
  10. data/lib/new_relic/agent/beacon_configuration.rb +4 -4
  11. data/lib/new_relic/agent/browser_monitoring.rb +13 -7
  12. data/lib/new_relic/agent/busy_calculator.rb +2 -2
  13. data/lib/new_relic/agent/configuration.rb +25 -0
  14. data/lib/new_relic/agent/configuration/defaults.rb +45 -8
  15. data/lib/new_relic/agent/configuration/environment_source.rb +8 -15
  16. data/lib/new_relic/agent/configuration/manager.rb +22 -2
  17. data/lib/new_relic/agent/configuration/mask_defaults.rb +10 -0
  18. data/lib/new_relic/agent/configuration/yaml_source.rb +4 -2
  19. data/lib/new_relic/agent/cross_process_monitoring.rb +43 -0
  20. data/lib/new_relic/agent/database.rb +2 -4
  21. data/lib/new_relic/agent/error_collector.rb +4 -9
  22. data/lib/new_relic/agent/instrumentation/active_merchant.rb +1 -1
  23. data/lib/new_relic/agent/instrumentation/active_record.rb +1 -1
  24. data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +1 -1
  25. data/lib/new_relic/agent/instrumentation/authlogic.rb +1 -1
  26. data/lib/new_relic/agent/instrumentation/browser_monitoring_timings.rb +41 -0
  27. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +7 -7
  28. data/lib/new_relic/agent/instrumentation/data_mapper.rb +1 -1
  29. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +1 -1
  30. data/lib/new_relic/agent/instrumentation/memcache.rb +4 -4
  31. data/lib/new_relic/agent/instrumentation/merb/controller.rb +1 -1
  32. data/lib/new_relic/agent/instrumentation/merb/errors.rb +1 -1
  33. data/lib/new_relic/agent/instrumentation/metric_frame/pop.rb +1 -1
  34. data/lib/new_relic/agent/instrumentation/net.rb +1 -1
  35. data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +2 -2
  36. data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +4 -4
  37. data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +1 -1
  38. data/lib/new_relic/agent/instrumentation/rails/errors.rb +1 -1
  39. data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +3 -3
  40. data/lib/new_relic/agent/instrumentation/rails3/errors.rb +1 -1
  41. data/lib/new_relic/agent/instrumentation/resque.rb +3 -2
  42. data/lib/new_relic/agent/instrumentation/sinatra.rb +1 -1
  43. data/lib/new_relic/agent/instrumentation/sunspot.rb +1 -1
  44. data/lib/new_relic/agent/instrumentation/unicorn_instrumentation.rb +2 -2
  45. data/lib/new_relic/agent/method_tracer.rb +6 -8
  46. data/lib/new_relic/agent/new_relic_service.rb +94 -106
  47. data/lib/new_relic/agent/pipe_channel_manager.rb +1 -1
  48. data/lib/new_relic/agent/samplers/memory_sampler.rb +4 -6
  49. data/lib/new_relic/agent/sql_sampler.rb +3 -18
  50. data/lib/new_relic/agent/stats_engine.rb +0 -5
  51. data/lib/new_relic/agent/stats_engine/metric_stats.rb +3 -3
  52. data/lib/new_relic/agent/stats_engine/samplers.rb +2 -4
  53. data/lib/new_relic/agent/thread.rb +8 -3
  54. data/lib/new_relic/agent/thread_profiler.rb +38 -27
  55. data/lib/new_relic/agent/transaction_info.rb +1 -1
  56. data/lib/new_relic/agent/transaction_sample_builder.rb +2 -3
  57. data/lib/new_relic/agent/transaction_sampler.rb +3 -7
  58. data/lib/new_relic/agent/worker_loop.rb +3 -11
  59. data/lib/new_relic/control.rb +0 -2
  60. data/lib/new_relic/control/class_methods.rb +8 -2
  61. data/lib/new_relic/control/frameworks/merb.rb +0 -6
  62. data/lib/new_relic/control/frameworks/rails.rb +8 -29
  63. data/lib/new_relic/control/frameworks/rails3.rb +8 -20
  64. data/lib/new_relic/control/frameworks/rails4.rb +23 -0
  65. data/lib/new_relic/control/frameworks/ruby.rb +1 -22
  66. data/lib/new_relic/control/instance_methods.rb +12 -34
  67. data/lib/new_relic/control/instrumentation.rb +7 -12
  68. data/lib/new_relic/control/server_methods.rb +5 -8
  69. data/lib/new_relic/delayed_job_injection.rb +1 -1
  70. data/lib/new_relic/local_environment.rb +30 -64
  71. data/lib/new_relic/metric_data.rb +1 -1
  72. data/lib/new_relic/metric_spec.rb +1 -1
  73. data/lib/new_relic/noticed_error.rb +1 -1
  74. data/lib/new_relic/rack/browser_monitoring.rb +5 -5
  75. data/lib/new_relic/stats.rb +9 -7
  76. data/lib/new_relic/transaction_sample.rb +2 -7
  77. data/lib/new_relic/version.rb +1 -1
  78. data/lib/newrelic_rpm.rb +1 -1
  79. data/newrelic_rpm.gemspec.erb +15 -17
  80. data/test/config/newrelic.yml +1 -1
  81. data/test/config/test_control.rb +18 -18
  82. data/test/fixtures/gemspec_no_build.rb +0 -2
  83. data/test/fixtures/gemspec_with_build.rb +0 -2
  84. data/test/fixtures/gemspec_with_build_and_stage.rb +0 -2
  85. data/test/multiverse/README.md +3 -8
  86. data/test/multiverse/suites/agent_only/Envfile +1 -0
  87. data/test/multiverse/suites/agent_only/audit_log_test.rb +99 -0
  88. data/test/multiverse/suites/agent_only/marshaling_test.rb +1 -1
  89. data/test/multiverse/suites/config_file_loading/Envfile +7 -0
  90. data/test/multiverse/suites/config_file_loading/config_file_loading_test.rb +106 -0
  91. data/test/multiverse/suites/logging/Envfile +4 -0
  92. data/test/multiverse/suites/logging/config/newrelic.yml +22 -0
  93. data/test/multiverse/suites/logging/logging_test.rb +143 -0
  94. data/test/multiverse/suites/no_load/config/newrelic.yml +1 -2
  95. data/test/multiverse/suites/rum_auto_instrumentation/sanity_test.rb +0 -13
  96. data/test/new_relic/agent/agent/connect_test.rb +30 -92
  97. data/test/new_relic/agent/agent/start_test.rb +4 -84
  98. data/test/new_relic/agent/agent/start_worker_thread_test.rb +8 -43
  99. data/test/new_relic/agent/agent_logger_test.rb +153 -0
  100. data/test/new_relic/agent/agent_test.rb +10 -9
  101. data/test/new_relic/agent/audit_logger_test.rb +105 -0
  102. data/test/new_relic/agent/browser_monitoring_test.rb +2 -1
  103. data/test/new_relic/agent/busy_calculator_test.rb +7 -0
  104. data/test/new_relic/agent/configuration/environment_source_test.rb +25 -20
  105. data/test/new_relic/agent/configuration/manager_test.rb +59 -4
  106. data/test/new_relic/agent/configuration/yaml_source_test.rb +20 -1
  107. data/test/new_relic/agent/cross_process_monitoring_test.rb +77 -0
  108. data/test/new_relic/agent/database_test.rb +0 -11
  109. data/test/new_relic/agent/error_collector/notice_error_test.rb +1 -3
  110. data/test/new_relic/agent/error_collector_test.rb +11 -7
  111. data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +39 -19
  112. data/test/new_relic/agent/instrumentation/browser_monitoring_timings_test.rb +39 -0
  113. data/test/new_relic/agent/instrumentation/metric_frame/pop_test.rb +1 -1
  114. data/test/new_relic/agent/method_tracer/class_methods/add_method_tracer_test.rb +0 -6
  115. data/test/new_relic/agent/method_tracer/instance_methods/trace_execution_scoped_test.rb +3 -15
  116. data/test/new_relic/agent/new_relic_service_test.rb +48 -8
  117. data/test/new_relic/agent/pipe_channel_manager_test.rb +1 -1
  118. data/test/new_relic/agent/sql_sampler_test.rb +1 -1
  119. data/test/new_relic/agent/thread_profiler_test.rb +46 -45
  120. data/test/new_relic/agent/thread_test.rb +13 -0
  121. data/test/new_relic/agent/transaction_sample_builder_test.rb +1 -1
  122. data/test/new_relic/agent/worker_loop_test.rb +4 -9
  123. data/test/new_relic/agent_test.rb +6 -9
  124. data/test/new_relic/control/class_methods_test.rb +0 -18
  125. data/test/new_relic/control_test.rb +6 -9
  126. data/test/new_relic/dispatcher_test.rb +54 -0
  127. data/test/new_relic/fake_collector.rb +15 -14
  128. data/test/new_relic/fake_service.rb +4 -1
  129. data/test/new_relic/fakes_sending_data.rb +30 -0
  130. data/test/new_relic/framework_test.rb +53 -0
  131. data/test/new_relic/local_environment_test.rb +5 -2
  132. data/test/new_relic/rack/browser_monitoring_test.rb +2 -1
  133. data/test/new_relic/rack/developer_mode_test.rb +1 -1
  134. data/test/new_relic/stats_test.rb +10 -0
  135. data/test/new_relic/transaction_sample_test.rb +2 -2
  136. data/test/script/ci.sh +1 -1
  137. data/test/test_helper.rb +23 -0
  138. data/ui/views/newrelic/file/images/arrow-close.png +0 -0
  139. data/ui/views/newrelic/file/images/arrow-open.png +0 -0
  140. data/ui/views/newrelic/file/images/blue_bar.gif +0 -0
  141. data/ui/views/newrelic/file/images/file_icon.png +0 -0
  142. data/ui/views/newrelic/file/images/gray_bar.gif +0 -0
  143. metadata +47 -41
  144. data/InstallationNotes.md +0 -15
  145. data/lib/new_relic/control/logging_methods.rb +0 -125
  146. data/test/multiverse/Rakefile +0 -17
  147. data/test/multiverse/suites/rum_auto_instrumentation/problem_response.html +0 -422
  148. data/test/new_relic/control/logging_methods_test.rb +0 -211
data/CHANGELOG CHANGED
@@ -1,6 +1,48 @@
1
1
 
2
2
  # New Relic Ruby Agent Release Notes #
3
3
 
4
+ ## v3.5.5 ##
5
+
6
+ * Add thread profiling support
7
+
8
+ Thread profiling performs statistical sampling of backtraces of all threads
9
+ within your Ruby processes. This feature requires MRI >= 1.9.2, and is
10
+ controlled via the New Relic web UI. JRuby support (in 1.9.x compat mode) is
11
+ considered experimental, due to issues with JRuby's Thread#backtrace.
12
+
13
+ * Add audit logging capability
14
+
15
+ The agent can now log all of the data it sends to the New Relic servers to
16
+ a special log file for human inspection. This feature is off by default, and
17
+ can be enabled by setting the audit_log.enabled configuration key to true.
18
+ You may also control the location of the audit log with the audit_log.path key.
19
+
20
+ * Use config system for dispatcher, framework, and config file detection
21
+
22
+ Several aspects of the agent's configuration were not being handled by the
23
+ configuration system. Detection/configuration of the dispatcher (e.g. passenger,
24
+ unicorn, resque), framework (e.g. rails3, sinatra), and newrelic.yml
25
+ location are now handled via the Agent environment, manual, and default
26
+ configuration sources.
27
+
28
+ * Updates to logging across the agent
29
+
30
+ We've carefully reviewed the logging messages that the agent outputs, adding
31
+ details in some cases, and removing unnecessary clutter. We've also altered
32
+ the startup sequence to ensure that we don't spam STDOUT with messages
33
+ during initialization.
34
+
35
+ * Fix passing environment to manual_start()
36
+
37
+ Thanks to Justin Hannus. The :env key, when passed to Agent.manual_start,
38
+ can again be used to specify which section of newrelic.yml is loaded.
39
+
40
+ * Rails 4 support
41
+
42
+ This release includes preliminary support for Rails 4 as of 4.0.0.beta.
43
+ Rails 4 is still in development, but the agent should work as expected for
44
+ people who are experimenting with the beta.
45
+
4
46
  ## v3.5.4 ##
5
47
 
6
48
  * Add queue time support for sinatra apps
@@ -64,6 +64,9 @@ These tests can be run by invoking:
64
64
  bundle
65
65
  bundle exec rake test:multiverse
66
66
 
67
+ More details are available in
68
+ [test/multiverse/README.md](https://github.com/newrelic/rpm/blob/master/test/multiverse/README.md).
69
+
67
70
  ### And Finally...
68
71
 
69
72
  You are welcome to send pull requests to us - however, by doing so you agree
data/Rakefile CHANGED
@@ -23,6 +23,14 @@ namespace :test do
23
23
  end
24
24
  end
25
25
 
26
+ desc "Test the multiverse testing framework by executing tests in test/multiverse/test. Get meta with it."
27
+ task 'multiverse:self', [:suite, :mode] => [:gemspec] do |t, args|
28
+ args.with_defaults(:suite => "", :mode => "")
29
+ puts ("Testing the multiverse testing framework...")
30
+ test_files = FileList['test/multiverse/test/*_test.rb']
31
+ ruby test_files.join(" ")
32
+ end
33
+
26
34
  Rake::TestTask.new(:intentional_fail) do |t|
27
35
  t.libs << "#{agent_home}/test"
28
36
  t.libs << "#{agent_home}/lib"
data/bin/mongrel_rpm CHANGED
@@ -28,6 +28,6 @@ builder = Rack::Builder.new { eval rackup_code, binding, ru_file }
28
28
 
29
29
  options = { :Host => '127.0.0.1', :Port => port }
30
30
  Rack::Handler::Mongrel.run(builder.to_app, options) do | server |
31
- NewRelic::Control.instance.log! "Started Mongrel listening for '#{NewRelic::Control.instance.app_names.join(" and ")}' data at #{server.host}:#{server.port}"
31
+ NewRelic::Agent.logger.info "Started Mongrel listening for '#{NewRelic::Control.instance.app_names.join(" and ")}' data at #{server.host}:#{server.port}"
32
32
  end
33
33
 
data/init.rb CHANGED
@@ -27,12 +27,5 @@ begin
27
27
  NewRelic::Control.instance.init_plugin :config => current_config
28
28
 
29
29
  rescue => e
30
- NewRelic::Control.instance.log! "Error initializing New Relic plugin (#{e})", :error
31
- NewRelic::Control.instance.log! e.backtrace.join("\n"), :error
32
- NewRelic::Control.instance.log! "Agent is disabled."
30
+ ::NewRelic::Agent.logger.error "Error initializing New Relic plugin. Agent is disabled.", e
33
31
  end
34
-
35
- #ClassLoadingWatcher.flag_const_missing = nil
36
- #
37
- # ::RAILS_DEFAULT_LOGGER.warn "New Relic detected environment: #{NewRelic::Control.instance.local_env.to_s}, RAILS_ENV: #{RAILS_ENV}"
38
- # ::RAILS_DEFAULT_LOGGER.warn "Enabled? #{NewRelic::Control.instance.agent_enabled?}"
@@ -77,6 +77,7 @@ module NewRelic
77
77
  require 'new_relic/agent'
78
78
  require 'new_relic/agent/chained_call'
79
79
  require 'new_relic/agent/browser_monitoring'
80
+ require 'new_relic/agent/cross_process_monitoring'
80
81
  require 'new_relic/agent/agent'
81
82
  require 'new_relic/agent/shim_agent'
82
83
  require 'new_relic/agent/method_tracer'
@@ -140,6 +141,16 @@ module NewRelic
140
141
 
141
142
  alias instance agent #:nodoc:
142
143
 
144
+ # Primary interface to logging is fronted by this accessor
145
+ # Access via ::NewRelic::Agent.logger
146
+ def logger
147
+ @logger || StartupLogger.instance
148
+ end
149
+
150
+ def logger=(log)
151
+ @logger = log
152
+ end
153
+
143
154
  # Get or create a statistics gatherer that will aggregate numerical data
144
155
  # under a metric name.
145
156
  #
@@ -154,19 +165,6 @@ module NewRelic
154
165
 
155
166
  alias get_stats_no_scope get_stats
156
167
 
157
- # Get the logger for the agent. Available after the agent has initialized.
158
- # This sends output to the agent log file. If the agent has not initialized
159
- # a standard output logger is returned.
160
- def logger
161
- control = NewRelic::Control.instance(false)
162
- if control && control.log
163
- control.log
164
- else
165
- require 'logger'
166
- @stdoutlog ||= Logger.new $stdout
167
- end
168
- end
169
-
170
168
  # Call this to manually start the Agent in situations where the Agent does
171
169
  # not auto-start.
172
170
  #
@@ -89,8 +89,13 @@ module NewRelic
89
89
  # handles things like static setup of the header for inclusion
90
90
  # into pages
91
91
  attr_reader :beacon_configuration
92
+ # cross process id's and encoding
93
+ attr_reader :cross_process_id
94
+ attr_reader :cross_process_encoding_bytes
95
+ # service for communicating with collector
92
96
  attr_accessor :service
93
97
 
98
+
94
99
  # Returns the length of the unsent errors array, if it exists,
95
100
  # otherwise nil
96
101
  def unsent_errors_size
@@ -180,13 +185,12 @@ module NewRelic
180
185
  @metric_ids = {}
181
186
  end
182
187
 
183
- # log.debug "Agent received after_fork notice in #$$: [#{control.agent_enabled?}; monitor=#{control.monitor_mode?}; connected: #{@connected.inspect}; thread=#{@worker_thread.inspect}]"
184
188
  return if !Agent.config[:agent_enabled] ||
185
189
  !Agent.config[:monitor_mode] ||
186
190
  @connected == false ||
187
191
  @worker_thread && @worker_thread.alive?
188
192
 
189
- log.info "Starting the worker thread in #{$$} after forking."
193
+ ::NewRelic::Agent.logger.debug "Starting the worker thread in #{$$} after forking."
190
194
 
191
195
  # Clear out stats that are left over from parent process
192
196
  reset_stats
@@ -226,7 +230,7 @@ module NewRelic
226
230
  @worker_loop.stop
227
231
  end
228
232
 
229
- log.debug "Starting Agent shutdown"
233
+ ::NewRelic::Agent.logger.info "Starting Agent shutdown"
230
234
 
231
235
  # if litespeed, then ignore all future SIGUSR1 - it's
232
236
  # litespeed trying to shut us down
@@ -241,14 +245,14 @@ module NewRelic
241
245
  graceful_disconnect
242
246
  end
243
247
  rescue => e
244
- log.error e
245
- log.error e.backtrace.join("\n")
248
+ ::NewRelic::Agent.logger.error e
246
249
  end
247
250
  NewRelic::Agent.config.remove_config do |config|
248
251
  config.class == NewRelic::Agent::Configuration::ManualSource ||
249
252
  config.class == NewRelic::Agent::Configuration::ServerSource
250
253
  end
251
254
  @started = nil
255
+ Control.reset
252
256
  end
253
257
 
254
258
  # Tells the statistics engine we are starting a new transaction
@@ -298,18 +302,13 @@ module NewRelic
298
302
  Thread.current[:newrelic_untraced].pop if Thread.current[:newrelic_untraced]
299
303
  end
300
304
 
301
- # Shorthand to the NewRelic::Agent.logger method
302
- def log
303
- NewRelic::Agent.logger
304
- end
305
-
306
305
  # Herein lies the corpse of the former 'start' method. May
307
306
  # its unmatched flog score rest in pieces.
308
307
  module Start
309
308
  # Check whether we have already started, which is an error condition
310
309
  def already_started?
311
310
  if started?
312
- control.log!("Agent Started Already!", :error)
311
+ ::NewRelic::Agent.logger.error("Agent Started Already!")
313
312
  true
314
313
  end
315
314
  end
@@ -321,22 +320,35 @@ module NewRelic
321
320
  !Agent.config[:agent_enabled]
322
321
  end
323
322
 
323
+ # Log startup information that we almost always want to know
324
+ def log_startup
325
+ log_environment
326
+ log_dispatcher
327
+ log_app_names
328
+ end
329
+
330
+ # Log the environment the app thinks it's running in.
331
+ # Useful in debugging, as this is the key for config YAML lookups.
332
+ def log_environment
333
+ ::NewRelic::Agent.logger.info "Environment: #{NewRelic::Control.instance.env}"
334
+ end
335
+
324
336
  # Logs the dispatcher to the log file to assist with
325
337
  # debugging. When no debugger is present, logs this fact to
326
338
  # assist with proper dispatcher detection
327
339
  def log_dispatcher
328
340
  dispatcher_name = Agent.config[:dispatcher].to_s
329
- return if log_if(dispatcher_name.empty?, :info, "No dispatcher detected.")
330
- log.info "Dispatcher: #{dispatcher_name}"
341
+ return if log_if(dispatcher_name.empty?, :warn, "No dispatcher detected.")
342
+ ::NewRelic::Agent.logger.info "Dispatcher: #{dispatcher_name}"
331
343
  end
332
344
 
333
345
  # Logs the configured application names
334
346
  def log_app_names
335
347
  names = Agent.config.app_names
336
348
  if names.respond_to?(:any?) && names.any?
337
- log.info "Application: #{names.join(", ")}"
349
+ ::NewRelic::Agent.logger.info "Application: #{names.join(", ")}"
338
350
  else
339
- 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.'
351
+ ::NewRelic::Agent.logger.error 'Unable to determine application name. Please set the application name in your newrelic.yml or in a NEW_RELIC_APP_NAME environment variable.'
340
352
  end
341
353
  end
342
354
 
@@ -384,28 +396,18 @@ module NewRelic
384
396
  end
385
397
  end
386
398
 
387
- # Tells us in the log file where the log file is
388
- # located. This seems redundant, but can come in handy when
389
- # we have some log file path set by the user which parses
390
- # incorrectly, sending the log file to who-knows-where
391
- def notify_log_file_location
392
- log_file = NewRelic::Control.instance.log_file
393
- log_if(File.exists?(log_file.to_s), :info,
394
- "Agent Log at #{log_file}")
395
- end
396
-
397
399
  # Classy logging of the agent version and the current pid,
398
400
  # so we can disambiguate processes in the log file and make
399
401
  # sure they're running a reasonable version
400
402
  def log_version_and_pid
401
- log.info "New Relic Ruby Agent #{NewRelic::VERSION::STRING} Initialized: pid = #{$$}"
403
+ ::NewRelic::Agent.logger.debug "New Relic Ruby Agent #{NewRelic::VERSION::STRING} Initialized: pid = #{$$}"
402
404
  end
403
405
 
404
406
  # A helper method that logs a condition if that condition is
405
407
  # true. Mentally cleaner than having every method set a
406
408
  # local and log if it is true
407
409
  def log_if(boolean, level, message)
408
- self.log.send(level, message) if boolean
410
+ ::NewRelic::Agent.logger.send(level, message) if boolean
409
411
  boolean
410
412
  end
411
413
 
@@ -413,7 +415,7 @@ module NewRelic
413
415
  # condition is true. Mentally cleaner than having every
414
416
  # method set a local and log unless it is true
415
417
  def log_unless(boolean, level, message)
416
- self.log.send(level, message) unless boolean
418
+ ::NewRelic::Agent.logger.send(level, message) unless boolean
417
419
  boolean
418
420
  end
419
421
 
@@ -428,7 +430,8 @@ module NewRelic
428
430
  # fix it by adding it to the file
429
431
  def has_license_key?
430
432
  log_unless(Agent.config[:license_key], :warn,
431
- "No license key found in newrelic.yml config.")
433
+ "No license key found in newrelic.yml config. " +
434
+ "This often means your newrelic.yml is missing a section for the running environment '#{NewRelic::Control.instance.env}'")
432
435
  end
433
436
 
434
437
  # A correct license key exists and is of the proper length
@@ -470,11 +473,9 @@ module NewRelic
470
473
  return if already_started? || disabled?
471
474
  @started = true
472
475
  @local_host = determine_host
473
- log_dispatcher
474
- log_app_names
476
+ log_startup
475
477
  check_config_and_start_agent
476
478
  log_version_and_pid
477
- notify_log_file_location
478
479
  end
479
480
 
480
481
  # Clear out the metric data, errors, and transaction traces,
@@ -497,8 +498,8 @@ module NewRelic
497
498
  # logs info about the worker loop so users can see when the
498
499
  # agent actually begins running in the background
499
500
  def log_worker_loop_start
500
- log.info "Reporting performance data every #{Agent.config[:data_report_period]} seconds."
501
- log.debug "Running worker loop"
501
+ ::NewRelic::Agent.logger.debug "Reporting performance data every #{Agent.config[:data_report_period]} seconds."
502
+ ::NewRelic::Agent.logger.debug "Running worker loop"
502
503
  end
503
504
 
504
505
  # Creates the worker loop and loads it with the instructions
@@ -514,7 +515,7 @@ module NewRelic
514
515
  # this clears the data, clears connection attempts, and
515
516
  # waits a while to reconnect.
516
517
  def handle_force_restart(error)
517
- log.info error.message
518
+ ::NewRelic::Agent.logger.debug error.message
518
519
  reset_stats
519
520
  @metric_ids = {}
520
521
  @connected = nil
@@ -525,15 +526,14 @@ module NewRelic
525
526
  # is the worker thread that gathers data and talks to the
526
527
  # server.
527
528
  def handle_force_disconnect(error)
528
- log.error "New Relic forced this agent to disconnect (#{error.message})"
529
+ ::NewRelic::Agent.logger.warn "New Relic forced this agent to disconnect (#{error.message})"
529
530
  disconnect
530
531
  end
531
532
 
532
533
  # there is a problem with connecting to the server, so we
533
534
  # stop trying to connect and shut down the agent
534
535
  def handle_server_connection_problem(error)
535
- log.error "Unable to establish connection with the server. Run with log level set to debug for more information."
536
- log.debug("#{error.class.name}: #{error.message}\n#{error.backtrace.first}")
536
+ ::NewRelic::Agent.logger.error "Unable to establish connection with the server.", error
537
537
  disconnect
538
538
  end
539
539
 
@@ -541,7 +541,7 @@ module NewRelic
541
541
  # it and disconnecting the agent, since we are now in an
542
542
  # unknown state
543
543
  def handle_other_error(error)
544
- log.error "Terminating worker loop: #{error.class.name}: #{error.message}\n #{error.backtrace.join("\n ")}"
544
+ ::NewRelic::Agent.logger.error "Terminating worker loop.", error
545
545
  disconnect
546
546
  end
547
547
 
@@ -583,7 +583,7 @@ module NewRelic
583
583
  # never reaches here unless there is a problem or
584
584
  # the agent is exiting
585
585
  else
586
- log.debug "No connection. Worker thread ending."
586
+ ::NewRelic::Agent.logger.debug "No connection. Worker thread ending."
587
587
  end
588
588
  end
589
589
  end
@@ -595,7 +595,7 @@ module NewRelic
595
595
  #
596
596
  # See #connect for a description of connection_options.
597
597
  def start_worker_thread(connection_options = {})
598
- log.debug "Creating Ruby Agent worker thread."
598
+ ::NewRelic::Agent.logger.debug "Creating Ruby Agent worker thread."
599
599
  @worker_thread = NewRelic::Agent::AgentThread.new('Worker Loop') do
600
600
  deferred_work!(connection_options)
601
601
  end
@@ -658,7 +658,7 @@ module NewRelic
658
658
  if @keep_retrying
659
659
  self.connect_attempts=(connect_attempts + 1)
660
660
  increment_retry_period!
661
- log.info "Will re-attempt in #{connect_retry_period} seconds"
661
+ ::NewRelic::Agent.logger.warn "Will re-attempt in #{connect_retry_period} seconds"
662
662
  true
663
663
  else
664
664
  disconnect
@@ -670,8 +670,7 @@ module NewRelic
670
670
  # to tell the user what happened, since this is not an error
671
671
  # we can handle gracefully.
672
672
  def log_error(error)
673
- log.error "Error establishing connection with New Relic Service at #{control.server}: #{error.message}"
674
- log.debug error.backtrace.join("\n")
673
+ ::NewRelic::Agent.logger.error "Error establishing connection with New Relic Service at #{control.server}:", error
675
674
  end
676
675
 
677
676
  # When the server sends us an error with the license key, we
@@ -682,37 +681,18 @@ module NewRelic
682
681
  # no longer try to connect to the server, saving the
683
682
  # application and the server load
684
683
  def handle_license_error(error)
685
- log.error error.message
686
- log.info "Visit NewRelic.com to obtain a valid license key, or to upgrade your account."
684
+ ::NewRelic::Agent.logger.error( \
685
+ error.message, \
686
+ "Visit NewRelic.com to obtain a valid license key, or to upgrade your account.")
687
687
  disconnect
688
688
  end
689
689
 
690
- # If we are using a seed and token to validate the agent, we
691
- # should debug log that fact so that debug logs include a
692
- # clue that token authentication is what will be used
693
- def log_seed_token
694
- if Agent.config[:validate_seed]
695
- log.debug "Connecting with validation seed/token: #{Agent.config[:validate_seed]}/#{Agent.config[:validate_token]}"
696
- end
697
- end
698
-
699
690
  # Checks whether we should send environment info, and if so,
700
691
  # returns the snapshot from the local environment
701
692
  def environment_for_connect
702
693
  Agent.config[:send_environment_info] ? Control.instance.local_env.snapshot : []
703
694
  end
704
695
 
705
- # These validation settings are used for cases where a
706
- # dynamic server is spun up for clients - partners can
707
- # include a seed and token to indicate that the host is
708
- # allowed to connect, rather than setting a unique hostname
709
- def validate_settings
710
- {
711
- :seed => Agent.config[:validate_seed],
712
- :token => Agent.config[:validate_token]
713
- }
714
- end
715
-
716
696
  # Initializes the hash of settings that we send to the
717
697
  # server. Returns a literal hash containing the options
718
698
  def connect_settings
@@ -723,16 +703,12 @@ module NewRelic
723
703
  :language => 'ruby',
724
704
  :agent_version => NewRelic::VERSION::STRING,
725
705
  :environment => environment_for_connect,
726
- :settings => Agent.config.flattened_config,
727
- :validate => validate_settings
706
+ :settings => Agent.config.to_collector_hash,
728
707
  }
729
708
  end
730
709
 
731
- # Does some simple logging to make sure that our seed and
732
- # token for verification are correct, then returns the
733
- # connect data passed back from the server
710
+ # Returns connect data passed back from the server
734
711
  def connect_to_server
735
- log_seed_token
736
712
  @service.connect(connect_settings)
737
713
  end
738
714
 
@@ -760,23 +736,38 @@ module NewRelic
760
736
  @service.agent_id = config_data['agent_run_id'] if @service
761
737
 
762
738
  if config_data['agent_config']
763
- log.info "Using config from server"
739
+ ::NewRelic::Agent.logger.debug "Using config from server"
764
740
  end
765
741
 
766
- log.debug "Server provided config: #{config_data.inspect}"
742
+ ::NewRelic::Agent.logger.debug "Server provided config: #{config_data.inspect}"
767
743
  server_config = NewRelic::Agent::Configuration::ServerSource.new(config_data)
768
744
  Agent.config.apply_config(server_config, 1)
769
745
  log_connection!(config_data) if @service
770
746
 
747
+ @cross_process_id = Agent.config[:cross_process_id]
748
+ @cross_process_encoding_key = Agent.config[:encoding_key]
749
+ @cross_process_encoding_bytes = get_bytes(@cross_process_encoding_key) unless @cross_process_encoding_key.nil?
750
+
771
751
  @beacon_configuration = BeaconConfiguration.new
772
752
  end
773
753
 
754
+ # Ruby 1.8.6 doesn't support the bytes method on strings.
755
+ def get_bytes(value)
756
+ return [] if value.nil?
757
+
758
+ bytes = []
759
+ value.each_byte do |b|
760
+ bytes << b
761
+ end
762
+ bytes
763
+ end
764
+
774
765
  # Logs when we connect to the server, for debugging purposes
775
766
  # - makes sure we know if an agent has not connected
776
767
  def log_connection!(config_data)
777
- log.info "Connected to NewRelic Service at #{@service.collector.name}"
778
- log.debug "Agent Run = #{@service.agent_id}."
779
- log.debug "Connection data = #{config_data.inspect}"
768
+ ::NewRelic::Agent.logger.debug "Connected to NewRelic Service at #{@service.collector.name}"
769
+ ::NewRelic::Agent.logger.debug "Agent Run = #{@service.agent_id}."
770
+ ::NewRelic::Agent.logger.debug "Connection data = #{config_data.inspect}"
780
771
  if config_data['messages'] && config_data['messages'].any?
781
772
  log_collector_messages(config_data['messages'])
782
773
  end
@@ -784,7 +775,7 @@ module NewRelic
784
775
 
785
776
  def log_collector_messages(messages)
786
777
  messages.each do |message|
787
- log.send(message['level'].downcase.to_sym, message['message'])
778
+ ::NewRelic::Agent.logger.send(message['level'].downcase, message['message'])
788
779
  end
789
780
  end
790
781
  end
@@ -859,7 +850,7 @@ module NewRelic
859
850
  @connect_retry_period = should_keep_retrying?(options) ? 10 : 0
860
851
 
861
852
  sleep connect_retry_period
862
- log.debug "Connecting Process to New Relic: #$0"
853
+ ::NewRelic::Agent.logger.debug "Connecting Process to New Relic: #$0"
863
854
  query_server_for_configuration
864
855
  @connected_pid = $$
865
856
  @connected = true
@@ -930,11 +921,11 @@ module NewRelic
930
921
  now.to_f,
931
922
  @unsent_timeslice_data.values)
932
923
  rescue UnrecoverableServerException => e
933
- log.debug e.message
924
+ ::NewRelic::Agent.logger.debug e.message
934
925
  end
935
926
  fill_metric_id_cache(metric_specs_and_ids)
936
927
 
937
- log.debug "#{now}: sent #{@unsent_timeslice_data.length} timeslices (#{@service.agent_id}) in #{Time.now - now} seconds"
928
+ ::NewRelic::Agent.logger.debug "#{now}: sent #{@unsent_timeslice_data.length} timeslices (#{@service.agent_id}) in #{Time.now - now} seconds"
938
929
 
939
930
  # if we successfully invoked this web service, then clear the unsent message cache.
940
931
  @unsent_timeslice_data = {}
@@ -953,13 +944,13 @@ module NewRelic
953
944
  # FIXME add the code to try to resend if our connection is down
954
945
  sql_traces = @sql_sampler.harvest
955
946
  unless sql_traces.empty?
956
- log.debug "Sending (#{sql_traces.size}) sql traces"
947
+ ::NewRelic::Agent.logger.debug "Sending (#{sql_traces.size}) sql traces"
957
948
  begin
958
949
  @service.sql_trace_data(sql_traces)
959
950
  rescue UnrecoverableServerException => e
960
- log.debug e.message
951
+ ::NewRelic::Agent.logger.debug e.message
961
952
  rescue => e
962
- log.debug "Remerging SQL traces after #{e.class.name}: #{e.message}"
953
+ ::NewRelic::Agent.logger.debug "Remerging SQL traces after #{e.class.name}: #{e.message}"
963
954
  @sql_sampler.merge sql_traces
964
955
  end
965
956
  end
@@ -975,7 +966,7 @@ module NewRelic
975
966
  harvest_transaction_traces
976
967
  unless @traces.empty?
977
968
  now = Time.now
978
- log.debug "Sending (#{@traces.length}) transaction traces"
969
+ ::NewRelic::Agent.logger.debug "Sending (#{@traces.length}) transaction traces"
979
970
 
980
971
  begin
981
972
  options = { :keep_backtraces => true }
@@ -987,9 +978,9 @@ module NewRelic
987
978
  end
988
979
  traces = @traces.map {|trace| trace.prepare_to_send(options) }
989
980
  @service.transaction_sample_data(traces)
990
- log.debug "Sent slowest sample (#{@service.agent_id}) in #{Time.now - now} seconds"
981
+ ::NewRelic::Agent.logger.debug "Sent slowest sample (#{@service.agent_id}) in #{Time.now - now} seconds"
991
982
  rescue UnrecoverableServerException => e
992
- log.debug e.message
983
+ ::NewRelic::Agent.logger.debug e.message
993
984
  end
994
985
  end
995
986
 
@@ -1005,7 +996,7 @@ module NewRelic
1005
996
  if @thread_profiler.finished?
1006
997
  profile = @thread_profiler.harvest
1007
998
 
1008
- log.debug "Sending thread profile #{profile.profile_id}"
999
+ ::NewRelic::Agent.logger.debug "Sending thread profile #{profile.profile_id}"
1009
1000
  @service.profile_data(profile)
1010
1001
  end
1011
1002
  end
@@ -1025,11 +1016,11 @@ module NewRelic
1025
1016
  def harvest_and_send_errors
1026
1017
  harvest_errors
1027
1018
  if @unsent_errors && @unsent_errors.length > 0
1028
- log.debug "Sending #{@unsent_errors.length} errors"
1019
+ ::NewRelic::Agent.logger.debug "Sending #{@unsent_errors.length} errors"
1029
1020
  begin
1030
1021
  @service.error_data(@unsent_errors)
1031
1022
  rescue UnrecoverableServerException => e
1032
- log.debug e.message
1023
+ ::NewRelic::Agent.logger.debug e.message
1033
1024
  end
1034
1025
  # if the remote invocation fails, then we never clear
1035
1026
  # @unsent_errors, and therefore we can re-attempt to send on
@@ -1039,21 +1030,9 @@ module NewRelic
1039
1030
  end
1040
1031
  end
1041
1032
 
1042
- # Only JSON marshalling appears to work with collector on
1043
- # get_agent_commands and agent_command_results. We only support
1044
- # these features on Ruby versions that can hack JSON out of the box
1045
- def agent_commands_supported?
1046
- RUBY_VERSION >= "1.9.2"
1047
- end
1048
-
1049
1033
  def check_for_agent_commands
1050
- if !agent_commands_supported?
1051
- log.debug("Skipping agent commands, as they aren't supported on this environment")
1052
- return
1053
- end
1054
-
1055
1034
  commands = @service.get_agent_commands
1056
- log.debug "Received get_agent_commands = #{commands}"
1035
+ ::NewRelic::Agent.logger.debug "Received get_agent_commands = #{commands.inspect}"
1057
1036
 
1058
1037
  @thread_profiler.respond_to_commands(commands) do |command_id, error|
1059
1038
  @service.agent_command_results(command_id, error)
@@ -1062,7 +1041,7 @@ module NewRelic
1062
1041
 
1063
1042
  def transmit_data(disconnecting=false)
1064
1043
  now = Time.now
1065
- log.debug "Sending data to New Relic Service"
1044
+ ::NewRelic::Agent.logger.debug "Sending data to New Relic Service"
1066
1045
  harvest_and_send_errors
1067
1046
  harvest_and_send_slowest_sample
1068
1047
  harvest_and_send_slowest_sql
@@ -1074,7 +1053,7 @@ module NewRelic
1074
1053
  retry_count ||= 0
1075
1054
  retry_count += 1
1076
1055
  if retry_count <= 1
1077
- log.debug "retrying transmit_data after #{e}"
1056
+ ::NewRelic::Agent.logger.debug "retrying transmit_data after #{e}"
1078
1057
  retry
1079
1058
  end
1080
1059
  raise e
@@ -1098,17 +1077,17 @@ module NewRelic
1098
1077
  transmit_data(true)
1099
1078
 
1100
1079
  if @connected_pid == $$ && !@service.kind_of?(NewRelic::Agent::NewRelicService)
1101
- log.debug "Sending New Relic service agent run shutdown message"
1080
+ ::NewRelic::Agent.logger.debug "Sending New Relic service agent run shutdown message"
1102
1081
  @service.shutdown(Time.now.to_f)
1103
1082
  else
1104
- log.debug "This agent connected from parent process #{@connected_pid}--not sending shutdown"
1083
+ ::NewRelic::Agent.logger.debug "This agent connected from parent process #{@connected_pid}--not sending shutdown"
1105
1084
  end
1106
- log.debug "Graceful disconnect complete"
1085
+ ::NewRelic::Agent.logger.debug "Graceful disconnect complete"
1107
1086
  rescue Timeout::Error, StandardError => e
1108
- log.debug "Error when disconnecting #{e.class.name}: #{e.message}"
1087
+ ::NewRelic::Agent.logger.debug "Error when disconnecting #{e.class.name}: #{e.message}"
1109
1088
  end
1110
1089
  else
1111
- log.debug "Bypassing graceful disconnect - agent not connected"
1090
+ ::NewRelic::Agent.logger.debug "Bypassing graceful disconnect - agent not connected"
1112
1091
  end
1113
1092
  end
1114
1093
  end