newrelic_rpm 3.8.1.221 → 3.9.0.229

Sign up to get free protection for your applications and to get access to all the features.
Files changed (288) hide show
  1. data.tar.gz.sig +0 -0
  2. data/.gitignore +1 -0
  3. data/.yardopts +2 -0
  4. data/CHANGELOG +95 -0
  5. data/README.md +9 -3
  6. data/Rakefile +6 -0
  7. data/lib/new_relic/agent.rb +37 -52
  8. data/lib/new_relic/agent/agent.rb +32 -64
  9. data/lib/new_relic/agent/agent_logger.rb +3 -2
  10. data/lib/new_relic/agent/audit_logger.rb +2 -1
  11. data/lib/new_relic/agent/busy_calculator.rb +10 -8
  12. data/lib/new_relic/agent/configuration.rb +0 -13
  13. data/lib/new_relic/agent/configuration/default_source.rb +27 -20
  14. data/lib/new_relic/agent/configuration/manager.rb +101 -27
  15. data/lib/new_relic/agent/cross_app_monitor.rb +43 -50
  16. data/lib/new_relic/agent/cross_app_tracing.rb +13 -12
  17. data/lib/new_relic/agent/error_collector.rb +31 -35
  18. data/lib/new_relic/agent/harvester.rb +5 -1
  19. data/lib/new_relic/agent/hostname.rb +17 -0
  20. data/lib/new_relic/agent/http_clients/curb_wrappers.rb +1 -1
  21. data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +1 -1
  22. data/lib/new_relic/agent/http_clients/uri_util.rb +13 -0
  23. data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +18 -32
  24. data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +15 -15
  25. data/lib/new_relic/agent/instrumentation/active_merchant.rb +1 -1
  26. data/lib/new_relic/agent/instrumentation/active_record.rb +6 -4
  27. data/lib/new_relic/agent/instrumentation/active_record_helper.rb +3 -2
  28. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +18 -20
  29. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +79 -93
  30. data/lib/new_relic/agent/instrumentation/curb.rb +3 -3
  31. data/lib/new_relic/agent/instrumentation/data_mapper.rb +5 -4
  32. data/lib/new_relic/agent/instrumentation/middleware_proxy.rb +96 -0
  33. data/lib/new_relic/agent/instrumentation/middleware_tracing.rb +69 -0
  34. data/lib/new_relic/agent/instrumentation/net.rb +1 -1
  35. data/lib/new_relic/agent/instrumentation/queue_time.rb +21 -13
  36. data/lib/new_relic/agent/instrumentation/rack.rb +85 -74
  37. data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +3 -1
  38. data/lib/new_relic/agent/instrumentation/rails_middleware.rb +39 -0
  39. data/lib/new_relic/agent/instrumentation/rubyprof.rb +3 -3
  40. data/lib/new_relic/agent/instrumentation/sidekiq.rb +28 -5
  41. data/lib/new_relic/agent/instrumentation/sinatra.rb +4 -4
  42. data/lib/new_relic/agent/instrumentation/typhoeus.rb +4 -2
  43. data/lib/new_relic/agent/javascript_instrumentor.rb +34 -30
  44. data/lib/new_relic/agent/memory_logger.rb +12 -12
  45. data/lib/new_relic/agent/method_tracer.rb +34 -74
  46. data/lib/new_relic/agent/new_relic_service.rb +1 -1
  47. data/lib/new_relic/agent/pipe_channel_manager.rb +3 -3
  48. data/lib/new_relic/agent/request_sampler.rb +10 -11
  49. data/lib/new_relic/agent/samplers/vm_sampler.rb +6 -6
  50. data/lib/new_relic/agent/shim_agent.rb +2 -1
  51. data/lib/new_relic/agent/sql_sampler.rb +52 -27
  52. data/lib/new_relic/agent/stats.rb +24 -10
  53. data/lib/new_relic/agent/stats_engine/gc_profiler.rb +5 -17
  54. data/lib/new_relic/agent/stats_engine/metric_stats.rb +106 -58
  55. data/lib/new_relic/agent/stats_engine/stats_hash.rb +20 -24
  56. data/lib/new_relic/agent/supported_versions.rb +3 -1
  57. data/lib/new_relic/agent/threading/agent_thread.rb +42 -11
  58. data/lib/new_relic/agent/threading/backtrace_service.rb +3 -7
  59. data/lib/new_relic/agent/threading/thread_profile.rb +2 -2
  60. data/lib/new_relic/agent/traced_method_stack.rb +28 -18
  61. data/lib/new_relic/agent/transaction.rb +249 -196
  62. data/lib/new_relic/agent/transaction_metrics.rb +57 -0
  63. data/lib/new_relic/agent/transaction_sample_builder.rb +10 -7
  64. data/lib/new_relic/agent/transaction_sampler.rb +81 -45
  65. data/lib/new_relic/agent/transaction_state.rb +38 -49
  66. data/lib/new_relic/agent/vm/monotonic_gc_profiler.rb +15 -18
  67. data/lib/new_relic/agent/vm/rubinius_vm.rb +4 -2
  68. data/lib/new_relic/cli/commands/deployments.rb +3 -2
  69. data/lib/new_relic/control/frameworks/ruby.rb +2 -3
  70. data/lib/new_relic/control/frameworks/sinatra.rb +0 -7
  71. data/lib/new_relic/control/instance_methods.rb +3 -5
  72. data/lib/new_relic/json_wrapper.rb +2 -0
  73. data/lib/new_relic/language_support.rb +1 -1
  74. data/lib/new_relic/local_environment.rb +0 -16
  75. data/lib/new_relic/metric_spec.rb +10 -38
  76. data/lib/new_relic/noticed_error.rb +16 -11
  77. data/lib/new_relic/rack/agent_hooks.rb +4 -10
  78. data/lib/new_relic/rack/agent_middleware.rb +31 -0
  79. data/lib/new_relic/rack/browser_monitoring.rb +7 -13
  80. data/lib/new_relic/rack/developer_mode.rb +16 -59
  81. data/lib/new_relic/rack/error_collector.rb +16 -54
  82. data/lib/new_relic/recipes.rb +8 -101
  83. data/lib/new_relic/recipes/capistrano3.rb +66 -0
  84. data/lib/new_relic/recipes/capistrano_legacy.rb +98 -0
  85. data/lib/new_relic/transaction_sample.rb +6 -54
  86. data/lib/new_relic/transaction_sample/composite_segment.rb +1 -1
  87. data/lib/new_relic/transaction_sample/segment.rb +12 -4
  88. data/lib/new_relic/transaction_sample/summary_segment.rb +1 -1
  89. data/lib/new_relic/version.rb +2 -2
  90. data/lib/newrelic_rpm.rb +1 -1
  91. data/lib/sequel/extensions/newrelic_instrumentation.rb +19 -19
  92. data/lib/tasks/tests.rake +20 -1
  93. data/lib/tasks/versions.html.erb +0 -4
  94. data/lib/tasks/versions.rake +4 -3
  95. data/newrelic.yml +4 -12
  96. data/newrelic_rpm.gemspec +1 -1
  97. data/test/agent_helper.rb +146 -44
  98. data/test/config/newrelic.yml +0 -1
  99. data/test/environments/norails/Gemfile +1 -1
  100. data/test/environments/rails21/Gemfile +1 -1
  101. data/test/environments/rails22/Gemfile +1 -1
  102. data/test/environments/rails23/Gemfile +1 -1
  103. data/test/environments/rails30/Gemfile +1 -1
  104. data/test/environments/rails31/Gemfile +1 -1
  105. data/test/environments/rails32/Gemfile +1 -1
  106. data/test/environments/rails40/Gemfile +1 -1
  107. data/test/environments/rails41/Gemfile +1 -1
  108. data/test/multiverse/lib/multiverse/runner.rb +13 -1
  109. data/test/multiverse/lib/multiverse/suite.rb +26 -9
  110. data/test/multiverse/suites/active_record/config/newrelic.yml +0 -1
  111. data/test/multiverse/suites/activemerchant/Envfile +18 -1
  112. data/test/multiverse/suites/agent_only/audit_log_test.rb +4 -3
  113. data/test/multiverse/suites/agent_only/collector_exception_handling_test.rb +35 -0
  114. data/test/multiverse/suites/agent_only/config/newrelic.yml +0 -1
  115. data/test/multiverse/suites/agent_only/cross_application_tracing_test.rb +1 -0
  116. data/test/multiverse/suites/agent_only/encoding_handling_test.rb +3 -2
  117. data/test/multiverse/suites/agent_only/exclusive_time_test.rb +178 -0
  118. data/test/multiverse/suites/agent_only/logging_test.rb +10 -6
  119. data/test/multiverse/suites/agent_only/marshaling_test.rb +11 -9
  120. data/test/multiverse/suites/agent_only/script/loading.rb +1 -1
  121. data/test/multiverse/suites/agent_only/service_timeout_test.rb +5 -1
  122. data/test/multiverse/suites/agent_only/transaction_ignoring_test.rb +2 -1
  123. data/test/multiverse/suites/agent_only/xray_sessions_test.rb +9 -9
  124. data/test/multiverse/suites/capistrano/Capfile +26 -0
  125. data/test/multiverse/suites/capistrano/Envfile +18 -0
  126. data/test/multiverse/suites/capistrano/config/deploy.rb +10 -0
  127. data/test/multiverse/suites/capistrano/config/deploy/production.rb +9 -0
  128. data/test/multiverse/suites/capistrano/config/newrelic.yml +21 -0
  129. data/test/multiverse/suites/capistrano/deployment_test.rb +47 -0
  130. data/test/multiverse/suites/capistrano2/Capfile +4 -0
  131. data/test/multiverse/suites/capistrano2/Envfile +4 -0
  132. data/test/multiverse/suites/capistrano2/config/deploy.rb +19 -0
  133. data/test/multiverse/suites/capistrano2/config/newrelic.yml +21 -0
  134. data/test/multiverse/suites/capistrano2/deployment_test.rb +38 -0
  135. data/test/multiverse/suites/curb/Envfile +10 -1
  136. data/test/multiverse/suites/curb/config/newrelic.yml +0 -1
  137. data/test/multiverse/suites/datamapper/config/newrelic.yml +0 -1
  138. data/test/multiverse/suites/deferred_instrumentation/config/newrelic.yml +0 -1
  139. data/test/multiverse/suites/excon/config/newrelic.yml +0 -1
  140. data/test/multiverse/suites/httpclient/config/newrelic.yml +0 -1
  141. data/test/multiverse/suites/mongo/config/newrelic.yml +0 -1
  142. data/test/multiverse/suites/net_http/config/newrelic.yml +0 -1
  143. data/test/multiverse/suites/padrino/config/newrelic.yml +0 -1
  144. data/test/multiverse/suites/rack/Envfile +25 -0
  145. data/test/multiverse/suites/rack/example_app.rb +50 -0
  146. data/test/multiverse/suites/rack/nested_non_rack_app_test.rb +66 -0
  147. data/test/multiverse/suites/rack/rack_auto_instrumentation_test.rb +143 -0
  148. data/test/multiverse/suites/rack/rack_unsupported_version_test.rb +45 -0
  149. data/test/multiverse/suites/rack/url_map_test.rb +120 -0
  150. data/test/multiverse/suites/rails/Envfile +10 -0
  151. data/test/multiverse/suites/rails/app.rb +28 -63
  152. data/test/multiverse/suites/rails/bad_instrumentation_test.rb +2 -4
  153. data/test/multiverse/suites/rails/config/newrelic.yml +1 -2
  154. data/test/multiverse/suites/rails/dummy.txt +1 -0
  155. data/test/multiverse/suites/rails/error_tracing_test.rb +46 -31
  156. data/test/multiverse/suites/rails/gc_instrumentation_test.rb +0 -1
  157. data/test/multiverse/suites/rails/ignore_test.rb +9 -3
  158. data/test/multiverse/suites/rails/middleware_instrumentation_test.rb +41 -0
  159. data/test/multiverse/suites/rails/middlewares.rb +19 -0
  160. data/test/multiverse/suites/rails/parameter_capture_test.rb +169 -0
  161. data/test/multiverse/suites/rails/queue_time_test.rb +14 -4
  162. data/test/multiverse/suites/rails/rails2_app/app/controllers/application.rb +7 -0
  163. data/test/multiverse/suites/rails/rails2_app/config/boot.rb +127 -0
  164. data/test/multiverse/suites/rails/rails2_app/config/database.yml +18 -0
  165. data/test/multiverse/suites/rails/rails2_app/config/environment.rb +16 -0
  166. data/test/multiverse/suites/rails/rails2_app/config/environments/development.rb +10 -0
  167. data/test/multiverse/suites/rails/rails2_app/config/initializers/load_newrelic_rpm.rb +9 -0
  168. data/test/multiverse/suites/rails/rails2_app/config/preinitializer.rb +25 -0
  169. data/test/multiverse/suites/rails/rails2_app/config/routes.rb +18 -0
  170. data/test/multiverse/suites/rails/rails2_app/db/schema.rb +5 -0
  171. data/test/multiverse/suites/rails/rails3_app/app_rails3_plus.rb +76 -0
  172. data/test/multiverse/suites/rails/request_statistics_test.rb +2 -4
  173. data/test/multiverse/suites/rails/transaction_ignoring_test.rb +3 -5
  174. data/test/multiverse/suites/rails/view_instrumentation_test.rb +73 -42
  175. data/test/multiverse/suites/resque/config/newrelic.yml +0 -1
  176. data/test/multiverse/suites/sequel/config/newrelic.yml +0 -1
  177. data/test/multiverse/suites/sidekiq/Envfile +4 -0
  178. data/test/multiverse/suites/sidekiq/after_suite.rb +7 -0
  179. data/test/multiverse/suites/sidekiq/config/newrelic.yml +0 -1
  180. data/test/multiverse/suites/sidekiq/sidekiq_instrumentation_test.rb +55 -34
  181. data/test/multiverse/suites/sidekiq/sidekiq_server.rb +30 -0
  182. data/test/multiverse/suites/sidekiq/test_worker.rb +60 -0
  183. data/test/multiverse/suites/sinatra/config/newrelic.yml +0 -1
  184. data/test/multiverse/suites/sinatra/ignoring_test.rb +33 -11
  185. data/test/multiverse/suites/sinatra/sinatra_metric_explosion_test.rb +3 -1
  186. data/test/multiverse/suites/typhoeus/Envfile +9 -0
  187. data/test/multiverse/suites/typhoeus/config/newrelic.yml +0 -1
  188. data/test/multiverse/suites/typhoeus/typhoeus_test.rb +10 -0
  189. data/test/multiverse/test/suite_examples/one/a/config/newrelic.yml +0 -1
  190. data/test/multiverse/test/suite_examples/one/b/config/newrelic.yml +0 -1
  191. data/test/new_relic/agent/agent/connect_test.rb +3 -10
  192. data/test/new_relic/agent/agent_logger_test.rb +24 -6
  193. data/test/new_relic/agent/agent_test.rb +7 -8
  194. data/test/new_relic/agent/agent_test_controller.rb +2 -2
  195. data/test/new_relic/agent/audit_logger_test.rb +5 -1
  196. data/test/new_relic/agent/busy_calculator_test.rb +1 -1
  197. data/test/new_relic/agent/configuration/manager_test.rb +68 -69
  198. data/test/new_relic/agent/cross_app_monitor_test.rb +32 -14
  199. data/test/new_relic/agent/cross_app_tracing_test.rb +2 -2
  200. data/test/new_relic/agent/error_collector/notice_error_test.rb +9 -33
  201. data/test/new_relic/agent/error_collector_test.rb +45 -14
  202. data/test/new_relic/agent/harvester_test.rb +9 -0
  203. data/test/new_relic/agent/hostname_test.rb +41 -0
  204. data/test/new_relic/agent/instrumentation/action_controller_subscriber_test.rb +27 -19
  205. data/test/new_relic/agent/instrumentation/active_record_subscriber_test.rb +1 -1
  206. data/test/new_relic/agent/instrumentation/active_record_test.rb +3 -3
  207. data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +95 -14
  208. data/test/new_relic/agent/instrumentation/middleware_proxy_test.rb +189 -0
  209. data/test/new_relic/agent/instrumentation/net_instrumentation_test.rb +2 -2
  210. data/test/new_relic/agent/instrumentation/queue_time_test.rb +18 -1
  211. data/test/new_relic/agent/instrumentation/rack_test.rb +10 -1
  212. data/test/new_relic/agent/instrumentation/sinatra_test.rb +3 -1
  213. data/test/new_relic/agent/javascript_instrumentor_test.rb +28 -41
  214. data/test/new_relic/agent/memory_logger_test.rb +14 -0
  215. data/test/new_relic/agent/method_interrobang_test.rb +1 -1
  216. data/test/new_relic/agent/method_tracer/class_methods/add_method_tracer_test.rb +1 -30
  217. data/test/new_relic/agent/method_tracer/instance_methods/trace_execution_scoped_test.rb +5 -21
  218. data/test/new_relic/agent/method_tracer_test.rb +5 -4
  219. data/test/new_relic/agent/mock_scope_listener.rb +2 -2
  220. data/test/new_relic/agent/obfuscator_test.rb +1 -1
  221. data/test/new_relic/agent/pipe_channel_manager_test.rb +17 -5
  222. data/test/new_relic/agent/request_sampler_test.rb +16 -16
  223. data/test/new_relic/agent/rpm_agent_test.rb +23 -29
  224. data/test/new_relic/agent/sql_sampler_test.rb +39 -31
  225. data/test/new_relic/agent/stats_engine/metric_stats_test.rb +189 -117
  226. data/test/new_relic/agent/stats_engine_test.rb +1 -1
  227. data/test/new_relic/agent/stats_hash_test.rb +28 -1
  228. data/test/new_relic/agent/stats_test.rb +1 -12
  229. data/test/new_relic/agent/threading/agent_thread_test.rb +23 -9
  230. data/test/new_relic/agent/threading/backtrace_service_test.rb +33 -32
  231. data/test/new_relic/agent/threading/fake_thread.rb +4 -8
  232. data/test/new_relic/agent/threading/threaded_test_case.rb +4 -14
  233. data/test/new_relic/agent/traced_method_stack_test.rb +43 -27
  234. data/test/new_relic/agent/transaction_interrobang_test.rb +1 -1
  235. data/test/new_relic/agent/transaction_metrics_test.rb +113 -0
  236. data/test/new_relic/agent/transaction_sample_builder_test.rb +1 -61
  237. data/test/new_relic/agent/transaction_sampler_test.rb +176 -228
  238. data/test/new_relic/agent/transaction_state_test.rb +62 -26
  239. data/test/new_relic/agent/transaction_test.rb +198 -80
  240. data/test/new_relic/agent/vm/monotonic_gc_profiler_test.rb +4 -4
  241. data/test/new_relic/agent/vm/rubinius_vm_test.rb +68 -0
  242. data/test/new_relic/agent_test.rb +31 -27
  243. data/test/new_relic/cli/commands/deployments_test.rb +7 -2
  244. data/test/new_relic/control/instance_methods_test.rb +4 -4
  245. data/test/new_relic/control_test.rb +28 -22
  246. data/test/new_relic/dependency_detection_test.rb +14 -0
  247. data/test/new_relic/fake_external_server.rb +1 -0
  248. data/test/new_relic/fake_rpm_site.rb +35 -0
  249. data/test/new_relic/http_client_test_cases.rb +12 -3
  250. data/test/new_relic/json_wrapper_test.rb +5 -0
  251. data/test/new_relic/language_support_test.rb +7 -0
  252. data/test/new_relic/license_test.rb +11 -5
  253. data/test/new_relic/local_environment_test.rb +0 -18
  254. data/test/new_relic/metric_data_test.rb +2 -2
  255. data/test/new_relic/metric_spec_test.rb +4 -23
  256. data/test/new_relic/multiverse_helpers.rb +1 -3
  257. data/test/new_relic/noticed_error_test.rb +6 -22
  258. data/test/new_relic/rack/agent_hooks_test.rb +5 -1
  259. data/test/new_relic/rack/agent_middleware_test.rb +32 -0
  260. data/test/new_relic/rack/browser_monitoring_test.rb +14 -1
  261. data/test/new_relic/rack/developer_mode_helper_test.rb +0 -8
  262. data/test/new_relic/rack/developer_mode_test.rb +1 -1
  263. data/test/new_relic/rack/error_collector_test.rb +6 -30
  264. data/test/new_relic/transaction_sample/fake_segment_test.rb +2 -2
  265. data/test/new_relic/transaction_sample/segment_test.rb +47 -47
  266. data/test/new_relic/transaction_sample_test.rb +9 -8
  267. data/test/performance/lib/performance/instrumentation/stackprof.rb +11 -8
  268. data/test/performance/script/runner +13 -0
  269. data/test/performance/suites/config.rb +5 -2
  270. data/test/performance/suites/rack_middleware.rb +84 -0
  271. data/test/performance/suites/rum_autoinsertion.rb +1 -1
  272. data/test/performance/suites/thread_profiling.rb +1 -1
  273. data/test/test_helper.rb +12 -10
  274. data/ui/helpers/developer_mode_helper.rb +3 -43
  275. data/ui/views/layouts/newrelic_default.rhtml +2 -2
  276. data/ui/views/newrelic/_sample.rhtml +2 -2
  277. data/ui/views/newrelic/_sql_row.rhtml +11 -11
  278. data/ui/views/newrelic/index.rhtml +21 -22
  279. data/vendor/gems/dependency_detection-0.0.1.build/lib/dependency_detection.rb +15 -10
  280. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser.rb +2 -0
  281. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/middleware.rb +34 -0
  282. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/nested.rb +24 -0
  283. metadata +108 -31
  284. metadata.gz.sig +0 -0
  285. data/lib/new_relic/rack/transaction_reset.rb +0 -20
  286. data/test/multiverse/suites/rails/mongrel_queue_depth_test.rb +0 -42
  287. data/test/new_relic/rack/transaction_reset_test.rb +0 -35
  288. data/ui/views/newrelic/show_source.rhtml +0 -3
