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
@@ -33,8 +33,8 @@ module NewRelic
33
33
  # See the documentation for +start_trace+ for an explanation of what
34
34
  # +request+ should look like.
35
35
  #
36
- def trace_http_request( request )
37
- return yield unless NewRelic::Agent.is_execution_traced?
36
+ def trace_http_request(request) #THREAD_LOCAL_ACCESS
37
+ return yield unless NewRelic::Agent.tl_is_execution_traced?
38
38
 
39
39
  begin
40
40
  t0, segment = start_trace( request )
@@ -63,11 +63,11 @@ module NewRelic
63
63
  # This method MUST return a pair. The first item always returns the
64
64
  # starting time of the trace, even if an error occurs. The second item is
65
65
  # the transaction segment if it was sucessfully pushed.
66
- def start_trace(request)
66
+ def start_trace(request) #THREAD_LOCAL_ACCESS
67
67
  t0 = Time.now
68
68
 
69
69
  inject_request_headers(request) if cross_app_enabled?
70
- segment = NewRelic::Agent::TracedMethodStack.push_frame(:http_request, t0)
70
+ segment = NewRelic::Agent::TracedMethodStack.tl_push_frame(:http_request, t0)
71
71
 
72
72
  return t0, segment
73
73
  rescue => err
@@ -87,7 +87,7 @@ module NewRelic
87
87
  # * [](key) - Reads response headers.
88
88
  # * to_hash - Converts response headers to a Hash
89
89
  #
90
- def finish_trace( t0, segment, request, response )
90
+ def finish_trace(t0, segment, request, response) #THREAD_LOCAL_ACCESS
91
91
  t1 = Time.now
92
92
  duration = t1.to_f - t0.to_f
93
93
 
@@ -95,11 +95,11 @@ module NewRelic
95
95
  if request
96
96
  # Figure out which metrics we need to report based on the request and response
97
97
  # The last (most-specific) one is scoped.
98
- metrics = metrics_for( request, response )
98
+ metrics = metrics_for(request, response)
99
99
  scoped_metric = metrics.pop
100
100
 
101
- stats_engine.record_metrics(metrics, duration)
102
- stats_engine.record_metrics(scoped_metric, duration, :scoped => true)
101
+ stats_engine.tl_record_scoped_and_unscoped_metrics(
102
+ scoped_metric, metrics, duration)
103
103
 
104
104
  # If we don't have segment, something failed during start_trace so
105
105
  # the current segment isn't the HTTP call it should have been.
@@ -111,7 +111,7 @@ module NewRelic
111
111
  ensure
112
112
  # If we have a segment, always pop the traced method stack to avoid
113
113
  # an inconsistent state, which prevents tracing of whole transaction.
114
- NewRelic::Agent::TracedMethodStack.pop_frame( segment, scoped_metric, t1 ) if segment
114
+ NewRelic::Agent::TracedMethodStack.tl_pop_frame(segment, scoped_metric, t1) if segment
115
115
  end
116
116
  rescue NewRelic::Agent::CrossAppTracing::Error => err
117
117
  NewRelic::Agent.logger.debug "while cross app tracing", err
@@ -150,12 +150,13 @@ module NewRelic
150
150
  end
151
151
 
152
152
  # Inject the X-Process header into the outgoing +request+.
153
- def inject_request_headers( request )
153
+ def inject_request_headers(request) #THREAD_LOCAL_ACCESS
154
154
  cross_app_id = NewRelic::Agent.config[:cross_process_id] or
155
155
  raise NewRelic::Agent::CrossAppTracing::Error, "no cross app ID configured"
156
156
 
157
- NewRelic::Agent::TransactionState.get.is_cross_app_caller = true
158
- txn_guid = NewRelic::Agent::TransactionState.get.request_guid
157
+ state = NewRelic::Agent::TransactionState.tl_get
158
+ state.is_cross_app_caller = true
159
+ txn_guid = state.request_guid
159
160
  txn_data = NewRelic::JSONWrapper.dump([ txn_guid, false ])
160
161
 
