wd_newrelic_rpm 3.3.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (264) hide show
  1. data/CHANGELOG +591 -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/install.rb +9 -0
  11. data/lib/conditional_vendored_dependency_detection.rb +3 -0
  12. data/lib/conditional_vendored_metric_parser.rb +5 -0
  13. data/lib/new_relic/agent.rb +467 -0
  14. data/lib/new_relic/agent/agent.rb +1325 -0
  15. data/lib/new_relic/agent/beacon_configuration.rb +121 -0
  16. data/lib/new_relic/agent/browser_monitoring.rb +142 -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 +223 -0
  20. data/lib/new_relic/agent/error_collector.rb +251 -0
  21. data/lib/new_relic/agent/instrumentation.rb +9 -0
  22. data/lib/new_relic/agent/instrumentation/active_merchant.rb +29 -0
  23. data/lib/new_relic/agent/instrumentation/active_record.rb +137 -0
  24. data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +68 -0
  25. data/lib/new_relic/agent/instrumentation/authlogic.rb +19 -0
  26. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +443 -0
  27. data/lib/new_relic/agent/instrumentation/data_mapper.rb +238 -0
  28. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +52 -0
  29. data/lib/new_relic/agent/instrumentation/memcache.rb +80 -0
  30. data/lib/new_relic/agent/instrumentation/merb/controller.rb +41 -0
  31. data/lib/new_relic/agent/instrumentation/merb/errors.rb +29 -0
  32. data/lib/new_relic/agent/instrumentation/metric_frame.rb +353 -0
  33. data/lib/new_relic/agent/instrumentation/metric_frame/pop.rb +80 -0
  34. data/lib/new_relic/agent/instrumentation/net.rb +29 -0
  35. data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +37 -0
  36. data/lib/new_relic/agent/instrumentation/queue_time.rb +210 -0
  37. data/lib/new_relic/agent/instrumentation/rack.rb +98 -0
  38. data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +114 -0
  39. data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +42 -0
  40. data/lib/new_relic/agent/instrumentation/rails/errors.rb +42 -0
  41. data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +180 -0
  42. data/lib/new_relic/agent/instrumentation/rails3/errors.rb +37 -0
  43. data/lib/new_relic/agent/instrumentation/sinatra.rb +78 -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/method_tracer.rb +528 -0
  47. data/lib/new_relic/agent/sampler.rb +50 -0
  48. data/lib/new_relic/agent/samplers/cpu_sampler.rb +58 -0
  49. data/lib/new_relic/agent/samplers/delayed_job_lock_sampler.rb +40 -0
  50. data/lib/new_relic/agent/samplers/memory_sampler.rb +143 -0
  51. data/lib/new_relic/agent/samplers/object_sampler.rb +26 -0
  52. data/lib/new_relic/agent/shim_agent.rb +29 -0
  53. data/lib/new_relic/agent/sql_sampler.rb +286 -0
  54. data/lib/new_relic/agent/stats_engine.rb +26 -0
  55. data/lib/new_relic/agent/stats_engine/gc_profiler.rb +123 -0
  56. data/lib/new_relic/agent/stats_engine/metric_stats.rb +187 -0
  57. data/lib/new_relic/agent/stats_engine/samplers.rb +95 -0
  58. data/lib/new_relic/agent/stats_engine/transactions.rb +125 -0
  59. data/lib/new_relic/agent/transaction_info.rb +74 -0
  60. data/lib/new_relic/agent/transaction_sample_builder.rb +116 -0
  61. data/lib/new_relic/agent/transaction_sampler.rb +468 -0
  62. data/lib/new_relic/agent/worker_loop.rb +89 -0
  63. data/lib/new_relic/collection_helper.rb +77 -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.rb +46 -0
  68. data/lib/new_relic/control/class_methods.rb +53 -0
  69. data/lib/new_relic/control/configuration.rb +206 -0
  70. data/lib/new_relic/control/frameworks.rb +10 -0
  71. data/lib/new_relic/control/frameworks/external.rb +16 -0
  72. data/lib/new_relic/control/frameworks/merb.rb +31 -0
  73. data/lib/new_relic/control/frameworks/rails.rb +164 -0
  74. data/lib/new_relic/control/frameworks/rails3.rb +75 -0
  75. data/lib/new_relic/control/frameworks/ruby.rb +42 -0
  76. data/lib/new_relic/control/frameworks/sinatra.rb +20 -0
  77. data/lib/new_relic/control/instance_methods.rb +179 -0
  78. data/lib/new_relic/control/instrumentation.rb +100 -0
  79. data/lib/new_relic/control/logging_methods.rb +143 -0
  80. data/lib/new_relic/control/profiling.rb +25 -0
  81. data/lib/new_relic/control/server_methods.rb +114 -0
  82. data/lib/new_relic/data_serialization.rb +151 -0
  83. data/lib/new_relic/delayed_job_injection.rb +51 -0
  84. data/lib/new_relic/language_support.rb +73 -0
  85. data/lib/new_relic/local_environment.rb +428 -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 +76 -0
  89. data/lib/new_relic/metrics.rb +9 -0
  90. data/lib/new_relic/noticed_error.rb +29 -0
  91. data/lib/new_relic/rack/browser_monitoring.rb +76 -0
  92. data/lib/new_relic/rack/developer_mode.rb +268 -0
  93. data/lib/new_relic/recipes.rb +77 -0
  94. data/lib/new_relic/stats.rb +335 -0
  95. data/lib/new_relic/timer_lib.rb +27 -0
  96. data/lib/new_relic/transaction_analysis.rb +77 -0
  97. data/lib/new_relic/transaction_analysis/segment_summary.rb +49 -0
  98. data/lib/new_relic/transaction_sample.rb +261 -0
  99. data/lib/new_relic/transaction_sample/composite_segment.rb +27 -0
  100. data/lib/new_relic/transaction_sample/fake_segment.rb +9 -0
  101. data/lib/new_relic/transaction_sample/segment.rb +203 -0
  102. data/lib/new_relic/transaction_sample/summary_segment.rb +21 -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/newrelic_rpm.gemspec +312 -0
  111. data/recipes/newrelic.rb +6 -0
  112. data/test/active_record_fixtures.rb +77 -0
  113. data/test/config/newrelic.yml +48 -0
  114. data/test/config/test_control.rb +48 -0
  115. data/test/fixtures/proc_cpuinfo.txt +575 -0
  116. data/test/new_relic/agent/agent/connect_test.rb +403 -0
  117. data/test/new_relic/agent/agent/start_test.rb +255 -0
  118. data/test/new_relic/agent/agent/start_worker_thread_test.rb +153 -0
  119. data/test/new_relic/agent/agent_test.rb +140 -0
  120. data/test/new_relic/agent/agent_test_controller.rb +77 -0
  121. data/test/new_relic/agent/agent_test_controller_test.rb +382 -0
  122. data/test/new_relic/agent/apdex_from_server_test.rb +9 -0
  123. data/test/new_relic/agent/beacon_configuration_test.rb +111 -0
  124. data/test/new_relic/agent/browser_monitoring_test.rb +323 -0
  125. data/test/new_relic/agent/busy_calculator_test.rb +81 -0
  126. data/test/new_relic/agent/database_test.rb +149 -0
  127. data/test/new_relic/agent/error_collector/notice_error_test.rb +257 -0
  128. data/test/new_relic/agent/error_collector_test.rb +192 -0
  129. data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +576 -0
  130. data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +34 -0
  131. data/test/new_relic/agent/instrumentation/instrumentation_test.rb +11 -0
  132. data/test/new_relic/agent/instrumentation/metric_frame/pop_test.rb +171 -0
  133. data/test/new_relic/agent/instrumentation/metric_frame_test.rb +50 -0
  134. data/test/new_relic/agent/instrumentation/net_instrumentation_test.rb +84 -0
  135. data/test/new_relic/agent/instrumentation/queue_time_test.rb +382 -0
  136. data/test/new_relic/agent/instrumentation/rack_test.rb +35 -0
  137. data/test/new_relic/agent/instrumentation/task_instrumentation_test.rb +184 -0
  138. data/test/new_relic/agent/memcache_instrumentation_test.rb +143 -0
  139. data/test/new_relic/agent/method_tracer/class_methods/add_method_tracer_test.rb +164 -0
  140. data/test/new_relic/agent/method_tracer/instance_methods/trace_execution_scoped_test.rb +234 -0
  141. data/test/new_relic/agent/method_tracer_test.rb +386 -0
  142. data/test/new_relic/agent/mock_scope_listener.rb +23 -0
  143. data/test/new_relic/agent/rpm_agent_test.rb +149 -0
  144. data/test/new_relic/agent/sampler_test.rb +19 -0
  145. data/test/new_relic/agent/shim_agent_test.rb +20 -0
  146. data/test/new_relic/agent/sql_sampler_test.rb +192 -0
  147. data/test/new_relic/agent/stats_engine/metric_stats/harvest_test.rb +150 -0
  148. data/test/new_relic/agent/stats_engine/metric_stats_test.rb +82 -0
  149. data/test/new_relic/agent/stats_engine/samplers_test.rb +99 -0
  150. data/test/new_relic/agent/stats_engine_test.rb +220 -0
  151. data/test/new_relic/agent/transaction_info_test.rb +13 -0
  152. data/test/new_relic/agent/transaction_sample_builder_test.rb +219 -0
  153. data/test/new_relic/agent/transaction_sampler_test.rb +967 -0
  154. data/test/new_relic/agent/worker_loop_test.rb +66 -0
  155. data/test/new_relic/agent_test.rb +187 -0
  156. data/test/new_relic/collection_helper_test.rb +149 -0
  157. data/test/new_relic/command/deployments_test.rb +68 -0
  158. data/test/new_relic/control/class_methods_test.rb +62 -0
  159. data/test/new_relic/control/configuration_test.rb +84 -0
  160. data/test/new_relic/control/logging_methods_test.rb +185 -0
  161. data/test/new_relic/control_test.rb +256 -0
  162. data/test/new_relic/data_serialization_test.rb +208 -0
  163. data/test/new_relic/delayed_job_injection_test.rb +16 -0
  164. data/test/new_relic/local_environment_test.rb +85 -0
  165. data/test/new_relic/metric_data_test.rb +125 -0
  166. data/test/new_relic/metric_parser/metric_parser_test.rb +11 -0
  167. data/test/new_relic/metric_spec_test.rb +95 -0
  168. data/test/new_relic/rack/all_test.rb +11 -0
  169. data/test/new_relic/rack/browser_monitoring_test.rb +142 -0
  170. data/test/new_relic/rack/developer_mode_helper_test.rb +141 -0
  171. data/test/new_relic/rack/developer_mode_test.rb +74 -0
  172. data/test/new_relic/stats_test.rb +411 -0
  173. data/test/new_relic/transaction_analysis/segment_summary_test.rb +91 -0
  174. data/test/new_relic/transaction_analysis_test.rb +121 -0
  175. data/test/new_relic/transaction_sample/composite_segment_test.rb +35 -0
  176. data/test/new_relic/transaction_sample/fake_segment_test.rb +17 -0
  177. data/test/new_relic/transaction_sample/segment_test.rb +389 -0
  178. data/test/new_relic/transaction_sample/summary_segment_test.rb +31 -0
  179. data/test/new_relic/transaction_sample_subtest_test.rb +56 -0
  180. data/test/new_relic/transaction_sample_test.rb +177 -0
  181. data/test/new_relic/version_number_test.rb +89 -0
  182. data/test/script/build_test_gem.sh +51 -0
  183. data/test/script/ci.sh +94 -0
  184. data/test/script/ci_bench.sh +52 -0
  185. data/test/test_contexts.rb +29 -0
  186. data/test/test_helper.rb +155 -0
  187. data/ui/helpers/developer_mode_helper.rb +357 -0
  188. data/ui/helpers/google_pie_chart.rb +48 -0
  189. data/ui/views/layouts/newrelic_default.rhtml +47 -0
  190. data/ui/views/newrelic/_explain_plans.rhtml +27 -0
  191. data/ui/views/newrelic/_sample.rhtml +20 -0
  192. data/ui/views/newrelic/_segment.rhtml +28 -0
  193. data/ui/views/newrelic/_segment_limit_message.rhtml +1 -0
  194. data/ui/views/newrelic/_segment_row.rhtml +12 -0
  195. data/ui/views/newrelic/_show_sample_detail.rhtml +24 -0
  196. data/ui/views/newrelic/_show_sample_sql.rhtml +24 -0
  197. data/ui/views/newrelic/_show_sample_summary.rhtml +3 -0
  198. data/ui/views/newrelic/_sql_row.rhtml +16 -0
  199. data/ui/views/newrelic/_stack_trace.rhtml +15 -0
  200. data/ui/views/newrelic/_table.rhtml +12 -0
  201. data/ui/views/newrelic/explain_sql.rhtml +43 -0
  202. data/ui/views/newrelic/file/images/arrow-close.png +0 -0
  203. data/ui/views/newrelic/file/images/arrow-open.png +0 -0
  204. data/ui/views/newrelic/file/images/blue_bar.gif +0 -0
  205. data/ui/views/newrelic/file/images/file_icon.png +0 -0
  206. data/ui/views/newrelic/file/images/gray_bar.gif +0 -0
  207. data/ui/views/newrelic/file/images/new-relic-rpm-desktop.gif +0 -0
  208. data/ui/views/newrelic/file/images/new_relic_rpm_desktop.gif +0 -0
  209. data/ui/views/newrelic/file/images/textmate.png +0 -0
  210. data/ui/views/newrelic/file/javascript/jquery-1.4.2.js +6240 -0
  211. data/ui/views/newrelic/file/javascript/transaction_sample.js +120 -0
  212. data/ui/views/newrelic/file/stylesheets/style.css +490 -0
  213. data/ui/views/newrelic/index.rhtml +71 -0
  214. data/ui/views/newrelic/sample_not_found.rhtml +2 -0
  215. data/ui/views/newrelic/show_sample.rhtml +80 -0
  216. data/ui/views/newrelic/show_source.rhtml +3 -0
  217. data/ui/views/newrelic/threads.rhtml +53 -0
  218. data/vendor/gems/dependency_detection-0.0.1.build/LICENSE +5 -0
  219. data/vendor/gems/dependency_detection-0.0.1.build/lib/dependency_detection.rb +67 -0
  220. data/vendor/gems/dependency_detection-0.0.1.build/lib/dependency_detection/version.rb +3 -0
  221. data/vendor/gems/metric_parser-0.1.0.pre1/lib/metric_parser.rb +1 -0
  222. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser.rb +64 -0
  223. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/action_mailer.rb +14 -0
  224. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/active_merchant.rb +31 -0
  225. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/active_record.rb +33 -0
  226. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/apdex.rb +89 -0
  227. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/background_transaction.rb +7 -0
  228. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/client.rb +46 -0
  229. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/controller.rb +67 -0
  230. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/controller_cpu.rb +43 -0
  231. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/controller_ext.rb +17 -0
  232. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/database.rb +48 -0
  233. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/database_pool.rb +24 -0
  234. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/dot_net.rb +28 -0
  235. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/dot_net_parser.rb +17 -0
  236. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/errors.rb +11 -0
  237. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/external.rb +55 -0
  238. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/frontend.rb +40 -0
  239. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/gc.rb +20 -0
  240. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/hibernate_session.rb +7 -0
  241. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/java.rb +31 -0
  242. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/java_parser.rb +17 -0
  243. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/jsp.rb +34 -0
  244. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/jsp_tag.rb +7 -0
  245. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/mem_cache.rb +55 -0
  246. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/metric_parser.rb +135 -0
  247. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/orm.rb +27 -0
  248. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/other_transaction.rb +40 -0
  249. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/servlet.rb +7 -0
  250. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/servlet_context_listener.rb +7 -0
  251. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/servlet_filter.rb +7 -0
  252. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/solr.rb +27 -0
  253. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/solr_request_handler.rb +15 -0
  254. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/spring.rb +54 -0
  255. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/spring_controller.rb +6 -0
  256. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/spring_view.rb +6 -0
  257. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/struts_action.rb +20 -0
  258. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/struts_result.rb +20 -0
  259. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/version.rb +5 -0
  260. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/view.rb +70 -0
  261. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/web_frontend.rb +18 -0
  262. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/web_service.rb +14 -0
  263. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/web_transaction.rb +133 -0
  264. metadata +376 -0
