newrelic_rpm 2.12.3 → 2.13.0.beta3

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 (118) hide show
  1. data/CHANGELOG +24 -2
  2. data/README.rdoc +172 -0
  3. data/bin/newrelic +13 -0
  4. data/bin/newrelic_cmd +2 -1
  5. data/install.rb +8 -45
  6. data/lib/new_relic/agent.rb +43 -30
  7. data/lib/new_relic/agent/agent.rb +699 -631
  8. data/lib/new_relic/agent/busy_calculator.rb +81 -81
  9. data/lib/new_relic/agent/error_collector.rb +9 -6
  10. data/lib/new_relic/agent/instrumentation/active_record_instrumentation.rb +2 -2
  11. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +10 -5
  12. data/lib/new_relic/agent/instrumentation/data_mapper.rb +13 -45
  13. data/lib/new_relic/agent/instrumentation/memcache.rb +15 -4
  14. data/lib/new_relic/agent/instrumentation/metric_frame.rb +37 -29
  15. data/lib/new_relic/agent/instrumentation/rack.rb +20 -34
  16. data/lib/new_relic/agent/method_tracer.rb +9 -9
  17. data/lib/new_relic/agent/samplers/delayed_job_lock_sampler.rb +31 -31
  18. data/lib/new_relic/agent/stats_engine/metric_stats.rb +5 -5
  19. data/lib/new_relic/agent/stats_engine/samplers.rb +3 -0
  20. data/lib/new_relic/agent/transaction_sampler.rb +31 -15
  21. data/lib/new_relic/agent/worker_loop.rb +29 -28
  22. data/lib/new_relic/collection_helper.rb +4 -2
  23. data/lib/new_relic/command.rb +85 -0
  24. data/lib/new_relic/commands/deployments.rb +74 -114
  25. data/lib/new_relic/commands/install.rb +81 -0
  26. data/lib/new_relic/control.rb +54 -379
  27. data/lib/new_relic/control/configuration.rb +149 -0
  28. data/lib/new_relic/control/{external.rb → frameworks/external.rb} +2 -2
  29. data/lib/new_relic/control/{merb.rb → frameworks/merb.rb} +1 -1
  30. data/lib/new_relic/control/frameworks/rails.rb +126 -0
  31. data/lib/new_relic/control/{rails3.rb → frameworks/rails3.rb} +11 -10
  32. data/lib/new_relic/control/{ruby.rb → frameworks/ruby.rb} +1 -1
  33. data/lib/new_relic/control/{sinatra.rb → frameworks/sinatra.rb} +2 -2
  34. data/lib/new_relic/control/instrumentation.rb +84 -0
  35. data/lib/new_relic/control/logging_methods.rb +74 -0
  36. data/lib/new_relic/control/profiling.rb +24 -0
  37. data/lib/new_relic/control/server_methods.rb +88 -0
  38. data/lib/new_relic/local_environment.rb +3 -3
  39. data/lib/new_relic/metric_parser.rb +13 -2
  40. data/lib/new_relic/metric_parser/active_record.rb +4 -1
  41. data/lib/new_relic/metric_parser/apdex.rb +53 -0
  42. data/lib/new_relic/metric_parser/controller.rb +13 -5
  43. data/lib/new_relic/metric_parser/mem_cache.rb +1 -1
  44. data/lib/new_relic/metric_parser/other_transaction.rb +21 -0
  45. data/lib/new_relic/metric_spec.rb +3 -3
  46. data/lib/new_relic/noticed_error.rb +1 -1
  47. data/lib/new_relic/rack/developer_mode.rb +257 -0
  48. data/lib/new_relic/rack/metric_app.rb +56 -50
  49. data/lib/new_relic/rack/mongrel_rpm.ru +7 -6
  50. data/lib/new_relic/rack/newrelic.yml +4 -3
  51. data/lib/new_relic/rack_app.rb +2 -1
  52. data/lib/new_relic/recipes.rb +7 -7
  53. data/lib/new_relic/stats.rb +6 -14
  54. data/lib/new_relic/timer_lib.rb +27 -0
  55. data/lib/new_relic/transaction_analysis.rb +2 -7
  56. data/lib/new_relic/transaction_sample.rb +17 -85
  57. data/lib/new_relic/url_rule.rb +14 -0
  58. data/lib/new_relic/version.rb +3 -3
  59. data/lib/newrelic_rpm.rb +5 -9
  60. data/newrelic.yml +26 -9
  61. data/newrelic_rpm.gemspec +67 -32
  62. data/test/config/newrelic.yml +5 -0
  63. data/test/config/test_control.rb +6 -8
  64. data/test/new_relic/agent/active_record_instrumentation_test.rb +5 -6
  65. data/test/new_relic/agent/agent_controller_test.rb +18 -4
  66. data/test/new_relic/agent/agent_test_controller.rb +1 -6
  67. data/test/new_relic/agent/busy_calculator_test.rb +2 -0
  68. data/test/new_relic/agent/collection_helper_test.rb +6 -6
  69. data/test/new_relic/agent/error_collector_test.rb +13 -21
  70. data/test/new_relic/agent/metric_data_test.rb +3 -6
  71. data/test/new_relic/agent/rpm_agent_test.rb +121 -117
  72. data/test/new_relic/agent/task_instrumentation_test.rb +128 -133
  73. data/test/new_relic/agent/transaction_sample_test.rb +176 -170
  74. data/test/new_relic/agent/worker_loop_test.rb +24 -18
  75. data/test/new_relic/control_test.rb +13 -3
  76. data/test/new_relic/deployments_api_test.rb +7 -7
  77. data/test/new_relic/environment_test.rb +1 -1
  78. data/test/new_relic/metric_parser_test.rb +58 -4
  79. data/test/new_relic/rack/episodes_test.rb +317 -0
  80. data/test/new_relic/stats_test.rb +3 -2
  81. data/test/test_contexts.rb +28 -0
  82. data/test/test_helper.rb +24 -5
  83. data/ui/helpers/{newrelic_helper.rb → developer_mode_helper.rb} +63 -23
  84. data/ui/views/layouts/newrelic_default.rhtml +6 -6
  85. data/ui/views/newrelic/_explain_plans.rhtml +4 -4
  86. data/ui/views/newrelic/_sample.rhtml +18 -17
  87. data/ui/views/newrelic/_segment.rhtml +1 -0
  88. data/ui/views/newrelic/_segment_row.rhtml +8 -8
  89. data/ui/views/newrelic/_show_sample_detail.rhtml +1 -1
  90. data/ui/views/newrelic/_show_sample_sql.rhtml +2 -2
  91. data/ui/views/newrelic/_sql_row.rhtml +8 -3
  92. data/ui/views/newrelic/_stack_trace.rhtml +9 -24
  93. data/ui/views/newrelic/_table.rhtml +1 -1
  94. data/ui/views/newrelic/explain_sql.rhtml +3 -2
  95. data/ui/views/newrelic/{images → file/images}/arrow-close.png +0 -0
  96. data/ui/views/newrelic/{images → file/images}/arrow-open.png +0 -0
  97. data/ui/views/newrelic/{images → file/images}/blue_bar.gif +0 -0
  98. data/ui/views/newrelic/{images → file/images}/file_icon.png +0 -0
  99. data/ui/views/newrelic/{images → file/images}/gray_bar.gif +0 -0
  100. data/ui/views/newrelic/{images → file/images}/new-relic-rpm-desktop.gif +0 -0
  101. data/ui/views/newrelic/{images → file/images}/new_relic_rpm_desktop.gif +0 -0
  102. data/ui/views/newrelic/{images → file/images}/textmate.png +0 -0
  103. data/ui/views/newrelic/file/javascript/jquery-1.4.2.js +6240 -0
  104. data/ui/views/newrelic/file/javascript/transaction_sample.js +120 -0
  105. data/ui/views/newrelic/{stylesheets → file/stylesheets}/style.css +0 -0
  106. data/ui/views/newrelic/index.rhtml +7 -5
  107. data/ui/views/newrelic/sample_not_found.rhtml +1 -1
  108. data/ui/views/newrelic/show_sample.rhtml +5 -6
  109. metadata +92 -34
  110. data/README.md +0 -138
  111. data/lib/new_relic/commands/new_relic_commands.rb +0 -30
  112. data/lib/new_relic/control/rails.rb +0 -151
  113. data/test/new_relic/agent/mock_ar_connection.rb +0 -40
  114. data/test/ui/newrelic_controller_test.rb +0 -14
  115. data/test/ui/newrelic_helper_test.rb +0 -53
  116. data/ui/controllers/newrelic_controller.rb +0 -220
  117. data/ui/views/newrelic/javascript/prototype-scriptaculous.js +0 -7288
  118. data/ui/views/newrelic/javascript/transaction_sample.js +0 -107