161
162
  request[ NR_ID_HEADER ] = obfuscator.obfuscate( cross_app_id )
@@ -28,7 +28,6 @@ module NewRelic
28
28
 
29
29
  # lookup of exception class names to ignore. Hash for fast access
30
30
  @ignore = {}
31
- @capture_source = Agent.config[:'error_collector.capture_source']
32
31
 
33
32
  initialize_ignored_errors(Agent.config[:'error_collector.ignore_errors'])
34
33
  @lock = Mutex.new
@@ -52,6 +51,10 @@ module NewRelic
52
51
  Agent.config[:'error_collector.enabled']
53
52
  end
54
53
 
54
+ def disabled?
55
+ !enabled?
56
+ end
57
+
55
58
  # Returns the error filter proc that is used to check if an
56
59
  # error should be reported. When given a block, resets the
57
60
  # filter to the provided block. The define_method() is used to
@@ -66,6 +69,12 @@ module NewRelic
66
69
  end
67
70
  end
68
71
 
72
+ # Only used from testing scenarios since can't tell difference between
73
+ # having a nil filter passed and no block for retrieval on main method.
74
+ def clear_ignore_error_filter
75
+ @ignore_filter = nil
76
+ end
77
+
69
78
  # errors is an array of Exception Class Names
70
79
  #
71
80
  def ignore(errors)
@@ -94,55 +103,49 @@ module NewRelic
94
103
  # an error is ignored if it is nil or if it is filtered
95
104
  def error_is_ignored?(error)
96
105
  error && filtered_error?(error)
106
+ rescue => e
107
+ NewRelic::Agent.logger.error("Error '#{error}' will NOT be ignored. Exception '#{e}' while determining whether to ignore or not.", e)
108
+ false
97
109
  end
98
110
 
99
- def seen?(exception)
100
- error_ids = TransactionState.get.transaction_noticed_error_ids
111
+ def seen?(txn, exception)
112
+ error_ids = txn.nil? ? [] : txn.noticed_error_ids
101
113
  error_ids.include?(exception.object_id)
102
114
  end
103
115
 
104
- def tag_as_seen(exception)
105
- txn = Transaction.current
116
+ def tag_as_seen(txn, exception)
106
117
  txn.noticed_error_ids << exception.object_id if txn
107
118
  end
108
119
 
109
- def blamed_metric_name(options)
120
+ def blamed_metric_name(txn, options)
110
121
  if options[:metric] && options[:metric] != ::NewRelic::Agent::UNKNOWN_METRIC
111
122
  "Errors/#{options[:metric]}"
112
123
  else
113
- if txn = TransactionState.get.most_recent_transaction
114
- "Errors/#{txn.name}"
115
- end
124
+ "Errors/#{txn.best_name}" if txn
116
125
  end
117
126
  end
118
127
 
119
128
  # Increments a statistic that tracks total error rate
120
129
  # Be sure not to double-count same exception. This clears per harvest.
121
- def increment_error_count!(exception, options={})
122
- return if seen?(exception)
123
- tag_as_seen(exception)
130
+ def increment_error_count!(exception, options={}) #THREAD_LOCAL_ACCESS
131
+ state = ::NewRelic::Agent::TransactionState.tl_get
132
+ txn = state.current_transaction
133
+
134
+ return if seen?(txn, exception)
135
+ tag_as_seen(txn, exception)
124
136
 
125
137
  metric_names = ["Errors/all"]
126
- blamed_metric = blamed_metric_name(options)
138
+ blamed_metric = blamed_metric_name(txn, options)
127
139
  metric_names << blamed_metric if blamed_metric
128
140
 
129
141
  stats_engine = NewRelic::Agent.agent.stats_engine
130
- stats_engine.record_metrics(metric_names) do |stats|
142
+ stats_engine.record_unscoped_metrics(state, metric_names) do |stats|
131
143
  stats.increment_count
132
144
  end
133
145
  end
134
146
 