@@ -19,25 +19,22 @@ module NewRelic
19
19
  @lock = Mutex.new
20
20
  end
21
21
 
22
- class ProfilerNotEnabledError < StandardError
23
- def initialize
24
- super("total_time is not available if GC::Profiler isn't enabled")
25
- end
26
- end
27
-
28
22
  def total_time_s
29
- raise ProfilerNotEnabledError.new unless NewRelic::LanguageSupport.gc_profiler_enabled?
30
-
31
- # There's a race here if the next two lines don't execute as an atomic
32
- # unit - we may end up double-counting some GC time in that scenario.
33
- # Locking around them guarantees atomicity of the read/increment/reset
34
- # sequence.
35
- @lock.synchronize do
36
- # The Ruby 1.9.x docs claim that GC::Profiler.total_time returns
37
- # a value in milliseconds. They are incorrect - both 1.9.x and 2.x
38
- # return values in seconds.
39
- @total_time_s += ::GC::Profiler.total_time
40
- ::GC::Profiler.clear
23
+ if NewRelic::LanguageSupport.gc_profiler_enabled?
24
+ # There's a race here if the next two lines don't execute as an atomic
25
+ # unit - we may end up double-counting some GC time in that scenario.
26
+ # Locking around them guarantees atomicity of the read/increment/reset
27
+ # sequence.
28
+ @lock.synchronize do
29
+ # The Ruby 1.9.x docs claim that GC::Profiler.total_time returns
30
+ # a value in milliseconds. They are incorrect - both 1.9.x and 2.x
31
+ # return values in seconds.
32
+ @total_time_s += ::GC::Profiler.total_time
33
+ ::GC::Profiler.clear
34
+ end
35
+ else
36
+ NewRelic::Agent.logger.log_once(:warn, :gc_profiler_disabled,
37
+ "Tried to measure GC time, but GC::Profiler was not enabled.")
41
38
  end