@@ -0,0 +1,149 @@
1
+ module NewRelic
2
+ class Control
3
+ module Configuration
4
+ def settings
5
+ unless @settings
6
+ @settings = (@yaml && merge_defaults(@yaml[env])) || {}
7
+ # At the time we bind the settings, we also need to run this little piece
8
+ # of magic which allows someone to augment the id with the app name, necessary
9
+ if self['multi_homed'] && app_names.size > 0
10
+ if @local_env.dispatcher_instance_id
11
+ @local_env.dispatcher_instance_id << ":#{app_names.first}"
12
+ else
13
+ @local_env.dispatcher_instance_id = app_names.first
14
+ end
15
+ end
16
+
17
+ end
18
+ @settings
19
+ end
20
+
21
+ def merge_defaults(settings_hash)
22
+ s = {
23
+ 'host' => 'collector.newrelic.com',
24
+ 'ssl' => false,
25
+ 'log_level' => 'info',
26
+ 'apdex_t' => 1.0
27
+ }
28
+ s.merge! settings_hash if settings_hash
29
+ # monitor_daemons replaced with agent_enabled
30
+ s['agent_enabled'] = s.delete('monitor_daemons') if s['agent_enabled'].nil? && s.include?('monitor_daemons')
31
+ s
32
+ end
33
+
34
+ # Merge the given options into the config options.
35
+ # They might be a nested hash
36
+ def merge_options(options, hash=self)
37
+ options.each do |key, val |
38
+ case
39
+ when key == :config then next
40
+ when val.is_a?(Hash)
41
+ merge_options(val, hash[key.to_s] ||= {})
42
+ when val.nil?
43
+ hash.delete(key.to_s)
44
+ else
45
+ hash[key.to_s] = val
46
+ end
47
+ end
48
+ end
49
+
50
+ def [](key)
51
+ fetch(key)
52
+ end
53
+
54
+ def []=(key, value)
55
+ settings[key] = value
56
+ end
57
+
58
+ def fetch(key, default=nil)
59
+ settings.fetch(key, default)
60
+ end
61
+
62
+ def apdex_t
63
+ # Always initialized with a default
64
+ fetch('apdex_t').to_f
65
+ end
66
+ def license_key
67
+ fetch('license_key')
68
+ end
69
+ def capture_params
70
+ fetch('capture_params')
71
+ end
72
+ # True if we are sending data to the server, monitoring production
73
+ def monitor_mode?
74
+ fetch('monitor_mode', fetch('enabled'))
75
+ end
76
+
77
+ # True if we are capturing data and displaying in /newrelic
78
+ def developer_mode?
79
+ fetch('developer_mode', fetch('developer'))
80
+ end
81
+
82
+ def episodes_enabled?
83
+ fetch('episodes_enabled', true)
84
+ end
85
+ # True if the app runs in multi-threaded mode
86
+ def multi_threaded?
87
+ fetch('multi_threaded')
88
+ end
89
+ # True if we should view files in textmate
90
+ def use_textmate?
91
+ fetch('textmate')
92
+ end
93
+ def post_size_limit
94
+ fetch('post_size_limit', 2 * 1024 * 1024)
95
+ end
96
+
97
+ # Configuration option of the same name to indicate that we should connect
98
+ # to RPM synchronously on startup. This means when the agent is loaded it
99
+ # won't return without trying to set up the server connection at least once
100
+ # which can make startup take longer. Defaults to false.
101
+ def sync_startup
102
+ fetch('sync_startup', false)
103
+ end
104
+
105
+ # Configuration option of the same name to indicate that we should flush
106
+ # data to the server on exiting. Defaults to true.
107
+ def send_data_on_exit
108
+ fetch('send_data_on_exit', true)
109
+ end
110
+
111
+ def dispatcher_instance_id
112
+ self['dispatcher_instance_id'] || @local_env.dispatcher_instance_id
113
+ end
114
+
115
+ def dispatcher
116
+ (self['dispatcher'] && self['dispatcher'].to_sym) || @local_env.dispatcher
117
+ end
118
+ def app_names
119
+ case self['app_name']
120
+ when Array then self['app_name']
121
+ when String then self['app_name'].split(';')
122
+ else [ env ]
123
+ end
124
+ end
125
+ def validate_seed
126
+ self['validate_seed'] || ENV['NR_VALIDATE_SEED']
127
+ end
128
+ def validate_token
129
+ self['validate_token'] || ENV['NR_VALIDATE_TOKEN']
130
+ end
131
+
132
+ def use_ssl?
133
+ @use_ssl = fetch('ssl', false) unless @use_ssl
134
+ @use_ssl
135
+ end
136
+
137
+ def verify_certificate?
138
+ unless @verify_certificate
139
+ unless use_ssl?
140
+ @verify_certificate = false
141
+ else
142
+ @verify_certificate = fetch('verify_certificate', false)
143
+ end
144
+ end
145
+ @verify_certificate
146
+ end
147
+ end
148
+ end
149
+ end
@@ -2,9 +2,9 @@
2
2
  # The New Relic Infrastructure Agent. We want to call this