135
- # whether we should return early from the notice_error process
136
- # - based on whether the error is ignored or the error
137
- # collector is disabled
138
- def should_exit_notice_error?(exception)
139
- if enabled?
140
- if !error_is_ignored?(exception)
141
- return exception.nil? # exit early if the exception is nil
142
- end
143
- end
144
- # disabled or an ignored error, per above
145
- true
147
+ def skip_notice_error?(exception)
148
+ disabled? || error_is_ignored?(exception) || exception.nil?
146
149
  end
147
150
 
148
151
  # acts just like Hash#fetch, but deletes the key from the hash
@@ -204,12 +207,6 @@ module NewRelic
204
207
  object.send(method) if object.respond_to?(method)
205
208
  end
206
209
 
207
- # extracts source from the exception, if the exception supports
208
- # that method
209
- def extract_source(exception)
210
- sense_method(exception, 'source_extract') if @capture_source
211
- end
212
-
213
210
  # extracts a stack trace from the exception for debugging purposes
214
211
  def extract_stack_trace(exception)
215
212
  actual_exception = sense_method(exception, 'original_exception') || exception
@@ -223,7 +220,6 @@ module NewRelic
223
220
  {
224
221
  :file_name => sense_method(exception, 'file_name'),
225
222
  :line_number => sense_method(exception, 'line_number'),
226
- :source => extract_source(exception),
227
223
  :stack_trace => extract_stack_trace(exception)
228
224
  }
229
225
  end
@@ -231,7 +227,7 @@ module NewRelic
231
227
  # checks the size of the error queue to make sure we are under
232
228
  # the maximum limit, and logs a warning if we are over the limit.
233
229
  def over_queue_limit?(message)
234
- over_limit = (@errors.reject{|err| err.exception_class_constant < NewRelic::Agent::InternalAgentError}.length >= MAX_ERROR_QUEUE_LENGTH)
230
+ over_limit = (@errors.reject{|err| err.is_internal}.length >= MAX_ERROR_QUEUE_LENGTH)
235
231
  ::NewRelic::Agent.logger.warn("The error reporting queue has reached #{MAX_ERROR_QUEUE_LENGTH}. The error detail for this and subsequent errors will not be transmitted to New Relic until the queued errors have been sent: #{message}") if over_limit
236
232
  over_limit
237
233
  end
@@ -262,7 +258,7 @@ module NewRelic
262
258
  # If anything is left over, it's added to custom params
263
259
  # If exception is nil, the error count is bumped and no traced error is recorded
264
260
  def notice_error(exception, options={})
265
- return if should_exit_notice_error?(exception)
261
+ return if skip_notice_error?(exception)
266
262
  increment_error_count!(exception, options)
267
263
  NewRelic::Agent.instance.events.notify(:notice_error, exception, options)
268
264
  action_path = fetch_from_options(options, :metric, "")
@@ -290,7 +286,7 @@ module NewRelic
290
286
 
291
287
  @lock.synchronize do
292
288
  # Already seen this class once? Bail!
293
- return if @errors.any? { |err| err.exception_class_constant == exception.class }
289
+ return if @errors.any? { |err| err.exception_class_name == exception.class.name }
294
290
 
295
291
  trace = exception.backtrace || caller.dup
