dolores_rpm 3.2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (257) hide show
  1. data/CHANGELOG +559 -0
  2. data/LICENSE +64 -0
  3. data/README.rdoc +179 -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 +118 -0
  8. data/cert/oldsite.pem +28 -0
  9. data/cert/site.pem +27 -0
  10. data/dolores_rpm-3.3.4.fork.gem +0 -0
  11. data/install.rb +9 -0
  12. data/lib/conditional_vendored_dependency_detection.rb +3 -0
  13. data/lib/conditional_vendored_metric_parser.rb +5 -0
  14. data/lib/new_relic/agent/agent.rb +1311 -0
  15. data/lib/new_relic/agent/beacon_configuration.rb +110 -0
  16. data/lib/new_relic/agent/browser_monitoring.rb +102 -0
  17. data/lib/new_relic/agent/busy_calculator.rb +99 -0
  18. data/lib/new_relic/agent/chained_call.rb +13 -0
  19. data/lib/new_relic/agent/database.rb +203 -0
  20. data/lib/new_relic/agent/error_collector.rb +251 -0
  21. data/lib/new_relic/agent/instrumentation/active_merchant.rb +27 -0
  22. data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +68 -0
  23. data/lib/new_relic/agent/instrumentation/authlogic.rb +19 -0
  24. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +424 -0
  25. data/lib/new_relic/agent/instrumentation/data_mapper.rb +57 -0
  26. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +52 -0
  27. data/lib/new_relic/agent/instrumentation/memcache.rb +80 -0
  28. data/lib/new_relic/agent/instrumentation/merb/controller.rb +41 -0
  29. data/lib/new_relic/agent/instrumentation/merb/errors.rb +29 -0
  30. data/lib/new_relic/agent/instrumentation/metric_frame/pop.rb +80 -0
  31. data/lib/new_relic/agent/instrumentation/metric_frame.rb +332 -0
  32. data/lib/new_relic/agent/instrumentation/net.rb +29 -0
  33. data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +36 -0
  34. data/lib/new_relic/agent/instrumentation/queue_time.rb +210 -0
  35. data/lib/new_relic/agent/instrumentation/rack.rb +98 -0
  36. data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +114 -0
  37. data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +42 -0
  38. data/lib/new_relic/agent/instrumentation/rails/active_record_instrumentation.rb +115 -0
  39. data/lib/new_relic/agent/instrumentation/rails/errors.rb +42 -0
  40. data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +118 -0
  41. data/lib/new_relic/agent/instrumentation/rails3/active_record_instrumentation.rb +122 -0
  42. data/lib/new_relic/agent/instrumentation/rails3/errors.rb +37 -0
  43. data/lib/new_relic/agent/instrumentation/sinatra.rb +58 -0
  44. data/lib/new_relic/agent/instrumentation/sunspot.rb +29 -0
  45. data/lib/new_relic/agent/instrumentation/unicorn_instrumentation.rb +21 -0
  46. data/lib/new_relic/agent/instrumentation.rb +9 -0
  47. data/lib/new_relic/agent/method_tracer.rb +528 -0
  48. data/lib/new_relic/agent/sampler.rb +50 -0
  49. data/lib/new_relic/agent/samplers/cpu_sampler.rb +58 -0
  50. data/lib/new_relic/agent/samplers/delayed_job_lock_sampler.rb +40 -0
  51. data/lib/new_relic/agent/samplers/memory_sampler.rb +144 -0
  52. data/lib/new_relic/agent/samplers/object_sampler.rb +26 -0
  53. data/lib/new_relic/agent/shim_agent.rb +29 -0
  54. data/lib/new_relic/agent/sql_sampler.rb +267 -0
  55. data/lib/new_relic/agent/stats_engine/metric_stats.rb +187 -0
  56. data/lib/new_relic/agent/stats_engine/samplers.rb +95 -0
  57. data/lib/new_relic/agent/stats_engine/transactions.rb +208 -0
  58. data/lib/new_relic/agent/stats_engine.rb +25 -0
  59. data/lib/new_relic/agent/transaction_sample_builder.rb +101 -0
  60. data/lib/new_relic/agent/transaction_sampler.rb +397 -0
  61. data/lib/new_relic/agent/worker_loop.rb +89 -0
  62. data/lib/new_relic/agent.rb +454 -0
  63. data/lib/new_relic/collection_helper.rb +75 -0
  64. data/lib/new_relic/command.rb +85 -0
  65. data/lib/new_relic/commands/deployments.rb +105 -0
  66. data/lib/new_relic/commands/install.rb +80 -0
  67. data/lib/new_relic/control/class_methods.rb +53 -0
  68. data/lib/new_relic/control/configuration.rb +202 -0
  69. data/lib/new_relic/control/frameworks/external.rb +16 -0
  70. data/lib/new_relic/control/frameworks/merb.rb +31 -0
  71. data/lib/new_relic/control/frameworks/rails.rb +164 -0
  72. data/lib/new_relic/control/frameworks/rails3.rb +75 -0
  73. data/lib/new_relic/control/frameworks/ruby.rb +42 -0
  74. data/lib/new_relic/control/frameworks/sinatra.rb +20 -0
  75. data/lib/new_relic/control/frameworks.rb +10 -0
  76. data/lib/new_relic/control/instance_methods.rb +179 -0
  77. data/lib/new_relic/control/instrumentation.rb +100 -0
  78. data/lib/new_relic/control/logging_methods.rb +143 -0
  79. data/lib/new_relic/control/profiling.rb +25 -0
  80. data/lib/new_relic/control/server_methods.rb +114 -0
  81. data/lib/new_relic/control.rb +46 -0
  82. data/lib/new_relic/data_serialization.rb +157 -0
  83. data/lib/new_relic/delayed_job_injection.rb +46 -0
  84. data/lib/new_relic/language_support.rb +69 -0
  85. data/lib/new_relic/local_environment.rb +414 -0
  86. data/lib/new_relic/merbtasks.rb +6 -0
  87. data/lib/new_relic/metric_data.rb +51 -0
  88. data/lib/new_relic/metric_spec.rb +75 -0
  89. data/lib/new_relic/metrics.rb +9 -0
  90. data/lib/new_relic/noticed_error.rb +24 -0
  91. data/lib/new_relic/rack/browser_monitoring.rb +68 -0
  92. data/lib/new_relic/rack/developer_mode.rb +268 -0
  93. data/lib/new_relic/recipes.rb +73 -0
  94. data/lib/new_relic/stats.rb +388 -0
  95. data/lib/new_relic/timer_lib.rb +27 -0
  96. data/lib/new_relic/transaction_analysis/segment_summary.rb +49 -0
  97. data/lib/new_relic/transaction_analysis.rb +77 -0
  98. data/lib/new_relic/transaction_sample/composite_segment.rb +27 -0
  99. data/lib/new_relic/transaction_sample/fake_segment.rb +9 -0
  100. data/lib/new_relic/transaction_sample/segment.rb +201 -0
  101. data/lib/new_relic/transaction_sample/summary_segment.rb +21 -0
  102. data/lib/new_relic/transaction_sample.rb +245 -0
  103. data/lib/new_relic/url_rule.rb +14 -0
  104. data/lib/new_relic/version.rb +55 -0
  105. data/lib/newrelic_rpm.rb +49 -0
  106. data/lib/tasks/all.rb +4 -0
  107. data/lib/tasks/install.rake +7 -0
  108. data/lib/tasks/tests.rake +19 -0
  109. data/newrelic.yml +265 -0
  110. data/recipes/newrelic.rb +6 -0
  111. data/test/active_record_fixtures.rb +77 -0
  112. data/test/config/newrelic.yml +48 -0
  113. data/test/config/test_control.rb +48 -0
  114. data/test/new_relic/agent/agent/connect_test.rb +410 -0
  115. data/test/new_relic/agent/agent/start_test.rb +255 -0
  116. data/test/new_relic/agent/agent/start_worker_thread_test.rb +153 -0
  117. data/test/new_relic/agent/agent_test.rb +139 -0
  118. data/test/new_relic/agent/agent_test_controller.rb +77 -0
  119. data/test/new_relic/agent/agent_test_controller_test.rb +363 -0
  120. data/test/new_relic/agent/apdex_from_server_test.rb +9 -0
  121. data/test/new_relic/agent/beacon_configuration_test.rb +108 -0
  122. data/test/new_relic/agent/browser_monitoring_test.rb +278 -0
  123. data/test/new_relic/agent/busy_calculator_test.rb +81 -0
  124. data/test/new_relic/agent/database_test.rb +162 -0
  125. data/test/new_relic/agent/error_collector/notice_error_test.rb +257 -0
  126. data/test/new_relic/agent/error_collector_test.rb +175 -0
  127. data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +538 -0
  128. data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +36 -0
  129. data/test/new_relic/agent/instrumentation/instrumentation_test.rb +11 -0
  130. data/test/new_relic/agent/instrumentation/metric_frame/pop_test.rb +172 -0
  131. data/test/new_relic/agent/instrumentation/metric_frame_test.rb +50 -0
  132. data/test/new_relic/agent/instrumentation/net_instrumentation_test.rb +84 -0
  133. data/test/new_relic/agent/instrumentation/queue_time_test.rb +387 -0
  134. data/test/new_relic/agent/instrumentation/rack_test.rb +35 -0
  135. data/test/new_relic/agent/instrumentation/task_instrumentation_test.rb +184 -0
  136. data/test/new_relic/agent/memcache_instrumentation_test.rb +143 -0
  137. data/test/new_relic/agent/method_tracer/class_methods/add_method_tracer_test.rb +164 -0
  138. data/test/new_relic/agent/method_tracer/instance_methods/trace_execution_scoped_test.rb +234 -0
  139. data/test/new_relic/agent/method_tracer_test.rb +386 -0
  140. data/test/new_relic/agent/mock_scope_listener.rb +23 -0
  141. data/test/new_relic/agent/rpm_agent_test.rb +149 -0
  142. data/test/new_relic/agent/sampler_test.rb +19 -0
  143. data/test/new_relic/agent/shim_agent_test.rb +20 -0
  144. data/test/new_relic/agent/sql_sampler_test.rb +160 -0
  145. data/test/new_relic/agent/stats_engine/metric_stats/harvest_test.rb +150 -0
  146. data/test/new_relic/agent/stats_engine/metric_stats_test.rb +82 -0
  147. data/test/new_relic/agent/stats_engine/samplers_test.rb +99 -0
  148. data/test/new_relic/agent/stats_engine_test.rb +185 -0
  149. data/test/new_relic/agent/transaction_sample_builder_test.rb +195 -0
  150. data/test/new_relic/agent/transaction_sampler_test.rb +955 -0
  151. data/test/new_relic/agent/worker_loop_test.rb +66 -0
  152. data/test/new_relic/agent_test.rb +175 -0
  153. data/test/new_relic/collection_helper_test.rb +149 -0
  154. data/test/new_relic/command/deployments_test.rb +68 -0
  155. data/test/new_relic/control/class_methods_test.rb +62 -0
  156. data/test/new_relic/control/configuration_test.rb +72 -0
  157. data/test/new_relic/control/logging_methods_test.rb +185 -0
  158. data/test/new_relic/control_test.rb +254 -0
  159. data/test/new_relic/data_serialization_test.rb +208 -0
  160. data/test/new_relic/delayed_job_injection_test.rb +16 -0
  161. data/test/new_relic/local_environment_test.rb +72 -0
  162. data/test/new_relic/metric_data_test.rb +125 -0
  163. data/test/new_relic/metric_spec_test.rb +95 -0
  164. data/test/new_relic/rack/all_test.rb +11 -0
  165. data/test/new_relic/rack/browser_monitoring_test.rb +84 -0
  166. data/test/new_relic/rack/developer_mode_helper_test.rb +141 -0
  167. data/test/new_relic/rack/developer_mode_test.rb +43 -0
  168. data/test/new_relic/stats_test.rb +426 -0
  169. data/test/new_relic/transaction_analysis/segment_summary_test.rb +91 -0
  170. data/test/new_relic/transaction_analysis_test.rb +121 -0
  171. data/test/new_relic/transaction_sample/composite_segment_test.rb +35 -0
  172. data/test/new_relic/transaction_sample/fake_segment_test.rb +17 -0
  173. data/test/new_relic/transaction_sample/segment_test.rb +389 -0
  174. data/test/new_relic/transaction_sample/summary_segment_test.rb +31 -0
  175. data/test/new_relic/transaction_sample_subtest_test.rb +56 -0
  176. data/test/new_relic/transaction_sample_test.rb +164 -0
  177. data/test/new_relic/version_number_test.rb +89 -0
  178. data/test/test_contexts.rb +29 -0
  179. data/test/test_helper.rb +154 -0
  180. data/ui/helpers/developer_mode_helper.rb +357 -0
  181. data/ui/helpers/google_pie_chart.rb +48 -0
  182. data/ui/views/layouts/newrelic_default.rhtml +47 -0
  183. data/ui/views/newrelic/_explain_plans.rhtml +27 -0
  184. data/ui/views/newrelic/_sample.rhtml +20 -0
  185. data/ui/views/newrelic/_segment.rhtml +28 -0
  186. data/ui/views/newrelic/_segment_limit_message.rhtml +1 -0
  187. data/ui/views/newrelic/_segment_row.rhtml +12 -0
  188. data/ui/views/newrelic/_show_sample_detail.rhtml +24 -0
  189. data/ui/views/newrelic/_show_sample_sql.rhtml +24 -0
  190. data/ui/views/newrelic/_show_sample_summary.rhtml +3 -0
  191. data/ui/views/newrelic/_sql_row.rhtml +16 -0
  192. data/ui/views/newrelic/_stack_trace.rhtml +15 -0
  193. data/ui/views/newrelic/_table.rhtml +12 -0
  194. data/ui/views/newrelic/explain_sql.rhtml +43 -0
  195. data/ui/views/newrelic/file/images/arrow-close.png +0 -0
  196. data/ui/views/newrelic/file/images/arrow-open.png +0 -0
  197. data/ui/views/newrelic/file/images/blue_bar.gif +0 -0
  198. data/ui/views/newrelic/file/images/file_icon.png +0 -0
  199. data/ui/views/newrelic/file/images/gray_bar.gif +0 -0
  200. data/ui/views/newrelic/file/images/new-relic-rpm-desktop.gif +0 -0
  201. data/ui/views/newrelic/file/images/new_relic_rpm_desktop.gif +0 -0
  202. data/ui/views/newrelic/file/images/textmate.png +0 -0
  203. data/ui/views/newrelic/file/javascript/jquery-1.4.2.js +6240 -0
  204. data/ui/views/newrelic/file/javascript/transaction_sample.js +120 -0
  205. data/ui/views/newrelic/file/stylesheets/style.css +490 -0
  206. data/ui/views/newrelic/index.rhtml +71 -0
  207. data/ui/views/newrelic/sample_not_found.rhtml +2 -0
  208. data/ui/views/newrelic/show_sample.rhtml +80 -0
  209. data/ui/views/newrelic/show_source.rhtml +3 -0
  210. data/ui/views/newrelic/threads.rhtml +53 -0
  211. data/vendor/gems/dependency_detection-0.0.1.build/LICENSE +5 -0
  212. data/vendor/gems/dependency_detection-0.0.1.build/lib/dependency_detection/version.rb +3 -0
  213. data/vendor/gems/dependency_detection-0.0.1.build/lib/dependency_detection.rb +62 -0
  214. data/vendor/gems/metric_parser-0.1.0.pre1/lib/metric_parser.rb +1 -0
  215. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/action_mailer.rb +14 -0
  216. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/active_merchant.rb +31 -0
  217. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/active_record.rb +33 -0
  218. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/apdex.rb +89 -0
  219. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/background_transaction.rb +7 -0
  220. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/client.rb +46 -0
  221. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/controller.rb +67 -0
  222. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/controller_cpu.rb +43 -0
  223. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/controller_ext.rb +17 -0
  224. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/database.rb +48 -0
  225. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/database_pool.rb +24 -0
  226. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/dot_net.rb +28 -0
  227. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/dot_net_parser.rb +17 -0
  228. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/errors.rb +11 -0
  229. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/external.rb +55 -0
  230. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/frontend.rb +40 -0
  231. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/gc.rb +20 -0
  232. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/hibernate_session.rb +7 -0
  233. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/java.rb +31 -0
  234. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/java_parser.rb +17 -0
  235. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/jsp.rb +34 -0
  236. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/jsp_tag.rb +7 -0
  237. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/mem_cache.rb +55 -0
  238. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/metric_parser.rb +122 -0
  239. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/orm.rb +27 -0
  240. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/other_transaction.rb +40 -0
  241. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/servlet.rb +7 -0
  242. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/servlet_context_listener.rb +7 -0
  243. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/servlet_filter.rb +7 -0
  244. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/solr.rb +27 -0
  245. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/solr_request_handler.rb +15 -0
  246. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/spring.rb +54 -0
  247. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/spring_controller.rb +6 -0
  248. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/spring_view.rb +6 -0
  249. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/struts_action.rb +20 -0
  250. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/struts_result.rb +20 -0
  251. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/version.rb +5 -0
  252. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/view.rb +70 -0
  253. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/web_frontend.rb +18 -0
  254. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/web_service.rb +14 -0
  255. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/web_transaction.rb +133 -0
  256. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser.rb +64 -0
  257. metadata +398 -0