3
3
  # out specifically because in this context we are not monitoring
4
4
  # the running process, but actually external things.
5
- require 'new_relic/control/ruby'
5
+ require 'new_relic/control/frameworks/ruby'
6
6
 
7
- class NewRelic::Control::External < NewRelic::Control::Ruby
7
+ class NewRelic::Control::Frameworks::External < NewRelic::Control::Frameworks::Ruby
8
8
 
9
9
  def init_config(options={})
10
10
  super
@@ -1,4 +1,4 @@
1
- class NewRelic::Control::Merb < NewRelic::Control
1
+ class NewRelic::Control::Frameworks::Merb < NewRelic::Control
2
2
 
3
3
  def env
4
4
  @env ||= ::Merb.env
@@ -0,0 +1,126 @@
1
+ # Control subclass instantiated when Rails is detected. Contains
2
+ # Rails specific configuration, instrumentation, environment values,
3
+ # etc.
4
+ class NewRelic::Control::Frameworks::Rails < NewRelic::Control
5
+
6
+ def env
7
+ @env ||= RAILS_ENV.dup
8
+ end
9
+ def root
10
+ RAILS_ROOT
11
+ end
12
+
13
+ # In versions of Rails prior to 2.0, the rails config was only available to
14
+ # the init.rb, so it had to be passed on from there.
15
+ def init_config(options={})
16
+ rails_config=options[:config]
17
+ if !agent_enabled?
18
+ # Might not be running if it does not think mongrel, thin, passenger, etc
19
+ # is running, if it things it's a rake task, or if the agent_enabled is false.
20
+ log! "New Relic Agent not running."
21
+ else
22
+ log! "Starting the New Relic Agent."
23
+ install_developer_mode rails_config if developer_mode?
24
+ install_episodes rails_config
25
+ end
26
+ end
27
+
28
+ def install_episodes(config)
29
+ return if config.nil? || !config.respond_to?(:middleware) || !episodes_enabled?
30
+ config.after_initialize do
31
+ if defined?(NewRelic::Rack::Episodes)
32
+ config.middleware.use NewRelic::Rack::Episodes
33
+ log! "Installed episodes middleware"
34
+ ::RAILS_DEFAULT_LOGGER.info "Installed episodes middleware"
35
+ end
36
+ end
37
+ end
38
+
39
+ def install_developer_mode(rails_config)
40
+ return if @installed
41
+ @installed = true
42
+ if rails_config && rails_config.respond_to?(:middleware)
43
+ begin
44
+ require 'new_relic/rack/developer_mode'
45
+ rails_config.middleware.use NewRelic::Rack::DeveloperMode
46
+
47
+ # inform user that the dev edition is available if we are running inside
48
+ # a webserver process
49
+ if @local_env.dispatcher_instance_id
50
+ port = @local_env.dispatcher_instance_id.to_s =~ /^\d+/ ? ":#{local_env.dispatcher_instance_id}" : ":port"
51
+ log!("NewRelic Agent Developer Mode enabled.")
52
+ log!("To view performance information, go to http://localhost#{port}/newrelic")
53
+ end
54
+ rescue Exception => e
55
+ log!("Error installing New Relic Developer Mode: #{e.inspect}", :error)
56
+ end
57
+ else
58
+ log!("Developer mode not available for Rails versions prior to 2.2", :warn)
59
+ end
60
+ end
61
+
62
+ def log!(msg, level=:info)
63
+ return unless should_log?
64
+ begin
65
+ ::RAILS_DEFAULT_LOGGER.send(level, msg)
66
+ rescue Exception => e
67
+ super
68
+ end
69
+ end
70
+
71
+ def to_stdout(message)
72
+ ::RAILS_DEFAULT_LOGGER.info(message)
73
+ rescue Exception => e
74
+ super
75
+ end
76
+
77
+ def rails_version
78
+ @rails_version ||= NewRelic::VersionNumber.new(::Rails::VERSION::STRING)
79
+ end
80
+
81
+ protected
82
+
83
+ def rails_vendor_root
84
+ File.join(root,'vendor','rails')
85
+ end
86
+
87
+ # Collect the Rails::Info into an associative array as well as the list of plugins
88
+ def append_environment_info
89
+ local_env.append_environment_value('Rails version'){ ::Rails::VERSION::STRING }
90
+ if rails_version >= NewRelic::VersionNumber.new('2.2.0')
91
+ local_env.append_environment_value('Rails threadsafe') do
92
+ ::Rails.configuration.action_controller.allow_concurrency == true
93
+ end
94
+ end
95
+ local_env.append_environment_value('Rails Env') { ENV['RAILS_ENV'] }
96
+ if rails_version >= NewRelic::VersionNumber.new('2.1.0')
97
+ local_env.append_gem_list do
98
+ ::Rails.configuration.gems.map do | gem |
99
+ version = (gem.respond_to?(:version) && gem.version) ||
100
+ (gem.specification.respond_to?(:version) && gem.specification.version)
101
+ gem.name + (version ? "(#{version})" : "")
102
+ end
103
+ end
104
+ # The plugins is configured manually. If it's nil, it loads everything non-deterministically
105
+ if ::Rails.configuration.plugins
106
+ local_env.append_plugin_list { ::Rails.configuration.plugins }
107
+ else
108
+ ::Rails.configuration.plugin_paths.each do |path|
109
+ local_env.append_plugin_list { Dir[File.join(path, '*')].collect{ |p| File.basename p if File.directory? p }.compact }
110
+ end
111
+ end
112
+ else
113
+ # Rails prior to 2.1, can't get the gems. Find plugins in the default location
114
+ local_env.append_plugin_list do
115
+ Dir[File.join(root, 'vendor', 'plugins', '*')].collect{ |p| File.basename p if File.directory? p }.compact
116
+ end
117
+ end
118
+ end
119
+
120
+ def install_shim
121
+ super
122
+ require 'new_relic/agent/instrumentation/controller_instrumentation'
123
+ ActionController::Base.send :include, NewRelic::Agent::Instrumentation::ControllerInstrumentation::Shim
124
+ end
125
+
126
+ end
@@ -1,7 +1,7 @@
1
1
  # Control subclass instantiated when Rails is detected. Contains