42
39
 
43
40
  @total_time_s
@@ -18,8 +18,10 @@ module NewRelic
18
18
  snap.gc_runs = GC.count
19
19
 
20
20
  gc_stats = GC.stat[:gc]
21
- snap.major_gc_count = gc_stats[:full][:count] if gc_stats[:full]
22
- snap.minor_gc_count = gc_stats[:young][:count] if gc_stats[:young]
21
+ if gc_stats
22
+ snap.major_gc_count = gc_stats[:full][:count] if gc_stats[:full]
23
+ snap.minor_gc_count = gc_stats[:young][:count] if gc_stats[:young]
24
+ end
23
25
 
24
26
  snap.thread_count = Thread.list.size
25
27
  end
@@ -8,6 +8,7 @@
8
8
  require 'yaml'
9
9
  require 'net/http'
10
10
  require 'rexml/document'
11
+ require 'new_relic/agent/hostname'
11
12
 
12
13
  # We need to use the Control object but we don't want to load
13
14
  # the rails/merb environment. The defined? clause is so that
@@ -43,7 +44,7 @@ class NewRelic::Cli::Deployments < NewRelic::Cli::Command
43
44
 
44
45
  def load_yaml_from_env(env)
45
46
  yaml = NewRelic::Agent::Configuration::YamlSource.new(NewRelic::Agent.config[:config_path], env)