296
292
  noticed_error = NewRelic::NoticedError.new("NewRelic/AgentError",
@@ -23,7 +23,7 @@ module NewRelic
23
23
  end
24
24
 
25
25
  def on_transaction(*_)
26
- return unless restart_in_children_enabled? && needs_restart?
26
+ return unless restart_in_children_enabled? && needs_restart? && harvest_thread_enabled?
27
27
 
28
28
  needs_thread_start = false
29
29
  @lock.synchronize do
@@ -48,6 +48,10 @@ module NewRelic
48
48
  NewRelic::Agent.config[:restart_thread_in_children]
49
49
  end
50
50
 
51
+ def harvest_thread_enabled?
52
+ !NewRelic::Agent.config[:disable_harvest_thread]
53
+ end
54
+
51
55
  def restart_harvest_thread
52
56
  # Daemonize reports thread as still alive when it isn't... whack!
53
57
  NewRelic::Agent.instance.instance_variable_set(:@worker_thread, nil)
@@ -0,0 +1,17 @@
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
+ module NewRelic
6
+ module Agent
7
+ module Hostname
8
+ def self.get
9
+ if (dyno_name = ENV['DYNO']) && ::NewRelic::Agent.config[:use_heroku_dyno_names]
10
+ dyno_name
11
+ else
12
+ Socket.gethostname
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -32,7 +32,7 @@ module NewRelic
32
32
  end
33
33
 
34
34
  def uri
35
- @uri ||= URI( @curlobj.url )
35
+ @uri ||= NewRelic::Agent::HTTPClients::URIUtil.parse_url(@curlobj.url)
36
36
  end
37
37
  end
38
38
 
@@ -40,7 +40,7 @@ module NewRelic
40
40
  @request = request
41
41
  @uri = case request.url
42
42
  when ::URI then request.url
43
- else ::URI.parse(request.url.to_s)
43
+ else NewRelic::Agent::HTTPClients::URIUtil.parse_url(request.url)
44
44
  end
45
45
  end
46
46
 
@@ -23,6 +23,19 @@ module NewRelic
23
23
  filtered.to_s
24
24
  end
25
25
 
26
+ # There are valid URI strings that some HTTP client libraries will
27
+ # accept that the stdlib URI module doesn't handle. If we find that
28
+ # Addressable is around, use that to normalize out our URL's.
29
+ def self.parse_url(url)
30
+ if defined?(::Addressable::URI)
31
+ address = ::Addressable::URI.parse(url)
32
+ address.normalize!
33
+ URI.parse(address.to_s)
34
+ else
35
+ URI.parse(url)
36
+ end
37
+ end
38
+
26
39
  end
27
40
  end
28
41
  end
@@ -7,43 +7,33 @@ module NewRelic
7
7
  module Agent
8
8
  module Instrumentation
9
9
  class ActionControllerSubscriber < EventedSubscriber
10
- def initialize
11
- super
12
- NewRelic::Agent.instance.events.subscribe(:before_call) do |env|
13
-
14
- request = begin
15
- require 'rack'
16
- ::Rack::Request.new(env)
17
- rescue => e
18
- Agent.logger.debug("Error creating Rack::Request object: #{e}")
19
- nil
20
- end
21
- TransactionState.request = request
22
- end
23
- end
24
10
 
25
- def start(name, id, payload)
26
- request = TransactionState.get.request
11
+ def start(name, id, payload) #THREAD_LOCAL_ACCESS
12
+ state = TransactionState.tl_get
13
+ request = state.request
27
14
  event = ControllerEvent.new(name, Time.now, nil, id, payload, request)
28
15
  push_event(event)
29
16
 
30
- if NewRelic::Agent.is_execution_traced? && !event.ignored?
31
- start_transaction(event)
17
+ if state.is_execution_traced? && !event.ignored?
18
+ start_transaction(state, event)
32
19
  else
33
20
  # if this transaction is ignored, make sure child
34
21
  # transaction are also ignored
22
+ state.current_transaction.ignore! if state.current_transaction
35
23
  NewRelic::Agent.instance.push_trace_execution_flag(false)
36
24
  end
37
25
  rescue => e
38
26
  log_notification_error(e, name, 'start')
39
27
  end
40
28
 
41
- def finish(name, id, payload)
29
+ def finish(name, id, payload) #THREAD_LOCAL_ACCESS
42
30
  event = pop_event(id)
43
31
  event.payload.merge!(payload)
44
32
 
45
- if NewRelic::Agent.is_execution_traced? && !event.ignored?
46
- stop_transaction(event)
33
+ state = TransactionState.tl_get
34
+
35
+ if state.is_execution_traced? && !event.ignored?
36
+ stop_transaction(state, event)
47
37
  else
48
38
  Agent.instance.pop_trace_execution_flag
49
39
  end
@@ -51,19 +41,19 @@ module NewRelic
51
41
  log_notification_error(e, name, 'finish')
52
42
  end
53
43
 
54
- def start_transaction(event)
55
- Transaction.start(:controller,
44
+ def start_transaction(state, event)
45
+ Transaction.start(state, :controller,
56
46
  :request => event.request,
57
47
  :filtered_params => filter(event.payload[:params]),
58
48
  :apdex_start_time => event.queue_start,
59
49
  :transaction_name => event.metric_name)
60
50
  end
61
51
 
62
- def stop_transaction(event)
63
- Transaction.stop(Time.now,
64
- :exception_encountered => event.exception_encountered?,
65
- :ignore_apdex => event.apdex_ignored?,
66
- :ignore_enduser => event.enduser_ignored?)
52
+ def stop_transaction(state, event)
53
+ txn = state.current_transaction
54
+ txn.ignore_apdex! if event.apdex_ignored?
55
+ txn.ignore_enduser! if event.enduser_ignored?
56
+ Transaction.stop(state)
67
57
  end
68
58
 
69
59
  def filter(params)
@@ -113,10 +103,6 @@ module NewRelic
113
103
  _is_filtered?('ignore_enduser')
114
104
  end
115
105
 
116
- def exception_encountered?
117
- payload[:exception]
118
- end
119
-
120
106
  # FIXME: shamelessly ripped from ControllerInstrumentation
121
107
  def _is_filtered?(key)
122
108
  if @controller_class.respond_to? :newrelic_read_attr
@@ -9,38 +9,38 @@ module NewRelic
9
9
  module Agent
10
10
  module Instrumentation
11
11
  class ActionViewSubscriber < EventedSubscriber
12
- def start(name, id, payload)
12
+ def start(name, id, payload) #THREAD_LOCAL_ACCESS
13
13
  event = RenderEvent.new(name, Time.now, nil, id, payload)
14
14
  push_event(event)
15
15
 
16
- if NewRelic::Agent.is_execution_traced? && event.recordable?
17
- event.frame = NewRelic::Agent::TracedMethodStack.push_frame(:action_view, event.time)
16
+ state = NewRelic::Agent::TransactionState.tl_get
17
+
18
+ if state.is_execution_traced? && event.recordable?
19
+ stack = state.traced_method_stack
20
+ event.frame = stack.push_frame(state, :action_view, event.time)
18
21
  end
19
22
  rescue => e
20
23
  log_notification_error(e, name, 'start')
21
24
  end
22
25
 
23
- def finish(name, id, payload)
26
+ def finish(name, id, payload) #THREAD_LOCAL_ACCESS
24
27
  event = pop_event(id)
25
28
 
26
- if NewRelic::Agent.is_execution_traced? && event.recordable?
27
- frame = NewRelic::Agent::TracedMethodStack.pop_frame(event.frame, event.metric_name, event.end)
29
+ state = NewRelic::Agent::TransactionState.tl_get
30
+
31
+ if state.is_execution_traced? && event.recordable?
32
+ stack = state.traced_method_stack
33
+ frame = stack.pop_frame(state, event.frame, event.metric_name, event.end)
28
34
  record_metrics(event, frame)
29
35
  end
30
36
  rescue => e
31
37
  log_notification_error(e, name, 'finish')
32
38
  end
33
39
 
34
- def record_metrics(event, frame)
40
+ def record_metrics(event, frame) #THREAD_LOCAL_ACCESS
35
41
  exclusive = event.duration - frame.children_time
36
- metric_specs = [
37
- NewRelic::MetricSpec.new(event.metric_name),
38
- NewRelic::MetricSpec.new(event.metric_name, StatsEngine::MetricStats::SCOPE_PLACEHOLDER)
39
- ]
40
- NewRelic::Agent.instance.stats_engine \
41
- .record_metrics_internal(metric_specs,
42
- event.duration,
43
- exclusive)
42
+ NewRelic::Agent.instance.stats_engine.tl_record_scoped_and_unscoped_metrics(
43
+ event.metric_name, nil, event.duration, exclusive)
44
44
  end
45
45
 
46
46
  class RenderEvent < Event