honkster-newrelic_rpm 2.13.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (174) hide show
  1. data/CHANGELOG +462 -0
  2. data/LICENSE +37 -0
  3. data/README.rdoc +172 -0
  4. data/bin/mongrel_rpm +33 -0
  5. data/bin/newrelic +13 -0
  6. data/bin/newrelic_cmd +5 -0
  7. data/cert/cacert.pem +34 -0
  8. data/install.rb +9 -0
  9. data/lib/new_relic/agent.rb +382 -0
  10. data/lib/new_relic/agent/agent.rb +741 -0
  11. data/lib/new_relic/agent/busy_calculator.rb +91 -0
  12. data/lib/new_relic/agent/chained_call.rb +13 -0
  13. data/lib/new_relic/agent/error_collector.rb +131 -0
  14. data/lib/new_relic/agent/instrumentation/active_merchant.rb +18 -0
  15. data/lib/new_relic/agent/instrumentation/active_record_instrumentation.rb +92 -0
  16. data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +45 -0
  17. data/lib/new_relic/agent/instrumentation/authlogic.rb +8 -0
  18. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +409 -0
  19. data/lib/new_relic/agent/instrumentation/data_mapper.rb +58 -0
  20. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +22 -0
  21. data/lib/new_relic/agent/instrumentation/memcache.rb +40 -0
  22. data/lib/new_relic/agent/instrumentation/merb/controller.rb +26 -0
  23. data/lib/new_relic/agent/instrumentation/merb/errors.rb +9 -0
  24. data/lib/new_relic/agent/instrumentation/metric_frame.rb +319 -0
  25. data/lib/new_relic/agent/instrumentation/net.rb +17 -0
  26. data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +22 -0
  27. data/lib/new_relic/agent/instrumentation/rack.rb +98 -0
  28. data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +59 -0
  29. data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +27 -0
  30. data/lib/new_relic/agent/instrumentation/rails/errors.rb +24 -0
  31. data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +45 -0
  32. data/lib/new_relic/agent/instrumentation/rails3/errors.rb +21 -0
  33. data/lib/new_relic/agent/instrumentation/sinatra.rb +46 -0
  34. data/lib/new_relic/agent/instrumentation/sunspot.rb +17 -0
  35. data/lib/new_relic/agent/instrumentation/unicorn_instrumentation.rb +10 -0
  36. data/lib/new_relic/agent/method_tracer.rb +350 -0
  37. data/lib/new_relic/agent/sampler.rb +50 -0
  38. data/lib/new_relic/agent/samplers/cpu_sampler.rb +54 -0
  39. data/lib/new_relic/agent/samplers/delayed_job_lock_sampler.rb +37 -0
  40. data/lib/new_relic/agent/samplers/memory_sampler.rb +142 -0
  41. data/lib/new_relic/agent/samplers/object_sampler.rb +24 -0
  42. data/lib/new_relic/agent/shim_agent.rb +25 -0
  43. data/lib/new_relic/agent/stats_engine.rb +24 -0
  44. data/lib/new_relic/agent/stats_engine/metric_stats.rb +118 -0
  45. data/lib/new_relic/agent/stats_engine/samplers.rb +83 -0
  46. data/lib/new_relic/agent/stats_engine/transactions.rb +149 -0
  47. data/lib/new_relic/agent/transaction_sampler.rb +330 -0
  48. data/lib/new_relic/agent/worker_loop.rb +81 -0
  49. data/lib/new_relic/collection_helper.rb +71 -0
  50. data/lib/new_relic/command.rb +85 -0
  51. data/lib/new_relic/commands/deployments.rb +105 -0
  52. data/lib/new_relic/commands/install.rb +81 -0
  53. data/lib/new_relic/control.rb +203 -0
  54. data/lib/new_relic/control/configuration.rb +149 -0
  55. data/lib/new_relic/control/frameworks/external.rb +13 -0
  56. data/lib/new_relic/control/frameworks/merb.rb +24 -0
  57. data/lib/new_relic/control/frameworks/rails.rb +126 -0
  58. data/lib/new_relic/control/frameworks/rails3.rb +60 -0
  59. data/lib/new_relic/control/frameworks/ruby.rb +36 -0
  60. data/lib/new_relic/control/frameworks/sinatra.rb +18 -0
  61. data/lib/new_relic/control/instrumentation.rb +95 -0
  62. data/lib/new_relic/control/logging_methods.rb +74 -0
  63. data/lib/new_relic/control/profiling.rb +24 -0
  64. data/lib/new_relic/control/server_methods.rb +88 -0
  65. data/lib/new_relic/delayed_job_injection.rb +27 -0
  66. data/lib/new_relic/histogram.rb +91 -0
  67. data/lib/new_relic/local_environment.rb +333 -0
  68. data/lib/new_relic/merbtasks.rb +6 -0
  69. data/lib/new_relic/metric_data.rb +42 -0
  70. data/lib/new_relic/metric_parser.rb +136 -0
  71. data/lib/new_relic/metric_parser/action_mailer.rb +9 -0
  72. data/lib/new_relic/metric_parser/active_merchant.rb +26 -0
  73. data/lib/new_relic/metric_parser/active_record.rb +28 -0
  74. data/lib/new_relic/metric_parser/apdex.rb +88 -0
  75. data/lib/new_relic/metric_parser/controller.rb +62 -0
  76. data/lib/new_relic/metric_parser/controller_cpu.rb +38 -0
  77. data/lib/new_relic/metric_parser/errors.rb +6 -0
  78. data/lib/new_relic/metric_parser/external.rb +50 -0
  79. data/lib/new_relic/metric_parser/mem_cache.rb +50 -0
  80. data/lib/new_relic/metric_parser/other_transaction.rb +36 -0
  81. data/lib/new_relic/metric_parser/view.rb +61 -0
  82. data/lib/new_relic/metric_parser/web_frontend.rb +14 -0
  83. data/lib/new_relic/metric_parser/web_service.rb +9 -0
  84. data/lib/new_relic/metric_spec.rb +67 -0
  85. data/lib/new_relic/metrics.rb +9 -0
  86. data/lib/new_relic/noticed_error.rb +24 -0
  87. data/lib/new_relic/rack/developer_mode.rb +257 -0
  88. data/lib/new_relic/rack/metric_app.rb +64 -0
  89. data/lib/new_relic/rack/mongrel_rpm.ru +26 -0
  90. data/lib/new_relic/rack/newrelic.yml +27 -0
  91. data/lib/new_relic/rack_app.rb +6 -0
  92. data/lib/new_relic/recipes.rb +82 -0
  93. data/lib/new_relic/stats.rb +368 -0
  94. data/lib/new_relic/timer_lib.rb +27 -0
  95. data/lib/new_relic/transaction_analysis.rb +119 -0
  96. data/lib/new_relic/transaction_sample.rb +586 -0
  97. data/lib/new_relic/url_rule.rb +14 -0
  98. data/lib/new_relic/version.rb +55 -0
  99. data/lib/new_relic_api.rb +276 -0
  100. data/lib/newrelic_rpm.rb +49 -0
  101. data/lib/tasks/all.rb +4 -0
  102. data/lib/tasks/install.rake +7 -0
  103. data/lib/tasks/tests.rake +15 -0
  104. data/newrelic.yml +246 -0
  105. data/newrelic_rpm.gemspec +254 -0
  106. data/recipes/newrelic.rb +6 -0
  107. data/test/active_record_fixtures.rb +55 -0
  108. data/test/config/newrelic.yml +48 -0
  109. data/test/config/test_control.rb +36 -0
  110. data/test/new_relic/agent/active_record_instrumentation_test.rb +286 -0
  111. data/test/new_relic/agent/agent_controller_test.rb +294 -0
  112. data/test/new_relic/agent/agent_test_controller.rb +77 -0
  113. data/test/new_relic/agent/busy_calculator_test.rb +81 -0
  114. data/test/new_relic/agent/collection_helper_test.rb +125 -0
  115. data/test/new_relic/agent/error_collector_test.rb +163 -0
  116. data/test/new_relic/agent/memcache_instrumentation_test.rb +103 -0
  117. data/test/new_relic/agent/method_tracer_test.rb +340 -0
  118. data/test/new_relic/agent/metric_data_test.rb +53 -0
  119. data/test/new_relic/agent/metric_frame_test.rb +51 -0
  120. data/test/new_relic/agent/mock_scope_listener.rb +23 -0
  121. data/test/new_relic/agent/net_instrumentation_test.rb +77 -0
  122. data/test/new_relic/agent/rpm_agent_test.rb +142 -0
  123. data/test/new_relic/agent/stats_engine/metric_stats_test.rb +79 -0
  124. data/test/new_relic/agent/stats_engine/samplers_test.rb +72 -0
  125. data/test/new_relic/agent/stats_engine/stats_engine_test.rb +184 -0
  126. data/test/new_relic/agent/task_instrumentation_test.rb +188 -0
  127. data/test/new_relic/agent/testable_agent.rb +13 -0
  128. data/test/new_relic/agent/transaction_sample_builder_test.rb +195 -0
  129. data/test/new_relic/agent/transaction_sample_test.rb +192 -0
  130. data/test/new_relic/agent/transaction_sampler_test.rb +385 -0
  131. data/test/new_relic/agent/worker_loop_test.rb +66 -0
  132. data/test/new_relic/control_test.rb +127 -0
  133. data/test/new_relic/deployments_api_test.rb +69 -0
  134. data/test/new_relic/environment_test.rb +75 -0
  135. data/test/new_relic/metric_parser_test.rb +226 -0
  136. data/test/new_relic/metric_spec_test.rb +177 -0
  137. data/test/new_relic/rack/episodes_test.rb +318 -0
  138. data/test/new_relic/shim_agent_test.rb +9 -0
  139. data/test/new_relic/stats_test.rb +312 -0
  140. data/test/new_relic/version_number_test.rb +89 -0
  141. data/test/test_contexts.rb +28 -0
  142. data/test/test_helper.rb +72 -0
  143. data/ui/helpers/developer_mode_helper.rb +359 -0
  144. data/ui/helpers/google_pie_chart.rb +49 -0
  145. data/ui/views/layouts/newrelic_default.rhtml +47 -0
  146. data/ui/views/newrelic/_explain_plans.rhtml +27 -0
  147. data/ui/views/newrelic/_sample.rhtml +20 -0
  148. data/ui/views/newrelic/_segment.rhtml +29 -0
  149. data/ui/views/newrelic/_segment_limit_message.rhtml +1 -0
  150. data/ui/views/newrelic/_segment_row.rhtml +14 -0
  151. data/ui/views/newrelic/_show_sample_detail.rhtml +24 -0
  152. data/ui/views/newrelic/_show_sample_sql.rhtml +20 -0
  153. data/ui/views/newrelic/_show_sample_summary.rhtml +3 -0
  154. data/ui/views/newrelic/_sql_row.rhtml +16 -0
  155. data/ui/views/newrelic/_stack_trace.rhtml +15 -0
  156. data/ui/views/newrelic/_table.rhtml +12 -0
  157. data/ui/views/newrelic/explain_sql.rhtml +43 -0
  158. data/ui/views/newrelic/file/images/arrow-close.png +0 -0
  159. data/ui/views/newrelic/file/images/arrow-open.png +0 -0
  160. data/ui/views/newrelic/file/images/blue_bar.gif +0 -0
  161. data/ui/views/newrelic/file/images/file_icon.png +0 -0
  162. data/ui/views/newrelic/file/images/gray_bar.gif +0 -0
  163. data/ui/views/newrelic/file/images/new-relic-rpm-desktop.gif +0 -0
  164. data/ui/views/newrelic/file/images/new_relic_rpm_desktop.gif +0 -0
  165. data/ui/views/newrelic/file/images/textmate.png +0 -0
  166. data/ui/views/newrelic/file/javascript/jquery-1.4.2.js +6240 -0
  167. data/ui/views/newrelic/file/javascript/transaction_sample.js +120 -0
  168. data/ui/views/newrelic/file/stylesheets/style.css +484 -0
  169. data/ui/views/newrelic/index.rhtml +59 -0
  170. data/ui/views/newrelic/sample_not_found.rhtml +2 -0
  171. data/ui/views/newrelic/show_sample.rhtml +79 -0
  172. data/ui/views/newrelic/show_source.rhtml +3 -0
  173. data/ui/views/newrelic/threads.rhtml +52 -0
  174. metadata +307 -0