46
- NewRelic::Agent.config.replace_or_add_config(yaml, 1)
47
+ NewRelic::Agent.config.replace_or_add_config(yaml)
47
48
  end
48
49
 
49
50
  def setup_logging(env)
@@ -59,7 +60,7 @@ class NewRelic::Cli::Deployments < NewRelic::Cli::Command
59
60
  create_params = {}
60
61
  {
61
62
  :application_id => @appname,
62
- :host => Socket.gethostname,
63
+ :host => NewRelic::Agent::Hostname.get,
63
64
  :description => @description,
64
65
  :user => @user,
65
66
  :revision => @revision,
@@ -7,9 +7,9 @@ module NewRelic
7
7
  module Frameworks
8
8
  # A control used when no framework is detected - the default.
9
9
  class Ruby < NewRelic::Control
10
-
11
10
  def env
12
- @env ||= ENV['RUBY_ENV'] || ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
11
+ @env ||= ENV['NEW_RELIC_ENV'] || ENV['RUBY_ENV'] ||
12
+ ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
13
13
  end
14
14
 
15
15
  def root
@@ -18,7 +18,6 @@ module NewRelic
18
18
 
19
19
  def init_config(options={})
20
20
  end
21
-
22
21
  end
23
22
  end
24
23
  end
@@ -2,22 +2,15 @@
2
2
  # This file is distributed under New Relic's license terms.
3
3
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
4
 
5
-
6
5
  require 'new_relic/control/frameworks/ruby'
7
6
  module NewRelic
8
7
  class Control
9
8
  module Frameworks
10
9
  # Contains basic control logic for Sinatra
11
10
  class Sinatra < NewRelic::Control::Frameworks::Ruby
12
-
13
- def env
14
- @env ||= ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development'
15
- end
16
-
17
11
  def init_config(options={})
18
12
  super
19
13
  end
20
-
21
14
  end
22
15
  end
23
16
  end
@@ -70,6 +70,7 @@ module NewRelic
70
70
  Module.send :include, NewRelic::Agent::MethodTracer
71
71
  init_config(options)
72
72
  NewRelic::Agent.agent = NewRelic::Agent::Agent.instance
73
+ NewRelic::Agent.agent.start_service_if_needed
73
74
  if Agent.config[:agent_enabled] && !NewRelic::Agent.instance.started?
74
75
  start_agent
75
76
  install_instrumentation
@@ -80,13 +81,10 @@ module NewRelic
80
81
 
81
82
  def configure_agent(env, options)
82
83
  manual = Agent::Configuration::ManualSource.new(options)
83
- Agent.config.replace_or_add_config(manual, 1)
84
+ Agent.config.replace_or_add_config(manual)
84
85
 
85
86
  config_file_path = @config_file_override || Agent.config[:config_path]
86
- Agent.config.replace_or_add_config(Agent::Configuration::YamlSource.new(config_file_path, env), 1)
87
-
88
- Agent.config.remove_config(manual)
89
- Agent.config.replace_or_add_config(Agent::Configuration::ManualSource.new(options), 1)
87
+ Agent.config.replace_or_add_config(Agent::Configuration::YamlSource.new(config_file_path, env))
90
88
  end
91
89
 
92
90
  # Install the real agent into the Agent module, and issue the start command.
@@ -59,6 +59,8 @@ module NewRelic
59
59
  case object
60
60
  when String
61
61
  normalize_string(object)
62
+ when Symbol
63
+ normalize_string(object.to_s)
62
64
  when Array
63
65
  return object if object.empty?
64
66
  result = object.map { |x| normalize(x) }
@@ -73,7 +73,7 @@ module NewRelic::LanguageSupport
73
73
  end
74
74
 
75
75
  def gc_profiler_enabled?
76
- if gc_profiler_usable? && ::GC::Profiler.enabled?
76
+ if gc_profiler_usable? && ::GC::Profiler.enabled? && !::NewRelic::Agent.config[:disable_gc_profiler]
77
77
  true
78
78
  else
79
79
  false
@@ -55,22 +55,6 @@ module NewRelic
55
55
  return nil
56
56
  end
57
57
 
58
- # Sets the @mongrel instance variable if we can find a Mongrel::HttpServer
59
- def mongrel
60
- return @mongrel if @looked_for_mongrel
61
- @looked_for_mongrel = true
62
- if defined?(::Mongrel) && defined?(::Mongrel::HttpServer)
63
- @mongrel = find_class_in_object_space(::Mongrel::HttpServer)
64
- end
65
- @mongrel
66
- end
67
-
68
- # Setter for testing
69
- def mongrel=(m)
70
- @looked_for_mongrel = true
71
- @mongrel = m
72
- end
73
-
74
58
  private
75
59
 
76
60
  def discover_dispatcher
@@ -2,65 +2,37 @@
2
2
  # This file is distributed under New Relic's license terms.
3
3
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
4
 
5
- require 'new_relic/agent/internal_agent_error'
6
-
7
5
  # this struct uniquely defines a metric, optionally inside
8
6
  # the call scope of another metric
9
7
  class NewRelic::MetricSpec
10
- attr_accessor :name
11
- attr_accessor :scope
8
+ attr_reader :name, :scope
12
9
 
13
10
  # the maximum length of a metric name or metric scope
14
11
  MAX_LENGTH = 255
15
12
  LENGTH_RANGE = (0...MAX_LENGTH)
16
- # Need a "zero-arg" constructor so it can be instantiated from java (using
17
- # jruby) for sending responses to ruby agents from the java collector.
18
- #
19
- def initialize(metric_name = '', metric_scope = nil)
20
- self.name = (metric_name || '') && metric_name.to_s[LENGTH_RANGE]
21
- if metric_scope
22
- self.scope = metric_scope && metric_scope.to_s[LENGTH_RANGE]
23
- else
24
- self.scope = ''
25
- end
26
- end
27
-
28
- class InvalidScopeSettingError < NewRelic::Agent::InternalAgentError
29
- def initialize(name, scope)
30
- super("Attempted to set scope for #{name} to #{scope.inspect}, ignoring.")
31
- end
32
- end
13
+ EMPTY_SCOPE = ''.freeze
33
14
 
34
- def scope=(s)
35
- if s.nil? || s == false
36
- NewRelic::Agent.instance.error_collector.notice_agent_error(InvalidScopeSettingError.new(@name, s))
15
+ def initialize(metric_name='', metric_scope=nil)
16
+ @name = metric_name.to_s[LENGTH_RANGE]
17
+ if metric_scope
18
+ @scope = metric_scope.to_s[LENGTH_RANGE]
37
19
  else
38
- @scope = s
20
+ @scope = EMPTY_SCOPE
39
21
  end
40
22
  end
41
23
 
42
- # truncates the name and scope to the MAX_LENGTH
43
- def truncate!
44
- self.name = name[LENGTH_RANGE] if name && name.size > MAX_LENGTH
45
- self.scope = scope[LENGTH_RANGE] if scope && scope.size > MAX_LENGTH
46
- end
47
-
48
24
  def ==(o)
49
25
  self.eql?(o)
50
26
  end
51
27
 
52
28
  def eql? o
53
- self.class == o.class &&
54
- name.eql?(o.name) &&
55
- # coerce scope to a string and compare
56
- scope.to_s == o.scope.to_s
29
+ @name == o.name && @scope == o.scope
57
30
  end
58
31
 
59
32
  def hash
60
- h = name.hash
61
- h ^= scope.hash unless scope.nil?
62
- h
33
+ @name.hash ^ @scope.hash
63
34
  end
35
+
64
36
  # return a new metric spec if the given regex
65
37
  # matches the name or scope.
66
38
  def sub(pattern, replacement, apply_to_scope = true)
@@ -7,9 +7,8 @@ require 'new_relic/helper'
7
7
  # This class encapsulates an error that was noticed by New Relic in a managed app.
8
8
  class NewRelic::NoticedError
9
9
  extend NewRelic::CollectionHelper
10
- attr_accessor :path, :timestamp, :params, :message,
11
- :exception_class_name, :exception_class_constant
12
- attr_reader :exception_id
10
+ attr_accessor :path, :timestamp, :params, :message, :exception_class_name
11
+ attr_reader :exception_id, :is_internal
13
12
 
14
13
  STRIPPED_EXCEPTION_REPLACEMENT_MESSAGE = "Message removed by New Relic 'strip_exception_messages' setting"
15
14
 
@@ -19,7 +18,12 @@ class NewRelic::NoticedError
19
18
  @params = NewRelic::NoticedError.normalize_params(data)
20
19
 
21
20
  @exception_class_name = exception.is_a?(Exception) ? exception.class.name : 'Error'
22
- @exception_class_constant = exception.class
21
+
22
+ # It's critical that we not hold onto the exception class constant in this
23
+ # class. These objects get serialized for Resque to a process that might
24
+ # not have the original exception class loaded, so do all processing now
25
+ # while we have the actual exception!
26
+ @is_internal = (exception.class < NewRelic::Agent::InternalAgentError)
23
27
 
24
28
  if exception.nil?
25
29
  @message = '<no message>'
@@ -43,7 +47,8 @@ class NewRelic::NoticedError
43
47
  @message = @message[0..4095] if @message.length > 4096
44
48
 
45
49
  # replace error message if enabled
46
- if NewRelic::Agent.config[:'strip_exception_messages.enabled'] && !whitelisted?
50
+ if NewRelic::Agent.config[:'strip_exception_messages.enabled'] &&
51
+ !self.class.passes_message_whitelist(exception.class)
47
52
  @message = STRIPPED_EXCEPTION_REPLACEMENT_MESSAGE
48
53
  end
49
54
 
@@ -57,12 +62,6 @@ class NewRelic::NoticedError
57
62
  exception_class_name
58
63
  end
59
64
 
60
- def whitelisted?
61
- NewRelic::Agent.config.stripped_exceptions_whitelist.find do |klass|
62
- exception_class_constant <= klass
63
- end
64
- end
65
-
66
65
  def ==(other)
67
66
  if other.respond_to?(:exception_id)
68
67
  exception_id == other.exception_id
@@ -71,6 +70,12 @@ class NewRelic::NoticedError
71
70
  end
72
71
  end
73
72
 
73
+ def self.passes_message_whitelist(exception_class)
74
+ NewRelic::Agent.config.stripped_exceptions_whitelist.any? do |klass|
75
+ exception_class <= klass
76
+ end
77
+ end
78
+
74
79
  include NewRelic::Coerce
75
80
 
76
81
  def to_collector_array(encoder=nil)
@@ -3,7 +3,8 @@
3
3
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
4
 
5
5
  require 'new_relic/agent/event_listener'
6
- require 'new_relic/rack/transaction_reset'
6
+ require 'new_relic/rack/agent_middleware'
7
+ require 'new_relic/agent/instrumentation/middleware_proxy'
7
8
 
8
9
  module NewRelic::Rack
9
10
  # This middleware is used by the agent internally, and is usually injected
@@ -12,13 +13,7 @@ module NewRelic::Rack
12
13
  #
13
14
  # @api public
14
15
  #
15
- class AgentHooks
16
- def initialize(app, options = {})
17
- @app = app
18
- end
19
-
20
- include TransactionReset
21
-
16
+ class AgentHooks < AgentMiddleware
22
17
  FIRED_FORMATS = {
23
18
  :before_call => "newrelic.agent_hooks_before_fired",
24
19
  :after_call => "newrelic.agent_hooks_after_fired"
@@ -26,8 +21,7 @@ module NewRelic::Rack
26
21
 
27
22
  # method required by Rack interface
28
23
  # [status, headers, response]
29
- def call(env)
30
- ensure_transaction_reset(env)
24
+ def traced_call(env)
31
25
  notify(:before_call, env)
32
26
  result = @app.call(env)
33
27
  notify(:after_call, env, result)
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
+
5
+ require 'new_relic/agent/transaction_state'
6
+ require 'new_relic/agent/instrumentation/controller_instrumentation'
7
+ require 'new_relic/agent/instrumentation/middleware_tracing'
8
+
9
+ module NewRelic
10
+ module Rack
11
+ class AgentMiddleware
12
+ include Agent::Instrumentation::MiddlewareTracing
13
+
14
+ attr_reader :transaction_options, :category, :target
15
+
16
+ def initialize(app, options={})
17
+ @app = app
18
+ @category = :middleware
19
+ @target = self
20
+ @transaction_options = {
21
+ :transaction_name => build_transaction_name
22
+ }
23
+ end
24
+
25
+ def build_transaction_name
26
+ prefix = ::NewRelic::Agent::Instrumentation::ControllerInstrumentation::TransactionNamer.prefix_for_category(nil, @category)
27
+ "#{prefix}#{self.class.name}/call"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -3,7 +3,8 @@
3
3
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
4
 
5
5
  require 'rack'
6
- require 'new_relic/rack/transaction_reset'
6
+ require 'new_relic/rack/agent_middleware'
7
+ require 'new_relic/agent/instrumentation/middleware_proxy'
7
8
 
8
9
  module NewRelic::Rack
9
10
  # This middleware is used by the agent for the Real user monitoring (RUM)
@@ -13,17 +14,8 @@ module NewRelic::Rack
13
14
  #
14
15
  # @api public
15
16
  #
16
- class BrowserMonitoring
17
-
18
- def initialize(app, options = {})
19
- @app = app
20
- end
21
-
22
- include TransactionReset
23
-
24
- # method required by Rack interface
25
- def call(env)
26
- ensure_transaction_reset(env)
17
+ class BrowserMonitoring < AgentMiddleware
18
+ def traced_call(env)
27
19
  result = @app.call(env) # [status, headers, response]
28
20
 
29
21
  if (NewRelic::Agent.browser_timing_header != "") && should_instrument?(env, result[0], result[1])
@@ -89,6 +81,9 @@ module NewRelic::Rack
89
81
  end
90
82
 
91
83
  source
84
+ rescue => e
85
+ NewRelic::Agent.logger.debug "Skipping RUM instrumentation on exception.", e
86
+ nil
92
87
  end
93
88
 
94
89
  def gather_source(response)
@@ -134,5 +129,4 @@ module NewRelic::Rack
134
129
  end
135
130
  end
136
131
  end
137
-
138
132
  end
@@ -8,7 +8,8 @@ require 'rack/response'
8
8
  require 'rack/file'
9
9
  require 'new_relic/collection_helper'
10
10
  require 'new_relic/metric_parser/metric_parser'
11
- require 'new_relic/rack/transaction_reset'
11
+ require 'new_relic/rack/agent_middleware'
12
+ require 'new_relic/agent/instrumentation/middleware_proxy'
12
13
 
13
14
  module NewRelic
14
15
  module Rack
@@ -26,22 +27,24 @@ module NewRelic
26
27
  #
27
28
  # @api public
28
29
  #
29
- class DeveloperMode
30
+ class DeveloperMode < AgentMiddleware
30
31
 
31
- VIEW_PATH = File.expand_path('../../../../ui/views/', __FILE__)
32
+ VIEW_PATH = File.expand_path('../../../../ui/views/' , __FILE__)
32
33
  HELPER_PATH = File.expand_path('../../../../ui/helpers/', __FILE__)
33
34
  require File.join(HELPER_PATH, 'developer_mode_helper.rb')
34
35
 
35
36
 
36
37
  include NewRelic::DeveloperModeHelper
37
- include TransactionReset
38
38
 
39
- def initialize(app)
40
- @app = app
39
+ class << self
40
+ attr_writer :profiling_enabled
41
41
  end
42
42
 
43
- def call(env)
44
- ensure_transaction_reset(env)
43
+ def self.profiling_enabled?
44
+ @profiling_enabled
45
+ end
46
+
47
+ def traced_call(env)
45
48
  return @app.call(env) unless /^\/newrelic/ =~ ::Rack::Request.new(env).path_info
46
49
  dup._call(env)
47
50
  end
@@ -70,8 +73,6 @@ module NewRelic
70
73
  show_sample_data
71
74
  when /explain_sql/
72
75
  explain_sql
73
- when /show_source/
74
- show_source
75
76
  when /^\/newrelic\/?$/
76
77
  index
77
78
  else
@@ -121,14 +122,9 @@ module NewRelic
121
122
  render(:explain_sql)
122
123
  end
123
124
 
124
- PROFILE_CONFIG = { :'profiling.enabled' => true }
125
-
126
125
  def profile
127
- if params['start'] == 'true'
128
- NewRelic::Agent.config.apply_config(PROFILE_CONFIG) unless NewRelic::Agent.config[:'profiling.enabled']
129
- else
130
- NewRelic::Agent.config.remove_config(PROFILE_CONFIG) if NewRelic::Agent.config[:'profiling.enabled']
131
- end
126
+ should_be_on = (params['start'] == 'true')
127
+ NewRelic::Rack::DeveloperMode.profiling_enabled = should_be_on
132
128
 
133
129
  index
134
130
  end
@@ -201,44 +197,6 @@ module NewRelic
201
197
  @segment
202
198
  end
203
199
 
204
-
205
- # show the selected source file with the highlighted selected line
206
- def show_source
207
- @filename = params['file']
208
- line_number = params['line'].to_i
209
-
210
- if !File.readable?(@filename)
211
- @source="<p>Unable to read #{@filename}.</p>"
212
- return
213
- end
214
- begin
215
- file = File.new(@filename, 'r')
216
- rescue => e
217
- @source="<p>Unable to access the source file #{@filename} (#{e.message}).</p>"
218
- return
219
- end
220
- @source = ""
221
-
222
- @source << "<pre>"
223
- file.each_line do |line|
224
- # place an anchor 6 lines above the selected line (if the line # < 6)
225
- if file.lineno == line_number - 6
226
- @source << "</pre><pre id = 'selected_line'>"
227
- @source << line.rstrip
228
- @source << "</pre><pre>"
229
-
230
- # highlight the selected line
231
- elsif file.lineno == line_number
232
- @source << "</pre><pre class = 'selected_source_line'>"
233
- @source << line.rstrip
234
- @source << "</pre><pre>"
235
- else
236
- @source << line
237
- end
238
- end
239
- render(:show_source)
240
- end
241
-
242
200
  def show_sample_data
243
201
  get_sample
244
202
 
@@ -247,7 +205,7 @@ module NewRelic
247
205
  @request_params = @sample.params['request_params'] || {}
248
206
  @custom_params = @sample.params['custom_params'] || {}
249
207
 
250
- controller_metric = @sample.root_segment.called_segments.first.metric_name
208
+ controller_metric = @sample.transaction_name
251
209
 
252
210
  metric_parser = NewRelic::MetricParser::MetricParser.for_metric_named controller_metric
253
211
  @sample_controller_name = metric_parser.controller_name
@@ -269,8 +227,7 @@ module NewRelic
269
227
  sample.params[:path] != nil
270
228
  end
271
229
 
272
- return @samples = @samples.sort{|x,y| y.omit_segments_with('(Rails/Application Code Loading)|(Database/.*/.+ Columns)').duration <=>
273
- x.omit_segments_with('(Rails/Application Code Loading)|(Database/.*/.+ Columns)').duration} if params['h']
230
+ return @samples = @samples.sort_by(&:duration).reverse if params['h']
274
231
  return @samples = @samples.sort{|x,y| x.params[:uri] <=> y.params[:uri]} if params['u']
275
232
  @samples = @samples.reverse
276
233
  end
@@ -281,7 +238,7 @@ module NewRelic
281
238
  sample_id = id.to_i
282
239
  @samples.each do |s|
283
240
  if s.sample_id == sample_id
284
- @sample = stripped_sample(s)
241
+ @sample = s
285
242
  return
286
243
  end
287
244
  end