@@ -0,0 +1,52 @@
1
+ #!/bin/bash
2
+
3
+ # Script to benchmark the ruby agent under various versions of ruby in ci.
4
+
5
+ echo "Executing $0"
6
+ echo "Running in $(pwd)"
7
+
8
+ # print commands in this script as they're invoked
9
+ # set -x
10
+ # fail if any command fails
11
+ set -e
12
+
13
+ # check for require environment variables
14
+ if [ "x$RUBY" == "x" ]; then
15
+ echo '$RUBY is undefined'
16
+ exit 1
17
+ fi
18
+
19
+
20
+ . "$HOME/.rvm/scripts/rvm"
21
+ rvm use $RUBY || rvm install $RUBY
22
+ echo `which ruby`
23
+
24
+ # make sure that we're in the project root
25
+ script_dirname=`dirname $0`
26
+ cd "$script_dirname/../../"
27
+ pwd
28
+
29
+ rm -rf tmp
30
+ mkdir -p tmp
31
+ cd tmp
32
+ git clone --depth=1 git@github.com:newrelic/agent_prof.git agent_prof
33
+ cd agent_prof
34
+
35
+ perl -p -i'.bak' -e 's#gem +.newrelic_rpm.*$#gem "newrelic_rpm", :path => "\.\.\/\.\.\/"#' Gemfile
36
+
37
+ rvm --force gemset delete ruby_bench_$RUBY
38
+ rvm gemset create ruby_bench_$RUBY
39
+ rvm gemset use ruby_bench_$RUBY
40
+
41
+ if [ "x$RUBY" == "x1.8.6" ]; then
42
+ # Bundler 1.1 dropped support for ruby 1.8.6
43
+ gem install bundler -v'~>1.0.0' --no-rdoc --no-ri
44
+ else
45
+ gem install bundler --no-rdoc --no-ri
46
+ fi
47
+
48
+ bundle
49
+ script/run
50
+ bundle exec script/post_log_to_dashboard
51
+
52
+
@@ -0,0 +1,29 @@
1
+
2
+ module TestContexts
3
+ def with_running_agent
4
+
5
+ context 'with running agent' do # this is needed for the nested setups
6
+
7
+ setup do
8
+ @log_data = StringIO.new
9
+ @log = Logger.new(@log_data)
10
+ NewRelic::Agent.manual_start :log => @log
11
+ @agent = NewRelic::Agent.instance
12
+ @agent.transaction_sampler.send :clear_builder
13
+ @agent.transaction_sampler.reset!
14
+ @agent.stats_engine.clear_stats
15
+ end
16
+
17
+ yield
18
+
19
+ def teardown
20
+ super
21
+ NewRelic::Agent.shutdown
22
+ @log_data.reset
23
+ NewRelic::Control.instance['dispatcher']=nil
24
+ NewRelic::Control.instance['dispatcher_instance_id']=nil
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,155 @@
1
+ module NewRelic; TEST = true; end unless defined? NewRelic::TEST
2
+ ENV['RAILS_ENV'] = 'test'
3
+ NEWRELIC_PLUGIN_DIR = File.expand_path(File.join(File.dirname(__FILE__),".."))
4
+ $LOAD_PATH << '.'
5
+ $LOAD_PATH << '../../..'
6
+ $LOAD_PATH << File.join(NEWRELIC_PLUGIN_DIR,"test")
7
+ $LOAD_PATH << File.join(NEWRELIC_PLUGIN_DIR,"ui/helpers")
8
+ $LOAD_PATH.uniq!
9
+
10
+ require 'rubygems'
11
+ # We can speed things up in tests that don't need to load rails.
12
+ # You can also run the tests in a mode without rails. Many tests
13
+ # will be skipped.
14
+
15
+ begin
16
+ require 'config/environment'
17
+ # require File.join(File.dirname(__FILE__),'..','..','rpm_test_app','config','environment')
18
+ begin
19
+ require 'test_help'
20
+ rescue LoadError
21
+ # ignore load problems on test help - it doesn't exist in rails 3
22
+ end
23
+
24
+ rescue LoadError
25
+ # To run the tests against a standalone agent build, you need to
26
+ # add a rails app to the load path. It can be 2.* to 3.*. It should
27
+ # referenc newrelic_rpm in the Gemfile with a :path option pointing
28
+ # to this work directory.
29
+ guess = File.expand_path("../../../rpm", __FILE__)
30
+ if $LOAD_PATH.include? guess
31
+ puts "Unable to load Rails for New Relic tests. See note in test_helper.rb"
32
+ raise
33
+ else
34
+ $LOAD_PATH << guess
35
+ retry
36
+ end
37
+ end
38
+ require 'newrelic_rpm'
39
+
40
+ require 'test/unit'
41
+ require 'shoulda'
42
+ require 'test_contexts'
43
+ require 'mocha'
44
+ require 'mocha/integration/test_unit'
45
+ require 'mocha/integration/test_unit/assertion_counter'
46
+
47
+ class Test::Unit::TestCase
48
+ include Mocha::API
49
+
50
+ # we can delete this trick when we stop supporting rails2.0.x
51
+ if ENV['BRANCH'] != 'rails20'
52
+ # a hack because rails2.0.2 does not like double teardowns
53
+ def teardown
54
+ mocha_teardown
55
+ end
56
+ end
57
+ end
58
+
59
+ def assert_between(floor, ceiling, value, message="expected #{floor} <= #{value} <= #{ceiling}")
60
+ assert((floor <= value && value <= ceiling), message)
61
+ end
62
+
63
+ def check_metric_time(metric, value, delta)
64
+ time = NewRelic::Agent.get_stats(metric).total_call_time
65
+ assert_between((value - delta), (value + delta), time)
66
+ end
67
+
68
+ def check_metric_count(metric, value)
69
+ count = NewRelic::Agent.get_stats(metric).call_count
70
+ assert_equal(value, count, "should have the correct number of calls")
71
+ end
72
+
73
+ def check_unscoped_metric_count(metric, value)
74
+ count = NewRelic::Agent.get_stats_unscoped(metric).call_count
75
+ assert_equal(value, count, "should have the correct number of calls")
76
+ end
77
+
78
+ def generate_unscoped_metric_counts(*metrics)
79
+ metrics.inject({}) do |sum, metric|
80
+ sum[metric] = NewRelic::Agent.get_stats_no_scope(metric).call_count
81
+ sum
82
+ end
83
+ end
84
+
85
+ def generate_metric_counts(*metrics)
86
+ metrics.inject({}) do |sum, metric|
87
+ sum[metric] = NewRelic::Agent.get_stats(metric).call_count
88
+ sum
89
+ end
90
+ end
91
+
92
+ def assert_does_not_call_metrics(*metrics)
93
+ first_metrics = generate_metric_counts(*metrics)
94
+ yield
95
+ last_metrics = generate_metric_counts(*metrics)
96
+ assert_equal first_metrics, last_metrics, "should not have changed these metrics"
97
+ end
98
+
99
+ def assert_calls_metrics(*metrics)
100
+ first_metrics = generate_metric_counts(*metrics)
101
+ yield
102
+ last_metrics = generate_metric_counts(*metrics)
103
+ assert_not_equal first_metrics, last_metrics, "should have changed these metrics"
104
+ end
105
+
106
+ def assert_calls_unscoped_metrics(*metrics)
107
+ first_metrics = generate_unscoped_metric_counts(*metrics)
108
+ yield
109
+ last_metrics = generate_unscoped_metric_counts(*metrics)
110
+ assert_not_equal first_metrics, last_metrics, "should have changed these metrics"
111
+ end
112
+
113
+
114
+ def compare_metrics(expected, actual)
115
+ actual.delete_if {|a| a.include?('GC/cumulative') } # in case we are in REE
116
+ assert_equal(expected.to_a.sort, actual.to_a.sort, "extra: #{(actual - expected).to_a.inspect}; missing: #{(expected - actual).to_a.inspect}")
117
+ end
118
+
119
+ module TransactionSampleTestHelper
120
+ def make_sql_transaction(*sql)
121
+ sampler = NewRelic::Agent::TransactionSampler.new
122
+ sampler.notice_first_scope_push Time.now.to_f
123
+ sampler.notice_transaction '/path', nil, :jim => "cool"
124
+ sampler.notice_push_scope "a"
125
+
126
+ sampler.notice_transaction '/path/2', nil, :jim => "cool"
127
+
128
+ sql.each {|sql_statement| sampler.notice_sql(sql_statement, {:adapter => "test"}, 0 ) }
129
+
130
+ sleep 0.02
131
+ yield if block_given?
132
+ sampler.notice_pop_scope "a"
133
+ sampler.notice_scope_empty
134
+
135
+ sampler.samples[0]
136
+ end
137
+
138
+ def run_sample_trace_on(sampler, path='/path')
139
+ sampler.notice_first_scope_push Time.now.to_f
140
+ sampler.notice_transaction path, path, {}
141
+ sampler.notice_push_scope "Controller/sandwiches/index"
142
+ sampler.notice_sql("SELECT * FROM sandwiches WHERE bread = 'wheat'", nil, 0)
143
+ sampler.notice_push_scope "ab"
144
+ sampler.notice_sql("SELECT * FROM sandwiches WHERE bread = 'white'", nil, 0)
145
+ yield sampler if block_given?
146
+ sampler.notice_pop_scope "ab"
147
+ sampler.notice_push_scope "lew"
148
+ sampler.notice_sql("SELECT * FROM sandwiches WHERE bread = 'french'", nil, 0)
149
+ sampler.notice_pop_scope "lew"
150
+ sampler.notice_pop_scope "Controller/sandwiches/index"
151
+ sampler.notice_scope_empty
152
+ sampler.samples[0]
153
+ end
154
+
155
+ end
@@ -0,0 +1,357 @@
1
+ require 'pathname'
2
+ require File.expand_path('../google_pie_chart', __FILE__)
3
+ require 'new_relic/collection_helper'
4
+ require 'new_relic/metric_parser/metric_parser'
5
+ module NewRelic::DeveloperModeHelper
6
+ include NewRelic::CollectionHelper
7
+
8
+ private
9
+
10
+ # limit of how many detail/SQL rows we display - very large data sets (~10000+) crash browsers
11
+ def trace_row_display_limit
12
+ 2000
13
+ end
14
+
15
+ def trace_row_display_limit_reached
16
+ (!@detail_segment_count.nil? && @detail_segment_count > trace_row_display_limit) || @sample.sql_segments.length > trace_row_display_limit
17
+ end
18
+
19
+ # return the sample but post processed to strip out segments that normally don't show
20
+ # up in production (after the first execution, at least) such as application code loading
21
+ def stripped_sample(sample = @sample)
22
+ sample.omit_segments_with('(Rails/Application Code Loading)|(Database/.*/.+ Columns)')
23
+ end
24
+
25
+ # return the highest level in the call stack for the trace that is not rails or
26
+ # newrelic agent code
27
+ def application_caller(trace)
28
+ trace = strip_nr_from_backtrace(trace) unless params[:show_nr]
29
+ trace.each do |trace_line|
30
+ file, line, gem = file_and_line(trace_line)
31
+ unless file && exclude_file_from_stack_trace?(file, false, gem)
32
+ return trace_line
33
+ end
34
+ end
35
+ trace.last
36
+ end
37
+
38
+ def application_stack_trace(trace, include_rails = false)
39
+ trace = strip_nr_from_backtrace(trace) unless params[:show_nr]
40
+ trace.reject do |trace_line|
41
+ file, line, gem = file_and_line(trace_line)
42
+ file && exclude_file_from_stack_trace?(file, include_rails, gem)
43
+ end
44
+ end
45
+
46
+ def render_backtrace
47
+ if @segment[:backtrace]
48
+ content_tag('h3', 'Application Stack Trace') +
49
+ render(:partial => 'stack_trace')
50
+ end
51
+ end
52
+
53
+ def h(text)
54
+ text
55
+ end
56
+
57
+ def agent_views_path(path)
58
+ path
59
+ end
60
+
61
+ def url_for_source(trace_line)
62
+ file, line = file_and_line(trace_line)
63
+ return "#" if file.nil?
64
+ begin
65
+ file = Pathname.new(file).realpath
66
+ rescue Errno::ENOENT
67
+ # we hit this exception when Pathame.realpath fails for some reason; attempt a link to
68
+ # the file without a real path. It may also fail, only when the user clicks on this specific
69
+ # entry in the stack trace
70
+ rescue
71
+ # catch all other exceptions. We're going to create an invalid link below, but that's okay.
72
+ end
73
+ if using_textmate?
74
+ "txmt://open?url=file://#{file}&line=#{line}"
75
+ else
76
+ "show_source?file=#{file}&amp;line=#{line}&amp;anchor=selected_line"
77
+ end
78
+ end
79
+
80
+ def dev_name(metric_name)
81
+ NewRelic::MetricParser::MetricParser.parse(metric_name).developer_name
82
+ end
83
+
84
+ # write the metric label for a segment metric in the detail view
85
+ def write_segment_label(segment)
86
+ if source_available && segment[:backtrace] && (source_url = url_for_source(application_caller(segment[:backtrace])))
87
+ link_to dev_name(segment.metric_name), source_url
88
+ else
89
+ dev_name(segment.metric_name)
90
+ end
91
+ end
92
+
93
+ def source_available
94
+ true
95
+ end
96
+
97
+ # write the metric label for a segment metric in the summary table of metrics
98
+ def write_summary_segment_label(segment)
99
+ dev_name(segment.metric_name)
100
+ end
101
+
102
+ def write_stack_trace_line(trace_line)
103
+ link_to trace_line, url_for_source(trace_line)
104
+ end
105
+
106
+ # write a link to the source for a trace
107
+ def link_to_source(trace)
108
+ image_url = 'file/images/' + (using_textmate? ? "textmate.png" : "file_icon.png")
109
+
110
+ link_to "<img src=#{image_url} alt=\"View Source\" title=\"View Source\"/>", url_for_source(application_caller(trace))
111
+ end
112
+
113
+ # print the formatted timestamp for a segment
114
+ def timestamp(segment)
115
+ sprintf("%1.3f", segment.entry_timestamp)
116
+ end
117
+
118
+ def format_timestamp(time)
119
+ time.strftime("%H:%M:%S")
120
+ end
121
+
122
+ def colorize(value, yellow_threshold = 0.05, red_threshold = 0.15, s=to_ms(value))
123
+ if value > yellow_threshold
124
+ color = (value > red_threshold ? 'red' : 'orange')
125
+ "<font color=#{color}>#{s}</font>"
126
+ else
127
+ "#{s}"
128
+ end
129
+ end
130
+
131
+ def expanded_image_path()
132
+ '/newrelic/file/images/arrow-open.png'
133
+ end
134
+
135
+ def collapsed_image_path()
136
+ '/newrelic/file/images/arrow-close.png'
137
+ end
138
+
139
+ def explain_sql_url(segment)
140
+ "explain_sql?id=#{@sample.sample_id}&amp;segment=#{segment.segment_id}"
141
+ end
142
+
143
+ def segment_duration_value(segment)
144
+ link_to colorize(segment.duration, 0.05, 0.15, "#{with_delimiter(to_ms(segment.duration))} ms"), explain_sql_url(segment)
145
+ end
146
+
147
+ def line_wrap_sql(sql)
148
+ sql.gsub(/\,/,', ').squeeze(' ') if sql
149
+ end
150
+
151
+ def render_sample_details(sample)
152
+ @indentation_depth=0
153
+ # skip past the root segments to the first child, which is always the controller
154
+ first_segment = sample.root_segment.called_segments.first
155
+
156
+ # render the segments, then the css classes to indent them
157
+ render_segment_details(first_segment).to_s + render_indentation_classes(@indentation_depth).to_s
158
+ end
159
+
160
+ # the rows logger plugin disables the sql tracing functionality of the NewRelic agent -
161
+ # notify the user about this
162
+ def rows_logger_present?
163
+ File.exist?(File.join(File.dirname(__FILE__), "../../../rows_logger/init.rb"))
164
+ end
165
+
166
+ def expand_segment_image(segment, depth)
167
+ if depth > 0
168
+ if !segment.called_segments.empty?
169
+ row_class =segment_child_row_class(segment)
170
+ link_to_function("<img src=\"#{collapsed_image_path}\" id=\"image_#{row_class}\" class_for_children=\"#{row_class}\" class=\"#{(!segment.called_segments.empty?) ? 'parent_segment_image' : 'child_segment_image'}\"", "toggle_row_class(this)")
171
+ end
172
+ end
173
+ end
174
+
175
+ def segment_child_row_class(segment)
176
+ "segment#{segment.segment_id}"
177
+ end
178
+
179
+ def summary_pie_chart(sample, width, height)
180
+ pie_chart = GooglePieChart.new
181
+ pie_chart.color, pie_chart.width, pie_chart.height = '6688AA', width, height
182
+
183
+ chart_data = sample.breakdown_data(6)
184
+ chart_data.each { |s| pie_chart.add_data_point dev_name(s.metric_name), to_ms(s.exclusive_time) }
185
+
186
+ pie_chart.render
187
+ end
188
+
189
+ def segment_row_classes(segment, depth)
190
+ classes = []
191
+
192
+ classes << "segment#{segment.parent_segment.segment_id}" if depth > 1
193
+
194
+ classes << "view_segment" if segment.metric_name.index('View') == 0
195
+ classes << "summary_segment" if segment.is_a?(NewRelic::TransactionSample::CompositeSegment)
196
+
197
+ classes.join(' ')
198
+ end
199
+
200
+ # render_segment_details should be called before calling this method
201
+ def render_indentation_classes(depth)
202
+ styles = []
203
+ (1..depth).each do |d|
204
+ styles << ".segment_indent_level#{d} { display: inline-block; margin-left: #{(d-1)*20}px }"
205
+ end
206
+ content_tag("style", styles.join(' '))
207
+ end
208
+
209
+ def sql_link_mouseover_options(segment)
210
+ { :onmouseover => "sql_mouse_over(#{segment.segment_id})", :onmouseout => "sql_mouse_out(#{segment.segment_id})"}
211
+ end
212
+
213
+ def explain_sql_link(segment, child_sql = false)
214
+ link_to 'SQL', explain_sql_url(segment)+ '"' + sql_link_mouseover_options(segment).map {|k,v| "#{k}=\"#{v}\""}.join(' ')+ 'fake=\"'
215
+ end
216
+
217
+ def explain_sql_links(segment)
218
+ if segment[:sql]
219
+ explain_sql_link segment
220
+ else
221
+ links = []
222
+ segment.called_segments.each do |child|
223
+ if child[:sql]
224
+ links << explain_sql_link(child, true)
225
+ end
226
+ end
227
+ links[0..1].join(', ') + (links.length > 2?', ...':'')
228
+ end
229
+ end
230
+
231
+ private
232
+ # return three objects, the file path, the line in the file, and the gem the file belongs to
233
+ # if found
234
+ def file_and_line(stack_trace_line)
235
+ if stack_trace_line =~ /^(?:(\w+) \([\d.]*\) )?(.*):(\d+)/
236
+ return $2, $3, $1
237
+ else
238
+ return nil
239
+ end
240
+ end
241
+
242
+ def using_textmate?
243
+ NewRelic::Control.instance.use_textmate?
244
+ end
245
+
246
+
247
+ def render_segment_details(segment, depth=0)
248
+ @detail_segment_count ||= 0
249
+ @detail_segment_count += 1
250
+
251
+ return '' if @detail_segment_count > trace_row_display_limit
252
+
253
+ @indentation_depth = depth if depth > @indentation_depth
254
+ repeat = nil
255
+ if segment.is_a?(NewRelic::TransactionSample::CompositeSegment)
256
+ html = ''
257
+ else
258
+ repeat = segment.parent_segment.detail_segments.length if segment.parent_segment.is_a?(NewRelic::TransactionSample::CompositeSegment)
259
+ html = render(:partial => 'segment', :object => [segment, depth, repeat])
260
+ depth += 1
261
+ end
262
+
263
+ segment.called_segments.each do |child|
264
+ html << render_segment_details(child, depth)
265
+ end
266
+
267
+ html
268
+ end
269
+
270
+ def exclude_file_from_stack_trace?(file, include_rails, gem=nil)
271
+ return false if include_rails
272
+ return true if file !~ /\.(rb|java)/
273
+ return true if %w[rack activerecord activeresource activesupport actionpack railties].include? gem
274
+ %w[/actionmailer/
275
+ /activerecord
276
+ /activeresource
277
+ /activesupport
278
+ /lib/mongrel
279
+ /actionpack
280
+ /passenger/
281
+ /railties
282
+ benchmark.rb].each { |s| return true if file.include? s }
283
+ false
284
+ end
285
+
286
+ def show_view_link(title, page_name)
287
+ link_to_function("[#{title}]", "show_view('#{page_name}')");
288
+ end
289
+
290
+
291
+ def link_to(name, location)
292
+ location = "/newrelic/#{location}" unless /:\/\// =~ location
293
+ "<a href=\"#{location}\">#{name}</a>"
294
+ end
295
+
296
+ def link_to_if(predicate, text, location="")
297
+ if predicate
298
+ link_to(text, location)
299
+ else
300
+ text
301
+ end
302
+ end
303
+
304
+ def link_to_unless_current(text, hash)
305
+ unless params[hash.keys[0].to_s]
306
+ link_to(text,"?#{hash.keys[0]}=#{hash.values[0]}")
307
+ else
308
+ text
309
+ end
310
+ end
311
+
312
+ def cycle(even, odd)
313
+ @cycle ||= 'a'
314
+ if @cycle == 'a'
315
+ @cycle = 'b'
316
+ even
317
+ else
318
+ @cycle = 'a'
319
+ odd
320
+ end
321
+ end
322
+
323
+ def link_to_function(title, javascript)
324
+ "<a href=\"#\" onclick=\"#{javascript}; return false;\">#{title}</a>"
325
+ end
326
+
327
+ def mime_type_from_extension(extension)
328
+ extension = extension[/[^.]*$/].dncase
329
+ case extension
330
+ when 'png'; 'image/png'
331
+ when 'gif'; 'image/gif'
332
+ when 'jpg'; 'image/jpg'
333
+ when 'css'; 'text/css'
334
+ when 'js'; 'text/javascript'
335
+ else 'text/plain'
336
+ end
337
+ end
338
+ def to_ms(number)
339
+ (number*1000).round
340
+ end
341
+ def to_percentage(value)
342
+ (value * 100).round if value
343
+ end
344
+ def with_delimiter(val)
345
+ return '0' if val.nil?
346
+ parts = val.to_s.split('.')
347
+ parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1,")
348
+ parts.join '.'
349
+ end
350
+
351
+ def profile_table(profile)
352
+ out = StringIO.new
353
+ printer = RubyProf::GraphHtmlPrinter.new(profile)
354
+ printer.print(out, :min_percent=>0.5)
355
+ out.string[/<body>(.*)<\/body>/im, 0].gsub('<table>', '<table class=profile>')
356
+ end
357
+ end