2
2
  # Rails specific configuration, instrumentation, environment values,
3
3
  # etc.
4
- class NewRelic::Control::Rails3 < NewRelic::Control
4
+ class NewRelic::Control::Frameworks::Rails3 < NewRelic::Control
5
5
 
6
6
  def env
7
7
  @env ||= ::Rails.env.to_s
@@ -15,17 +15,18 @@ class NewRelic::Control::Rails3 < NewRelic::Control
15
15
  ::Rails.logger
16
16
  end
17
17
 
18
- def base_log_file
19
- logger.instance_eval {
20
- @log.path
21
- }
22
- rescue
23
- File.join(root, 'log')
18
+
19
+ def log!(msg, level=:info)
20
+ return unless should_log?
21
+ logger.send(level, msg)
22
+ rescue Exception => e
23
+ super
24
24
  end
25
- private :base_log_file
26
25
 
27
- def log_path
28
- @log_path ||= File.expand_path(File.dirname(base_log_file))
26
+ def to_stdout(msg)
27
+ logger.info(msg)
28
+ rescue
29
+ super
29
30
  end
30
31
 
31
32
  def vendor_root
@@ -3,7 +3,7 @@
3
3
  # including ./, ./config, $HOME/.newrelic and $HOME/.
4
4
  # It loads the settings from the newrelic.yml section