@@ -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
@@ -0,0 +1,13 @@
1
+ # This is the control used when starting up in the context of
2
+ # The New Relic Infrastructure Agent. We want to call this
3
+ # out specifically because in this context we are not monitoring
4
+ # the running process, but actually external things.
5
+ require 'new_relic/control/frameworks/ruby'
6
+
7
+ class NewRelic::Control::Frameworks::External < NewRelic::Control::Frameworks::Ruby
8
+
9
+ def init_config(options={})
10
+ super
11
+ end
12
+
13
+ end
@@ -0,0 +1,24 @@
1
+ class NewRelic::Control::Frameworks::Merb < NewRelic::Control
2
+
3
+ def env
4
+ @env ||= ::Merb.env
5
+ end
6
+ def root
7
+ ::Merb.root
8
+ end
9
+
10
+ def to_stdout(msg)
11
+ Merb.logger.info("NewRelic ~ " + msg)
12
+ rescue Exception => e
13
+ STDOUT.puts "NewRelic ~ " + msg
14
+ end
15
+
16
+ def init_config options={}
17
+ ::Merb::Plugins.add_rakefiles File.join(newrelic_root,"lib/tasks/all.rb")
18
+
19
+ # Merb gives you a Merb::Plugins.config hash...feel free to put your stuff in your piece of it
20
+ ::Merb::Plugins.config[:newrelic] = {
21
+ :config => self
22
+ }
23
+ end
24
+ end
@@ -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
@@ -0,0 +1,60 @@
1
+ # Control subclass instantiated when Rails is detected. Contains
2
+ # Rails specific configuration, instrumentation, environment values,
3
+ # etc.
4
+ require 'new_relic/control/frameworks/rails'
5
+ class NewRelic::Control::Frameworks::Rails3 < NewRelic::Control::Frameworks::Rails
6
+
7
+ def env
8
+ @env ||= ::Rails.env.to_s
9
+ end
10
+
11
+ def root
12
+ @root ||= Rails.root.to_s
13
+ end
14
+
15
+ def logger
16
+ ::Rails.logger
17
+ end
18
+
19
+
20
+ def log!(msg, level=:info)
21
+ return unless should_log?
22
+ logger.send(level, msg)
23
+ rescue Exception => e
24
+ super
25
+ end
26
+
27
+ def to_stdout(msg)
28
+ logger.info(msg)
29
+ rescue
30
+ super
31
+ end
32
+
33
+ def vendor_root
34
+ @vendor_root ||= File.join(root,'vendor','rails')
35
+ end
36
+
37
+ def version
38
+ @rails_version ||= NewRelic::VersionNumber.new(::Rails::VERSION::STRING)
39
+ end
40
+
41
+ protected
42
+
43
+ # Collect the Rails::Info into an associative array as well as the list of plugins
44
+ def append_environment_info
45
+ local_env.append_environment_value('Rails version'){ version }
46
+ local_env.append_environment_value('Rails threadsafe') do
47
+ ::Rails.configuration.action_controller.allow_concurrency == true
48
+ end
49
+ local_env.append_environment_value('Rails Env') { env }
50
+ local_env.append_gem_list do
51
+ ::Rails.configuration.gems.map do | gem |
52
+ version = (gem.respond_to?(:version) && gem.version) ||
53
+ (gem.specification.respond_to?(:version) && gem.specification.version)
54
+ gem.name + (version ? "(#{version})" : "")
55
+ end
56
+ end
57
+ local_env.append_plugin_list { ::Rails.configuration.plugins }
58
+ end
59
+
60
+ end
@@ -0,0 +1,36 @@
1
+ # A control used when no framework is detected.
2
+ # Looks for a newrelic.yml file in several locations
3
+ # including ./, ./config, $HOME/.newrelic and $HOME/.
4
+ # It loads the settings from the newrelic.yml section
5
+ # based on the value of RUBY_ENV or RAILS_ENV.
6
+ class NewRelic::Control::Frameworks::Ruby < NewRelic::Control
7
+
8
+ def env
9
+ @env ||= ENV['RUBY_ENV'] || ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
10
+ end
11
+ def root
12
+ @root ||= ENV['APP_ROOT'] || Dir['.']
13
+ end
14
+ # Check a sequence of file locations for newrelic.yml
15
+ def config_file
16
+ files = []
17
+ files << File.join(root,"config","newrelic.yml")
18
+ files << File.join(root,"newrelic.yml")
19
+ if ENV["HOME"]
20
+ files << File.join(ENV["HOME"], ".newrelic", "newrelic.yml")
21
+ files << File.join(ENV["HOME"], "newrelic.yml")
22
+ end
23
+ files << File.expand_path(ENV["NRCONFIG"]) if ENV["NRCONFIG"]
24
+ files.each do | file |
25
+ return File.expand_path(file) if File.exists? file
26
+ end
27
+ return File.expand_path(files.first)
28
+ end
29
+ def to_stdout(msg)
30
+ STDOUT.puts msg
31
+ end
32
+
33
+ def init_config(options={})
34
+ end
35
+
36
+ end
@@ -0,0 +1,18 @@
1
+
2
+ require 'new_relic/control/frameworks/ruby'
3
+
4
+ class NewRelic::Control::Frameworks::Sinatra < NewRelic::Control::Frameworks::Ruby
5
+
6
+ def env
7
+ @env ||= ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development'
8
+ end
9
+
10
+ # This is the control used when starting up in the context of
11
+ # The New Relic Infrastructure Agent. We want to call this
12
+ # out specifically because in this context we are not monitoring
13
+ # the running process, but actually external things.
14
+ def init_config(options={})
15
+ super
16
+ end
17
+
18
+ end
@@ -0,0 +1,95 @@
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
+
36
+ def _delayed_instrumentation
37
+ Rails.configuration.after_initialize do
38
+ _install_instrumentation
39
+ end
40
+ rescue
41
+ _install_instrumentation
42
+ end
43
+
44
+ def install_instrumentation
45
+ if defined?(Rails) && !Rails.initialized?
46
+ _delayed_instrumentation
47
+ else
48
+ _install_instrumentation
49
+ end
50
+ rescue NameError
51
+ # needed in the rails 3 case, where Rails.initialized? raises
52
+ # an error if rails has not been initialised. which is totally sane.
53
+ _delayed_instrumentation
54
+ end
55
+
56
+ def load_samplers
57
+ agent = NewRelic::Agent.instance
58
+ NewRelic::Agent::Sampler.sampler_classes.each do | subclass |
59
+ begin
60
+ log.debug "#{subclass.name} not supported on this platform." and next if not subclass.supported_on_this_platform?
61
+ sampler = subclass.new
62
+ if subclass.use_harvest_sampler?
63
+ agent.stats_engine.add_harvest_sampler sampler
64
+ log.debug "Registered #{subclass.name} for harvest time sampling"
65
+ else
66
+ agent.stats_engine.add_sampler sampler
67
+ log.debug "Registered #{subclass.name} for periodic sampling"
68
+ end
69
+ rescue NewRelic::Agent::Sampler::Unsupported => e
70
+ log.info "#{subclass} sampler not available: #{e}"
71
+ rescue => e
72
+ log.error "Error registering sampler: #{e}, #{e.backtrace.join("\n")}"
73
+ end
74
+ end
75
+ end
76
+
77
+ private
78
+
79
+ def _install_instrumentation
80
+ return if @instrumented
81
+
82
+ @instrumented = true
83
+
84
+ # Instrumentation for the key code points inside rails for monitoring by NewRelic.
85
+ # note this file is loaded only if the newrelic agent is enabled (through config/newrelic.yml)
86
+ instrumentation_path = File.join(File.dirname(__FILE__), '..', 'agent','instrumentation')
87
+ @instrumentation_files <<
88
+ File.join(instrumentation_path, '*.rb') <<
89
+ File.join(instrumentation_path, app.to_s, '*.rb')
90
+ @instrumentation_files.each { | pattern | load_instrumentation_files pattern }
91
+ log.debug "Finished instrumentation"
92
+ end
93
+ end
94
+ end
95
+ end