@@ -0,0 +1,75 @@
1
+ require 'new_relic/control/frameworks/rails'
2
+ module NewRelic
3
+ class Control
4
+ module Frameworks
5
+ # Control subclass instantiated when Rails is detected. Contains
6
+ # Rails 3.0+ specific configuration, instrumentation, environment values,
7
+ # etc. Many methods are inherited from the
8
+ # NewRelic::Control::Frameworks::Rails class, where the two do
9
+ # not differ
10
+ class Rails3 < NewRelic::Control::Frameworks::Rails
11
+
12
+ def env
13
+ ::Rails.env.to_s
14
+ end
15
+
16
+ # Rails can return an empty string from this method, causing
17
+ # the agent not to start even when it is properly in a rails 3
18
+ # application, so we test the value to make sure it actually
19
+ # has contents, and bail to the parent class if it is empty.
20
+ def root
21
+ value = ::Rails.root.to_s
22
+ if value.empty?
23
+ super
24
+ else
25
+ value
26
+ end
27
+ end
28
+
29
+ def logger
30
+ ::Rails.logger
31
+ end
32
+
33
+
34
+ def log!(msg, level=:info)
35
+ if should_log?
36
+ logger.send(level, msg)
37
+ else
38
+ super
39
+ end
40
+ rescue Exception => e
41
+ super
42
+ end
43
+
44
+ def to_stdout(msg)
45
+ logger.info(msg)
46
+ rescue
47
+ super
48
+ end
49
+
50
+ def vendor_root
51
+ @vendor_root ||= File.join(root,'vendor','rails')
52
+ end
53
+
54
+ def version
55
+ @rails_version ||= NewRelic::VersionNumber.new(::Rails::VERSION::STRING)
56
+ end
57
+
58
+ protected
59
+
60
+ # Collect the Rails::Info into an associative array as well as the list of plugins
61
+ def append_environment_info
62
+ local_env.append_environment_value('Rails version'){ version }
63
+ local_env.append_environment_value('Rails threadsafe') do
64
+ true == ::Rails.configuration.action_controller.allow_concurrency
65
+ end
66
+ local_env.append_environment_value('Rails Env') { env }
67
+ local_env.append_gem_list do
68
+ bundler_gem_list
69
+ end
70
+ local_env.append_plugin_list { ::Rails.configuration.plugins.to_a }
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,42 @@
1
+ module NewRelic
2
+ class Control
3
+ module Frameworks
4
+ # A control used when no framework is detected - the default.
5
+ # Looks for a newrelic.yml file in several locations including
6
+ # ./, ./config, $HOME/.newrelic and $HOME/. It loads the
7
+ # settings from the newrelic.yml section based on the value of
8
+ # RUBY_ENV or RAILS_ENV.
9
+ class Ruby < NewRelic::Control
10
+
11
+ def env
12
+ @env ||= ENV['RUBY_ENV'] || ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
13
+ end
14
+ def root
15
+ @root ||= ENV['APP_ROOT'] || Dir['.']
16
+ end
17
+ # Check a sequence of file locations for newrelic.yml
18
+ def config_file
19
+ files = []
20
+ files << File.join(root,"config","newrelic.yml")
21
+ files << File.join(root,"newrelic.yml")
22
+ if ENV["HOME"]
23
+ files << File.join(ENV["HOME"], ".newrelic", "newrelic.yml")
24
+ files << File.join(ENV["HOME"], "newrelic.yml")
25
+ end
26
+ files << File.expand_path(ENV["NRCONFIG"]) if ENV["NRCONFIG"]
27
+ files.each do | file |
28
+ return File.expand_path(file) if File.exists? file
29
+ end
30
+ return File.expand_path(files.first)
31
+ end
32
+ def to_stdout(msg)
33
+ STDOUT.puts msg
34
+ end
35
+
36
+ def init_config(options={})
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,20 @@
1
+
2
+ require 'new_relic/control/frameworks/ruby'
3
+ module NewRelic
4
+ class Control
5
+ module Frameworks
6
+ # Contains basic control logic for Sinatra
7
+ class Sinatra < NewRelic::Control::Frameworks::Ruby
8
+
9
+ def env
10
+ @env ||= ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development'
11
+ end
12
+
13
+ def init_config(options={})
14
+ super
15
+ end
16
+
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,10 @@
1
+ module NewRelic
2
+ class Control
3
+ # Contains subclasses of NewRelic::Control that are used when
4
+ # starting the agent within an application. Framework-specific
5
+ # logic should be included here, as documented within the Control
6
+ # abstract parent class
7
+ module Frameworks
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,179 @@
1
+ require 'new_relic/language_support'
2
+
3
+ module NewRelic
4
+ class Control
5
+ include NewRelic::LanguageSupport::Control
6
+
7
+ # Contains methods that relate to the runtime usage of the control
8
+ # object. Note that these are subject to override in the
9
+ # NewRelic::Control::Framework classes that are actually instantiated
10
+ module InstanceMethods
11
+ # The env is the setting used to identify which section of the newrelic.yml
12
+ # to load. This defaults to a framework specific value, such as ENV['RAILS_ENV']
13
+ # but can be overridden as long as you set it before calling #init_plugin
14
+ attr_writer :env
15
+
16
+ # The local environment contains all the information we report
17
+ # to the server about what kind of application this is, what
18
+ # gems and plugins it uses, and many other kinds of
19
+ # machine-dependent information useful in debugging
20
+ attr_reader :local_env
21
+
22
+
23
+ # Initialize the plugin/gem and start the agent. This does the
24
+ # necessary configuration based on the framework environment and
25
+ # determines whether or not to start the agent. If the agent is
26
+ # not going to be started then it loads the agent shim which has
27
+ # stubs for all the external api.
28
+ #
29
+ # This may be invoked multiple times, as long as you don't attempt
30
+ # to uninstall the agent after it has been started.
31
+ #
32
+ # If the plugin is initialized and it determines that the agent is
33
+ # not enabled, it will skip starting it and install the shim. But
34
+ # if you later call this with <tt>:agent_enabled => true</tt>,
35
+ # then it will install the real agent and start it.
36
+ #
37
+ # What determines whether the agent is launched is the result of
38
+ # calling agent_enabled? This will indicate whether the
39
+ # instrumentation should/will be installed. If we're in a mode
40
+ # where tracers are not installed then we should not start the
41
+ # agent.
42
+ #
43
+ # Subclasses are not allowed to override, but must implement
44
+ # init_config({}) which is called one or more times.
45
+ #
46
+ def init_plugin(options={})
47
+ options['app_name'] = ENV['NEWRELIC_APP_NAME'] if ENV['NEWRELIC_APP_NAME']
48
+ options['app_name'] ||= ENV['NEW_RELIC_APP_NAME'] if ENV['NEW_RELIC_APP_NAME']
49
+
50
+ # Merge the stringified options into the config as overrides:
51
+ logger_override = options.delete(:log)
52
+ environment_name = options.delete(:env) and self.env = environment_name
53
+ dispatcher = options.delete(:dispatcher) and @local_env.dispatcher = dispatcher
54
+ dispatcher_instance_id = options.delete(:dispatcher_instance_id) and @local_env.dispatcher_instance_id = dispatcher_instance_id
55
+
56
+
57
+ # Clear out the settings, if they've already been loaded. It may be that
58
+ # between calling init_plugin the first time and the second time, the env
59
+ # has been overridden
60
+ @settings = nil
61
+ settings
62
+ merge_options(options)
63
+ if logger_override
64
+ @log = logger_override
65
+ # Try to grab the log filename
66
+ @log_file = @log.instance_eval { @logdev.filename rescue nil }
67
+ end
68
+ # An artifact of earlier implementation, we put both #add_method_tracer and #trace_execution
69
+ # methods in the module methods.
70
+ Module.send :include, NewRelic::Agent::MethodTracer::ClassMethods
71
+ Module.send :include, NewRelic::Agent::MethodTracer::InstanceMethods
72
+ init_config(options)
73
+ NewRelic::Agent.agent = NewRelic::Agent::Agent.instance
74
+ if agent_enabled? && !NewRelic::Agent.instance.started?
75
+ setup_log unless logger_override
76
+ start_agent
77
+ install_instrumentation
78
+ load_samplers unless self['disable_samplers']
79
+ local_env.gather_environment_info
80
+ append_environment_info
81
+ elsif !agent_enabled?
82
+ install_shim
83
+ end
84
+ end
85
+
86
+ # Install the real agent into the Agent module, and issue the start command.
87
+ def start_agent
88
+ NewRelic::Agent.agent.start
89
+ end
90
+
91
+ # True if dev mode or monitor mode are enabled, and we are running
92
+ # inside a valid dispatcher like mongrel or passenger. Can be overridden
93
+ # by NEWRELIC_ENABLE env variable, monitor_daemons config option when true, or
94
+ # agent_enabled config option when true or false.
95
+ def agent_enabled?
96
+ return false if !developer_mode? && !monitor_mode?
97
+ return self['agent_enabled'].to_s =~ /true|on|yes/i if !self['agent_enabled'].nil? && self['agent_enabled'] != 'auto'
98
+ return false if ENV['NEWRELIC_ENABLE'].to_s =~ /false|off|no/i
99
+ return true if self['monitor_daemons'].to_s =~ /true|on|yes/i
100
+ return true if ENV['NEWRELIC_ENABLE'].to_s =~ /true|on|yes/i
101
+ # When in 'auto' mode the agent is enabled if there is a known
102
+ # dispatcher running
103
+ return true if @local_env.dispatcher != nil
104
+ end
105
+
106
+ # Asks the LocalEnvironment instance which framework should be loaded
107
+ def app
108
+ @local_env.framework
109
+ end
110
+ alias framework app
111
+
112
+ def to_s #:nodoc:
113
+ "Control[#{self.app}]"
114
+ end
115
+
116
+ protected
117
+
118
+ # Append framework specific environment information for uploading to
119
+ # the server for change detection. Override in subclasses
120
+ def append_environment_info; end
121
+
122
+ # Asks bundler to tell us which gemspecs are loaded in the
123
+ # current process
124
+ def bundler_gem_list
125
+ if defined?(Bundler) && Bundler.instance_eval do @load end
126
+ Bundler.load.specs.map do | spec |
127
+ version = (spec.respond_to?(:version) && spec.version)
128
+ spec.name + (version ? "(#{version})" : "")
129
+ end
130
+ else
131
+ []
132
+ end
133
+ end
134
+
135
+ # path to the config file, defaults to the "#{root}/config/newrelic.yml"
136
+ def config_file
137
+ File.expand_path(File.join(root,"config","newrelic.yml"))
138
+ end
139
+
140
+ # initializes the control instance with a local environment and
141
+ # an optional config file override. Checks for the config file
142
+ # and loads it.
143
+ def initialize local_env, config_file_override=nil
144
+ @local_env = local_env
145
+ @instrumentation_files = []
146
+ newrelic_file = config_file_override || config_file
147
+ # Next two are for populating the newrelic.yml via erb binding, necessary
148
+ # when using the default newrelic.yml file
149
+ generated_for_user = ''
150
+ license_key=''
151
+ if !File.exists?(newrelic_file)
152
+ puts "Cannot find or read #{newrelic_file}"
153
+ @yaml = {}
154
+ else
155
+ @yaml = load_newrelic_yml(newrelic_file, binding)
156
+ end
157
+ rescue ScriptError, StandardError => e
158
+ puts e
159
+ puts e.backtrace.join("\n")
160
+ raise "Error reading newrelic.yml file: #{e}"
161
+ end
162
+
163
+ def load_newrelic_yml(path, binding)
164
+ YAML.load(ERB.new(File.read(path)).result(binding))
165
+ end
166
+
167
+ def root
168
+ '.'
169
+ end
170
+
171
+ # Delegates to the class method newrelic_root, implemented by
172
+ # each subclass
173
+ def newrelic_root
174
+ self.class.newrelic_root
175
+ end
176
+ end
177
+ include InstanceMethods
178
+ end
179
+ end
@@ -0,0 +1,100 @@
1
+ module NewRelic
2
+ class Control
3
+ # Contains methods that relate to adding and executing files that
4
+ # contain instrumentation for the Ruby Agent
5
+ module Instrumentation
6
+
7
+ # Adds a list of files in Dir.glob format
8
+ # (e.g. '/app/foo/**/*_instrumentation.rb')
9
+ # This requires the files within a rescue block, so that any
10
+ # errors within instrumentation files do not affect the overall
11
+ # agent or application in which it runs.
12
+ #
13
+ # Logs at debug level for each file loaded, and logs errors in
14
+ # file loading at error level
15
+ def load_instrumentation_files pattern
16
+ Dir.glob(pattern) do |file|
17
+ begin
18
+ log.debug "Processing instrumentation file '#{file}'"
19
+ require file.to_s
20
+ rescue Exception => e
21
+ log.error "Error loading instrumentation file '#{file}': #{e}"
22
+ log.debug e.backtrace.join("\n")
23
+ end
24
+ end
25
+ end
26
+
27
+ # Install stubs to the proper location so the app code will not fail
28
+ # if the agent is not running.
29
+ def install_shim
30
+ # Once we install instrumentation, you can't undo that by installing the shim.
31
+ raise "Cannot install the Agent shim after instrumentation has already been installed!" if @instrumented
32
+ NewRelic::Agent.agent = NewRelic::Agent::ShimAgent.instance
33
+ end
34
+
35
+ # Add instrumentation. Don't call this directly. Use NewRelic::Agent#add_instrumentation.
36
+ # This will load the file synchronously if we've already loaded the default
37
+ # instrumentation, otherwise instrumentation files specified
38
+ # here will be deferred until all instrumentation is run
39
+ #
40
+ # This happens after the agent has loaded and all dependencies
41
+ # are ready to be instrumented
42
+ def add_instrumentation pattern
43
+ if @instrumented
44
+ load_instrumentation_files pattern
45
+ else
46
+ @instrumentation_files << pattern
47
+ end
48
+ end
49
+
50
+ # Signals the agent that it's time to actually load the
51
+ # instrumentation files. May be overridden by subclasses
52
+ def install_instrumentation
53
+ _install_instrumentation
54
+ end
55
+
56
+ # adds samplers to the stats engine so that they run every
57
+ # minute. This is dynamically recognized by any class that
58
+ # subclasses NewRelic::Agent::Sampler
59
+ def load_samplers
60
+ agent = NewRelic::Agent.instance
61
+ NewRelic::Agent::Sampler.sampler_classes.each do | subclass |
62
+ begin
63
+ log.debug "#{subclass.name} not supported on this platform." and next if not subclass.supported_on_this_platform?
64
+ sampler = subclass.new
65
+ if subclass.use_harvest_sampler?
66
+ agent.stats_engine.add_harvest_sampler sampler
67
+ log.debug "Registered #{subclass.name} for harvest time sampling"
68
+ else
69
+ agent.stats_engine.add_sampler sampler
70
+ log.debug "Registered #{subclass.name} for periodic sampling"
71
+ end
72
+ rescue NewRelic::Agent::Sampler::Unsupported => e
73
+ log.info "#{subclass} sampler not available: #{e}"
74
+ rescue => e
75
+ log.error "Error registering sampler: #{e}, #{e.backtrace.join("\n")}"
76
+ end
77
+ end
78
+ end
79
+
80
+ private
81
+
82
+ def _install_instrumentation
83
+ return if @instrumented
84
+
85
+ @instrumented = true
86
+
87
+ # Instrumentation for the key code points inside rails for monitoring by NewRelic.
88
+ # note this file is loaded only if the newrelic agent is enabled (through config/newrelic.yml)
89
+ instrumentation_path = File.expand_path(File.join(File.dirname(__FILE__), '..', 'agent','instrumentation'))
90
+ @instrumentation_files <<
91
+ File.join(instrumentation_path, '*.rb') <<
92
+ File.join(instrumentation_path, app.to_s, '*.rb')
93
+ @instrumentation_files.each { | pattern | load_instrumentation_files pattern }
94
+ DependencyDetection.detect!
95
+ log.debug "Finished instrumentation"
96
+ end
97
+ end
98
+ include Instrumentation
99
+ end
100
+ end
@@ -0,0 +1,143 @@
1
+
2
+ module NewRelic
3
+ class Control
4
+ # Contains methods that relate to locating, creating, and writing
5
+ # to the log file and/or standard out
6
+ module LoggingMethods
7
+
8
+ attr_accessor :log_file
9
+
10
+ # returns either the log set up with setup_log or else a new
11
+ # logger pointing to standard out, if we're trying to log before
12
+ # a log exists
13
+ def log
14
+ if !@log
15
+ l = Logger.new(STDOUT)
16
+ l.level = Logger::INFO
17
+ return l
18
+ end
19
+ @log
20
+ end
21
+
22
+ # send the given message to STDOUT so that it shows
23
+ # up in the console. This should be used for important informational messages at boot.
24
+ # The to_stdout may be implemented differently by different config subclasses.
25
+ # This will NOT print anything if tracers are not enabled
26
+ def log!(msg, level=:info)
27
+ to_stdout msg
28
+ return unless should_log?
29
+ log.send level, msg if @log
30
+ end
31
+
32
+ # true if the agent has settings, and the agent is enabled,
33
+ # otherwise false
34
+ def should_log?
35
+ @settings && agent_enabled?
36
+ end
37
+
38
+ # set the log level as specified in the config file
39
+ #
40
+ # Possible values are from the Logger class: debug, info, warn,
41
+ #error, and fatal
42
+ # Defaults to info
43
+ def set_log_level!(logger)
44
+ case fetch("log_level","info").downcase
45
+ when "debug" then logger.level = Logger::DEBUG
46
+ when "info" then logger.level = Logger::INFO
47
+ when "warn" then logger.level = Logger::WARN
48
+ when "error" then logger.level = Logger::ERROR
49
+ when "fatal" then logger.level = Logger::FATAL
50
+ else logger.level = Logger::INFO
51
+ end
52
+ logger
53
+ end
54
+
55
+ # patches the logger's format_message method to change the format just for our logger
56
+ def set_log_format!(logger)
57
+ def logger.format_message(severity, timestamp, progname, msg)
58
+ prefix = @logdev.dev == STDOUT ? '** [NewRelic]' : ''
59
+ prefix + "[#{timestamp.strftime("%m/%d/%y %H:%M:%S %z")} #{Socket.gethostname} (#{$$})] #{severity} : #{msg}\n"
60
+ end
61
+ logger
62
+ end
63
+
64
+ # Create the logger using the configuration variables
65
+ #
66
+ # Control subclasses may override this, but it can be called multiple times.
67
+ def setup_log
68
+ if log_to_stdout?
69
+ @log = Logger.new(STDOUT)
70
+ else
71
+ @log_file = "#{log_path}/#{log_file_name}"
72
+ @log = Logger.new(@log_file) rescue nil
73
+ @log ||= Logger.new(STDOUT) # failsafe to STDOUT
74
+ end
75
+
76
+ if @log
77
+ set_log_format!(@log)
78
+ set_log_level!(@log)
79
+ end
80
+ # note this is not the variable from above - it is the `log`
81
+ # method, which returns a default logger if none is setup
82
+ # above
83
+ log
84
+ end
85
+
86
+ # simply puts a message to standard out, prepended with the
87
+ # '** [NewRelic]' sigil to make sure people know where the message
88
+ # comes from. This should be used sparingly
89
+ def to_stdout(msg)
90
+ STDOUT.puts "** [NewRelic] " + msg
91
+ end
92
+
93
+ # Sets up and caches the log path, attempting to create it if it
94
+ # does not exist. If it does not succeed, it prints an
95
+ # error and returns nil.
96
+ # This comes from the configuration variable 'log_file_path' in the configuration file.
97
+ def log_path
98
+ return @log_path if @log_path
99
+ if log_to_stdout?
100
+ @log_path = nil
101
+ else
102
+ if ENV['NEW_RELIC_LOG']
103
+ log_path_setting = File.dirname(ENV['NEW_RELIC_LOG'])
104
+ else
105
+ log_path_setting = fetch('log_file_path', 'log')
106
+ end
107
+ @log_path = find_or_create_file_path(log_path_setting)
108
+ log!("Error creating log directory #{log_path_setting}, using standard out for logging.", :warn) unless @log_path
109
+ end
110
+ @log_path
111
+ end
112
+
113
+ def find_or_create_file_path(path_setting)
114
+ for abs_path in [ File.expand_path(path_setting),
115
+ File.expand_path(File.join(root, path_setting)) ] do
116
+ if File.directory?(abs_path) || (Dir.mkdir(abs_path) rescue nil)
117
+ return abs_path[%r{^(.*?)/?$}]
118
+ end
119
+ end
120
+ nil
121
+ end
122
+
123
+ def log_to_stdout?
124
+ return true if @stdout
125
+ destination = ENV['NEW_RELIC_LOG'] || fetch('log_file_path', 'log')
126
+ if destination.upcase == 'STDOUT'
127
+ @stdout = true
128
+ end
129
+ end
130
+
131
+ # Retrieves the log file's name from the config file option
132
+ #'log_file_name', defaulting to 'newrelic_agent.log'
133
+ def log_file_name
134
+ if ENV['NEW_RELIC_LOG']
135
+ File.basename(ENV['NEW_RELIC_LOG'])
136
+ else
137
+ fetch('log_file_name', 'newrelic_agent.log')
138
+ end
139
+ end
140
+ end
141
+ include LoggingMethods
142
+ end
143
+ end
@@ -0,0 +1,25 @@
1
+ module NewRelic
2
+ class Control
3
+ module Profiling
4
+
5
+ # A flag used in dev mode to indicate if profiling is available
6
+ def profiling?
7
+ @profiling
8
+ end
9
+
10
+ def profiling_available?
11
+ @profiling_available ||=
12
+ begin
13
+ require 'ruby-prof'
14
+ true
15
+ rescue LoadError; end
16
+ end
17
+ # Set the flag for capturing profiles in dev mode. If RubyProf is not
18
+ # loaded a true value is ignored.
19
+ def profiling=(val)
20
+ @profiling = profiling_available? && val && defined?(RubyProf)
21
+ end
22
+ end
23
+ include Profiling
24
+ end
25
+ end