5
5
  # based on the value of RUBY_ENV or RAILS_ENV.
6
- class NewRelic::Control::Ruby < NewRelic::Control
6
+ class NewRelic::Control::Frameworks::Ruby < NewRelic::Control
7
7
 
8
8
  def env
9
9
  @env ||= ENV['RUBY_ENV'] || ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
@@ -1,7 +1,7 @@
1
1
 
2
- require 'new_relic/control/ruby'
2
+ require 'new_relic/control/frameworks/ruby'
3
3
 
4
- class NewRelic::Control::Sinatra < NewRelic::Control::Ruby
4
+ class NewRelic::Control::Frameworks::Sinatra < NewRelic::Control::Frameworks::Ruby
5
5
 
6
6
  def env
7
7
  @env ||= ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development'
@@ -0,0 +1,84 @@
1
+ module NewRelic
2
+ class Control
3
+ module Instrumentation
4
+ def load_instrumentation_files pattern
5
+ Dir.glob(pattern) do |file|
6
+ begin
7
+ log.debug "Processing instrumentation file '#{file}'"
8
+ require file
9
+ rescue => e
10
+ log.error "Error loading instrumentation file '#{file}': #{e}"
11
+ log.debug e.backtrace.join("\n")
12
+ end
13
+ end
14
+ end
15
+
16
+ # Install stubs to the proper location so the app code will not fail
17
+ # if the agent is not running.
18
+ def install_shim
19
+ # Once we install instrumentation, you can't undo that by installing the shim.
20
+ raise "Cannot install the Agent shim after instrumentation has already been installed!" if @instrumented
21
+ NewRelic::Agent.agent = NewRelic::Agent::ShimAgent.instance
22
+ end
23
+
24
+ # Add instrumentation. Don't call this directly. Use NewRelic::Agent#add_instrumentation.
25
+ # This will load the file synchronously if we've already loaded the default
26
+ # instrumentation.
27
+ #
28
+ def add_instrumentation pattern
29
+ if @instrumented
30
+ load_instrumentation_files pattern
31
+ else
32
+ @instrumentation_files << pattern
33
+ end
34
+ end
35
+ def install_instrumentation
36
+ if defined?(Rails.initialized?) && !Rails.initialized?
37
+ Rails.configuration.after_initialize do
38
+ _install_instrumentation
39
+ end
40
+ else
41
+ _install_instrumentation
42
+ end
43
+ end
44
+
45
+ def load_samplers
46
+ agent = NewRelic::Agent.instance
47
+ NewRelic::Agent::Sampler.sampler_classes.each do | subclass |
48
+ begin
49
+ log.debug "#{subclass.name} not supported on this platform." and next if not subclass.supported_on_this_platform?
50
+ sampler = subclass.new
51
+ if subclass.use_harvest_sampler?
52
+ agent.stats_engine.add_harvest_sampler sampler
53
+ log.debug "Registered #{subclass.name} for harvest time sampling"
54
+ else
55
+ agent.stats_engine.add_sampler sampler
56
+ log.debug "Registered #{subclass.name} for periodic sampling"
57
+ end
58
+ rescue NewRelic::Agent::Sampler::Unsupported => e
59
+ log.info "#{subclass} sampler not available: #{e}"
60
+ rescue => e
61
+ log.error "Error registering sampler: #{e}, #{e.backtrace.join("\n")}"
62
+ end
63
+ end
64
+ end
65
+
66
+ private
67
+
68
+ def _install_instrumentation
69
+ return if @instrumented
70
+
71
+ @instrumented = true
72
+
73
+ # Instrumentation for the key code points inside rails for monitoring by NewRelic.
74
+ # note this file is loaded only if the newrelic agent is enabled (through config/newrelic.yml)
75
+ instrumentation_path = File.join(File.dirname(__FILE__), '..', 'agent','instrumentation')
76
+ @instrumentation_files <<
77
+ File.join(instrumentation_path, '*.rb') <<
78
+ File.join(instrumentation_path, app.to_s, '*.rb')
79
+ @instrumentation_files.each { | pattern | load_instrumentation_files pattern }
80
+ log.debug "Finished instrumentation"
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,74 @@
1
+
2
+ module NewRelic
3
+ class Control
4
+ module LoggingMethods
5
+
6
+ attr_accessor :log_file
7
+
8
+ def log
9
+ # If we try to get a log before one has been set up, return a stdout log
10
+ unless @log
11
+ l = Logger.new(STDOUT)
12
+ l.level = Logger::INFO
13
+ return l
14
+ end
15
+ @log
16
+ end
17
+
18
+ # send the given message to STDOUT so that it shows
19
+ # up in the console. This should be used for important informational messages at boot.
20
+ # The to_stdout may be implemented differently by different config subclasses.
21
+ # This will NOT print anything if tracers are not enabled
22
+ def log!(msg, level=:info)
23
+ return unless should_log?
24
+ to_stdout msg
25
+ log.send level, msg if @log
26
+ end
27
+
28
+ def should_log?
29
+ @settings && agent_enabled?
30
+ end
31
+
32
+ # Control subclasses may override this, but it can be called multiple times.
33
+ def setup_log
34
+ @log_file = "#{log_path}/#{log_file_name}"
35
+ @log = Logger.new(@log_file) rescue nil
36
+
37
+ # change the format just for our logger
38
+
39
+ def log.format_message(severity, timestamp, progname, msg)
40
+ "[#{timestamp.strftime("%m/%d/%y %H:%M:%S %z")} #{Socket.gethostname} (#{$$})] #{severity} : #{msg}\n"
41
+ end
42
+
43
+ # set the log level as specified in the config file
44
+
45
+ case fetch("log_level","info").downcase
46
+ when "debug" then log.level = Logger::DEBUG
47
+ when "info" then log.level = Logger::INFO
48
+ when "warn" then log.level = Logger::WARN
49
+ when "error" then log.level = Logger::ERROR
50
+ when "fatal" then log.level = Logger::FATAL
51
+ else log.level = Logger::INFO
52
+ end
53
+ log
54
+ end
55
+
56
+ def to_stdout(msg)
57
+ STDOUT.puts "** [NewRelic] " + msg
58
+ end
59
+
60
+ def log_path
61
+ return if @log_path
62
+ @log_path = File.expand_path(fetch('log_file_path', 'log/'))
63
+ if !File.directory?(@log_path) && ! (Dir.mkdir(@log_path) rescue nil)
64
+ log!("Error creating New Relic log directory '#{@log_path}'", :error)
65
+ end
66
+ @log_path
67
+ end
68
+
69
+ def log_file_name
70
+ fetch('log_file_name', 'newrelic_agent.log')
71
+ end
72
+ end
73
+ end
74
+ end