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
@@ -291,7 +291,7 @@ module NewRelic
291
291
  data, size, serialize_finish_ts = nil
292
292
  begin
293
293
  data = @marshaller.dump(args)
294
- rescue => e
294
+ rescue StandardError, SystemStackError => e
295
295
  handle_serialization_error(method, e)
296
296
  end
297
297
  serialize_finish_ts = Time.now
@@ -149,7 +149,7 @@ module NewRelic
149
149
  def start
150
150
  return if @started == true
151
151
  @started = true
152
- @thread = NewRelic::Agent::Threading::AgentThread.new('Pipe Channel Manager') do
152
+ @thread = NewRelic::Agent::Threading::AgentThread.create('Pipe Channel Manager') do
153
153
  now = nil
154
154
  loop do
155
155
  clean_up_pipes
@@ -229,8 +229,8 @@ module NewRelic
229
229
  Marshal.load(data)
230
230
  end
231
231
  rescue StandardError => e
232
- msg = "#{e.class.name} '#{e.message}' trying to load #{Base64.encode64(data)}"
233
- ::NewRelic::Agent.logger.debug(msg)
232
+ ::NewRelic::Agent.logger.error "Failure unmarshalling message from Resque child process", e
233
+ ::NewRelic::Agent.logger.debug Base64.encode64(data)
234
234
  nil
235
235
  end
236
236
 
@@ -77,7 +77,7 @@ class NewRelic::Agent::RequestSampler
77
77
  end
78
78
  end
79
79
 
80
- def record_sampling_rate(request_count, sample_count)
80
+ def record_sampling_rate(request_count, sample_count) #THREAD_LOCAL_ACCESS
81
81
  request_count_lifetime = @samples.seen_lifetime
82
82
  sample_count_lifetime = @samples.captured_lifetime
83
83
  NewRelic::Agent.logger.debug("Sampled %d / %d (%.1f %%) requests this cycle, %d / %d (%.1f %%) since startup" % [
@@ -90,8 +90,8 @@ class NewRelic::Agent::RequestSampler
90
90
  ])
91
91
 
92
92
  engine = NewRelic::Agent.instance.stats_engine
93
- engine.record_supportability_metric_count("RequestSampler/requests", request_count)
94
- engine.record_supportability_metric_count("RequestSampler/samples", sample_count)
93
+ engine.tl_record_supportability_metric_count("RequestSampler/requests", request_count)
94
+ engine.tl_record_supportability_metric_count("RequestSampler/samples", sample_count)
95
95
  end
96
96
 
97
97
  def register_config_callbacks
@@ -125,11 +125,10 @@ class NewRelic::Agent::RequestSampler
125
125
  def self.map_metric(metric_name, to_add={})
126
126
  to_add.values.each(&:freeze)
127
127
 
128
- spec = ::NewRelic::MetricSpec.new(metric_name)
129
- mappings = OVERVIEW_SPECS.fetch(spec, {})
128
+ mappings = OVERVIEW_SPECS.fetch(metric_name, {})
130
129
  mappings.merge!(to_add)
131
130
 
132
- OVERVIEW_SPECS[spec] = mappings
131
+ OVERVIEW_SPECS[metric_name] = mappings
133
132
  end
134
133
 
135
134
  OVERVIEW_SPECS = {}
@@ -154,12 +153,12 @@ class NewRelic::Agent::RequestSampler
154
153
  map_metric('External/allOther', :total_call_time => "externalDuration")
155
154
  map_metric('External/allOther', :call_count => "externalCallCount")
156
155
 
157
- def extract_metrics(stats_hash)
156
+ def extract_metrics(txn_metrics)
158
157
  result = {}
159
- if stats_hash
160
- OVERVIEW_SPECS.each do |(metric_spec, extracted_values)|
161
- if stats_hash.has_key?(metric_spec)
162
- stat = stats_hash[metric_spec]
158
+ if txn_metrics
159
+ OVERVIEW_SPECS.each do |(name, extracted_values)|
160
+ if txn_metrics.has_key?(name)
161
+ stat = txn_metrics[name]
163
162
  extracted_values.each do |value_name, key_name|
164
163
  result[key_name] = stat.send(value_name)
165
164
  end
@@ -49,7 +49,7 @@ module NewRelic
49
49
  end
50
50
  end
51
51
 
52
- def record_gc_runs_metric(snapshot, txn_count)
52
+ def record_gc_runs_metric(snapshot, txn_count) #THREAD_LOCAL_ACCESS
53
53
  if snapshot.gc_total_time || snapshot.gc_runs
54
54
  if snapshot.gc_total_time
55
55
  gc_time = snapshot.gc_total_time - @last_snapshot.gc_total_time.to_f
@@ -58,7 +58,7 @@ module NewRelic
58
58
  gc_runs = snapshot.gc_runs - @last_snapshot.gc_runs
59
59
  end
60
60
  wall_clock_time = snapshot.taken_at - @last_snapshot.taken_at
61
- NewRelic::Agent.agent.stats_engine.record_metrics(GC_RUNS_METRIC) do |stats|
61
+ NewRelic::Agent.agent.stats_engine.tl_record_unscoped_metrics(GC_RUNS_METRIC) do |stats|
62
62
  stats.call_count += txn_count
63
63
  stats.total_call_time += gc_runs if gc_runs
64
64
  stats.total_exclusive_time += gc_time if gc_time
@@ -68,19 +68,19 @@ module NewRelic
68
68
  end
69
69
  end
70
70
 
71
- def record_delta(snapshot, key, metric, txn_count)
71
+ def record_delta(snapshot, key, metric, txn_count) #THREAD_LOCAL_ACCESS
72
72
  value = snapshot.send(key)
73
73
  if value
74
74
  delta = value - @last_snapshot.send(key)
75
- NewRelic::Agent.agent.stats_engine.record_metrics(metric) do |stats|
75
+ NewRelic::Agent.agent.stats_engine.tl_record_unscoped_metrics(metric) do |stats|
76
76
  stats.call_count += txn_count
77
77
  stats.total_call_time += delta
78
78
  end
79
79
  end
80
80
  end
81
81
 
82
- def record_gauge_metric(metric_name, value)
83
- NewRelic::Agent.agent.stats_engine.record_metrics(metric_name) do |stats|
82
+ def record_gauge_metric(metric_name, value) #THREAD_LOCAL_ACCESS
83
+ NewRelic::Agent.agent.stats_engine.tl_record_unscoped_metrics(metric_name) do |stats|
84
84
  stats.call_count = value
85
85
  stats.sum_of_squares = 1
86
86
  end
@@ -11,6 +11,7 @@ module NewRelic
11
11
  def self.instance
12
12
  @instance ||= self.new
13
13
  end
14
+
14
15
  def initialize
15
16
  super
16
17
  @stats_engine.extend NewRelic::Agent::StatsEngine::Shim
@@ -18,6 +19,7 @@ module NewRelic
18
19
  @sql_sampler.extend NewRelic::Agent::SqlSampler::Shim
19
20
  @error_collector.extend NewRelic::Agent::ErrorCollector::Shim
20
21
  end
22
+
21
23
  def after_fork *args; end
22
24
  def start *args; end
23
25
  def shutdown *args; end
@@ -25,7 +27,6 @@ module NewRelic
25
27
  def push_trace_execution_flag *args; end
26
28
  def pop_trace_execution_flag *args; end
27
29
  def browser_timing_header; "" end
28
- def browser_timing_config; "" end
29
30
  def browser_timing_footer; "" end
30
31
  end
31
32
  end
@@ -11,6 +11,21 @@ require 'new_relic/control'
11
11
 
12
12
  module NewRelic
13
13
  module Agent
14
+ # This class contains the logic of recording slow SQL traces, which may
15
+ # represent multiple aggregated SQL queries.
16
+ #
17
+ # A slow SQL trace consists of a collection of SQL instrumented SQL queries
18
+ # that all normalize to the same text. For example, the following two
19
+ # queries would be aggregated together into a single slow SQL trace:
20
+ #
21
+ # SELECT * FROM table WHERE id=42
22
+ # SELECT * FROM table WHERE id=1234
23
+ #
24
+ # Each slow SQL trace keeps track of the number of times the same normalized
25
+ # query was seen, the min, max, and total time spent executing those
26
+ # queries, and an example backtrace from one of the aggregated queries.
27
+ #
28
+ # @api public
14
29
  class SqlSampler
15
30
 
16
31
  # Module defining methods stubbed out when the agent is disabled
@@ -26,7 +41,6 @@ module NewRelic
26
41
 
27
42
  def initialize
28
43
  @sql_traces = {}
29
- clear_transaction_data
30
44
 
31
45
  # This lock is used to synchronize access to @sql_traces
32
46
  # and related variables. It can become necessary on JRuby or
@@ -41,31 +55,26 @@ module NewRelic
41
55
  Agent.config[:'transaction_tracer.enabled']
42
56
  end
43
57
 
44
- def on_start_transaction(start_time, uri=nil, params={})
45
- TransactionState.get.sql_sampler_transaction_data = TransactionSqlData.new
58
+ def on_start_transaction(state, start_time, uri=nil)
59
+ state.sql_sampler_transaction_data = TransactionSqlData.new
46
60
 
47
- if NewRelic::Agent.instance.transaction_sampler.builder
48
- guid = NewRelic::Agent.instance.transaction_sampler.builder.sample.guid
61
+ if state.transaction_sample_builder
62
+ guid = state.transaction_sample_builder.sample.guid
49
63
  end
50
64
 
51
- if Agent.config[:'slow_sql.enabled'] && transaction_data
52
- transaction_data.set_transaction_info(uri, params, guid)
65
+ if Agent.config[:'slow_sql.enabled'] && state.sql_sampler_transaction_data
66
+ state.sql_sampler_transaction_data.set_transaction_info(uri, guid)
53
67
  end
54
68
  end
55
69
 
56
- def transaction_data
57
- TransactionState.get.sql_sampler_transaction_data
58
- end
59
-
60
- def clear_transaction_data
61
- TransactionState.get.sql_sampler_transaction_data = nil
70
+ def tl_transaction_data # only used for testing
71
+ TransactionState.tl_get.sql_sampler_transaction_data
62
72
  end
63
73
 
64
74
  # This is called when we are done with the transaction.
65
- def on_finishing_transaction(name, time=Time.now)
66
- data = transaction_data
75
+ def on_finishing_transaction(state, name, time=Time.now)
76
+ data = state.sql_sampler_transaction_data
67
77
  data.set_transaction_name(name)
68
- clear_transaction_data
69
78
 
70
79
  if data.sql_data.size > 0
71
80
  @samples_lock.synchronize do
@@ -91,14 +100,33 @@ module NewRelic
91
100
  end
92
101
  end
93
102
 
94
- def notice_sql(sql, metric_name, config, duration, &explainer)
95
- return unless transaction_data
96
- if NewRelic::Agent.is_sql_recorded?
103
+ # Records an SQL query, potentially creating a new slow SQL trace, or
104
+ # aggregating the query into an existing slow SQL trace.
105
+ #
106
+ # This method should be used only by gem authors wishing to extend
107
+ # the Ruby agent to instrument new database interfaces - it should
108
+ # generally not be called directly from application code.
109
+ #
110
+ # @param sql [String] the SQL query being recorded
111
+ # @param metric_name [String] is the metric name under which this query will be recorded
112
+ # @param config [Object] is the driver configuration for the connection
113
+ # @param duration [Float] number of seconds the query took to execute
114
+ # @param explainer [Proc] for internal use only - 3rd-party clients must
115
+ # not pass this parameter.
116
+ #
117
+ # @api public
118
+ #
119
+ def notice_sql(sql, metric_name, config, duration, state=nil, &explainer) #THREAD_LOCAL_ACCESS sometimes
120
+ state ||= TransactionState.tl_get
121
+ data = state.sql_sampler_transaction_data
122
+ return unless data
123
+
124
+ if state.is_sql_recorded?
97
125
  if duration > Agent.config[:'slow_sql.explain_threshold']
98
126
  backtrace = caller.join("\n")
99
- transaction_data.sql_data << SlowSql.new(Database.capture_query(sql),
100
- metric_name, config,
101
- duration, backtrace, &explainer)
127
+ data.sql_data << SlowSql.new(Database.capture_query(sql),
128
+ metric_name, config,
129
+ duration, backtrace, &explainer)
102
130
  end
103
131
  end
104
132
  end
@@ -138,7 +166,6 @@ module NewRelic
138
166
  class TransactionSqlData
139
167
  attr_reader :path
140
168
  attr_reader :uri
141
- attr_reader :params
142
169
  attr_reader :sql_data
143
170
  attr_reader :guid
144
171
 
@@ -146,9 +173,8 @@ module NewRelic
146
173
  @sql_data = []
147
174
  end
148
175
 
149
- def set_transaction_info(uri, params, guid)
176
+ def set_transaction_info(uri, guid)
150
177
  @uri = uri
151
- @params = params
152
178
  @guid = guid
153
179
  end
154
180
 
@@ -205,7 +231,7 @@ module NewRelic
205
231
 
206
232
  def initialize(normalized_query, slow_sql, path, uri)
207
233
  super()
208
- @params = {} #FIXME
234
+ @params = {}
209
235
  @sql_id = consistent_hash(normalized_query)
210
236
  set_primary slow_sql, path, uri
211
237
  record_data_point(float(slow_sql.duration))
@@ -217,7 +243,6 @@ module NewRelic
217
243
  @database_metric_name = slow_sql.metric_name
218
244
  @path = path
219
245
  @url = uri
220
- # FIXME
221
246
  @params[:backtrace] = slow_sql.backtrace if slow_sql.backtrace
222
247
  end
223
248
 
@@ -33,20 +33,18 @@ module NewRelic
33
33
  stats.merge!(other_stats)
34
34
  end
35
35
 
36
- def merge!(other_stats)
37
- Array(other_stats).each do |other|
38
- @min_call_time = other.min_call_time if min_time_less?(other)
39
- @max_call_time = other.max_call_time if other.max_call_time > max_call_time
40
- @total_call_time += other.total_call_time
41
- @total_exclusive_time += other.total_exclusive_time
42
- @sum_of_squares += other.sum_of_squares
43
- @call_count += other.call_count
44
- end
36
+ def merge!(other)
37
+ @min_call_time = other.min_call_time if min_time_less?(other)
38
+ @max_call_time = other.max_call_time if other.max_call_time > max_call_time
39
+ @total_call_time += other.total_call_time
40
+ @total_exclusive_time += other.total_exclusive_time
41
+ @sum_of_squares += other.sum_of_squares
42
+ @call_count += other.call_count
45
43
  self
46
44
  end
47
45
 
48
46
  def to_s
49
- "[#{'%2i' % call_count.to_i} calls #{'%.4f' % total_call_time.to_f}s]"
47
+ "[#{'%2i' % call_count.to_i} calls #{'%.4f' % total_call_time.to_f}s / #{'%.4f' % total_exclusive_time.to_f}s ex]"
50
48
  end
51
49
 
52
50
  def to_json(*_)
@@ -60,6 +58,22 @@ module NewRelic
60
58
  }.to_json(*_)
61
59
  end
62
60
 
61
+ def record(value=nil, aux=nil, &blk)
62
+ if blk
63
+ yield self
64
+ else
65
+ case value
66
+ when Numeric
67
+ aux ||= value
68
+ self.record_data_point(value, aux)
69
+ when :apdex_s, :apdex_t, :apdex_f
70
+ self.record_apdex(value, aux)
71
+ when NewRelic::Agent::Stats
72
+ self.merge!(value)
73
+ end
74
+ end
75
+ end
76
+
63
77
  # record a single data point into the statistical gatherer. The gatherer
64
78
  # will aggregate all data points collected over a specified period and upload
65
79
  # its data to the NewRelic server
@@ -45,8 +45,8 @@ module NewRelic
45
45
  end
46
46
  end
47
47
 
48
- def self.record_gc_metric(call_count, elapsed)
49
- NewRelic::Agent.agent.stats_engine.record_metrics(gc_metric_specs) do |stats|
48
+ def self.record_gc_metric(call_count, elapsed) #THREAD_LOCAL_ACCESS
49
+ NewRelic::Agent.agent.stats_engine.tl_record_scoped_and_unscoped_metrics(gc_metric_name, GC_ROLLUP) do |stats|
50
50
  stats.call_count += call_count
51
51
  stats.total_call_time += elapsed
52
52
  stats.total_exclusive_time += elapsed
@@ -57,23 +57,11 @@ module NewRelic
57
57
  GC_OTHER = 'GC/Transaction/allOther'.freeze
58
58
  GC_WEB = 'GC/Transaction/allWeb'.freeze
59
59
 
60
- SCOPE_PLACEHOLDER = NewRelic::Agent::StatsEngine::MetricStats::SCOPE_PLACEHOLDER
61
-
62
- GC_ROLLUP_SPEC = NewRelic::MetricSpec.new(GC_ROLLUP)
63
- GC_OTHER_SPEC = NewRelic::MetricSpec.new(GC_OTHER)
64
- GC_OTHER_SCOPED_SPEC = NewRelic::MetricSpec.new(GC_OTHER, SCOPE_PLACEHOLDER)
65
- GC_WEB_SPEC = NewRelic::MetricSpec.new(GC_WEB)
66
- GC_WEB_SCOPED_SPEC = NewRelic::MetricSpec.new(GC_WEB, SCOPE_PLACEHOLDER)
67
-
68
- def self.gc_metric_specs
69
- # The .dup call on the scoped MetricSpec here is necessary because
70
- # metric specs with non-empty scopes will have their scopes mutated
71
- # when the metrics are merged into the global stats hash, and we don't
72
- # want to mutate the original MetricSpec.
60
+ def self.gc_metric_name
73
61
  if NewRelic::Agent::Transaction.recording_web_transaction?
74
- [GC_ROLLUP_SPEC, GC_WEB_SPEC, GC_WEB_SCOPED_SPEC.dup]
62
+ GC_WEB
75
63
  else
76
- [GC_ROLLUP_SPEC, GC_OTHER_SPEC, GC_OTHER_SCOPED_SPEC.dup]
64
+ GC_OTHER
77
65
  end
78
66
  end
79
67
 
@@ -9,58 +9,127 @@ module NewRelic
9
9
  class StatsEngine
10
10
  # Handles methods related to actual Metric collection
11
11
  module MetricStats
12
- SCOPE_PLACEHOLDER = :__SCOPE__
12
+ SCOPE_PLACEHOLDER = '__SCOPE__'.freeze
13
13
 
14
- # Lookup and write to the named metric in a single call.
14
+ # Update the unscoped metrics given in metric_names.
15
+ # metric_names may be either a single name, or an array of names.
15
16
  #
16
- # This method is thead-safe, and is preferred to the lookup / modify
17
- # method pairs (e.g. get_stats + record_data_point)
17
+ # This is an internal method, subject to change at any time. Client apps
18
+ # and gems should use the public API (NewRelic::Agent.record_metric)
19
+ # instead.
20
+ #
21
+ # There are four ways to use this method:
22
+ #
23
+ # 1. With a numeric value, it will update the Stats objects associated
24
+ # with the given metrics by calling record_data_point(value, aux).
25
+ # aux will be treated in this case as the exclusive time associated
26
+ # with the call being recorded.
27
+ #
28
+ # 2. With a value of :apdex_s, :apdex_t, or :apdex_f, it will treat the
29
+ # associated stats as an Apdex metric, updating it to reflect the
30
+ # occurrence of a transaction falling into the given category.
31
+ # The aux value in this case should be the apdex threshold used in
32
+ # bucketing the request.
33
+ #
34
+ # 3. If a block is given, value and aux will be ignored, and instead the
35
+ # Stats object associated with each named unscoped metric will be
36
+ # yielded to the block for customized update logic.
37
+ #
38
+ # 4. If value is a Stats instance, it will be merged into the Stats
39
+ # associated with each named unscoped metric.
40
+ #
41
+ # If this method is called during a transaction, the metrics will be
42
+ # attached to the Transaction, and not merged into the global set until
43
+ # the end of the transaction.
44
+ #
45
+ # Otherwise, the metrics will be recorded directly into the global set
46
+ # of metrics, under a lock.
18
47
  #
19
48
  # @api private
20
- def record_metrics(metric_names_or_specs, value=nil, options={}, &blk)
21
- scoped = options[:scoped]
22
- scope = in_transaction? ? SCOPE_PLACEHOLDER : nil
23
- effective_scope = scoped && scope
24
-
25
- specs = coerce_to_metric_spec_array(metric_names_or_specs, effective_scope)
49
+ #
50
+ def tl_record_unscoped_metrics(metric_names, value=nil, aux=nil, &blk)
51
+ state = NewRelic::Agent::TransactionState.tl_get
52
+ record_unscoped_metrics(state, metric_names, value, aux, &blk)
53
+ end
26
54
 
27
- if in_transaction?
28
- transaction_stats_hash.record(specs, value, &blk)
55
+ def record_unscoped_metrics(state, metric_names, value=nil, aux=nil, &blk)
56
+ txn = state.current_transaction
57
+ if txn
58
+ txn.metrics.record_unscoped(metric_names, value, aux, &blk)
29
59
  else
60
+ specs = coerce_to_metric_spec_array(metric_names, nil)
30
61
  with_stats_lock do
31
- @stats_hash.record(specs, value, &blk)
62
+ @stats_hash.record(specs, value, aux, &blk)
32
63
  end
33
64
  end
34
65
  end
35
66
 
36
- # Fast-path version of the #record_metrics version above, used in
37
- # performance-sensitive code paths
67
+ # Like tl_record_unscoped_metrics, but records a scoped metric as well.
38
68
  #
39
- # metric_specs must be an Array of MetricSpec objects
40
- # value and aux are passed directly to the corresponding parameters of
41
- # StatsHash#record
69
+ # This is an internal method, subject to change at any time. Client apps
70
+ # and gems should use the public API (NewRelic::Agent.record_metric)
71
+ # instead.
72
+ #
73
+ # The given scoped_metric will be recoded as both a scoped *and* an
74
+ # unscoped metric. The summary_metrics will be recorded as unscoped
75
+ # metrics only.
76
+ #
77
+ # If called during a transaction, all metrics will be attached to the
78
+ # Transaction, and not merged into the global set of metrics until the
79
+ # end of the transaction.
80
+ #
81
+ # If called outside of a transaction, only the *unscoped* metrics will
82
+ # be recorded, directly into the global set of metrics (under a lock).
42
83
  #
43
84
  # @api private
44
- def record_metrics_internal(metric_specs, value, aux)
45
- tsh = transaction_stats_hash
46
- if tsh
47
- tsh.record(metric_specs, value, aux)
85
+ #
86
+ def tl_record_scoped_and_unscoped_metrics(scoped_metric, summary_metrics=nil, value=nil, aux=nil, &blk)
87
+ state = NewRelic::Agent::TransactionState.tl_get
88
+ record_scoped_and_unscoped_metrics(state, scoped_metric, summary_metrics, value, aux, &blk)
89
+ end
90
+
91
+ def record_scoped_and_unscoped_metrics(state, scoped_metric, summary_metrics=nil, value=nil, aux=nil, &blk)
92
+ txn = state.current_transaction
93
+ if txn
94
+ txn.metrics.record_scoped(scoped_metric, value, aux, &blk)
95
+ txn.metrics.record_unscoped(scoped_metric, value, aux, &blk)
96
+ if summary_metrics
97
+ txn.metrics.record_unscoped(summary_metrics, value, aux, &blk)
98
+ end
48
99
  else
100
+ specs = coerce_to_metric_spec_array(scoped_metric, nil)
101
+ if summary_metrics
102
+ specs.concat(coerce_to_metric_spec_array(summary_metrics, nil))
103
+ end
49
104
  with_stats_lock do
50
- @stats_hash.record(metric_specs, value, aux)
105
+ @stats_hash.record(specs, value, aux, &blk)
51
106
  end
52
107
  end
53
108
  end
54
109
 
55
- # a simple accessor for looking up a stat with no scope -
56
- # returns a new stats object if no stats object for that
57
- # metric exists yet
110
+ # This method is deprecated and not thread safe, and should not be used
111
+ # by any new client code. Use NewRelic::Agent.record_metric instead.
112
+ #
113
+ # Lookup the Stats object for a given unscoped metric, returning a new
114
+ # Stats object if one did not exist previously.
115
+ #
116
+ # @api public
117
+ # @deprecated
118
+ #
58
119
  def get_stats_no_scope(metric_name)
59
120
  get_stats(metric_name, false)
60
121
  end
61
122
 
62
- # If scoped_metric_only is true, only a scoped metric is created (used by rendering metrics which by definition are per controller only)
123
+ # This method is deprecated and not thread safe, and should not be used
124
+ # by any new client code. Use NewRelic::Agent.record_metric instead.
125
+ #
126
+ # If scoped_metric_only is true, only a scoped metric is created (used
127
+ # by rendering metrics which by definition are per controller only)
63
128
  # Leaving second, unused parameter for compatibility
129
+ #
130
+ # @api public
131
+ # @deprecated
132
+ #
64
133
  def get_stats(metric_name, _ = true, scoped_metric_only = false, scope = nil)
65
134
  stats = nil
66
135
  with_stats_lock do
@@ -81,8 +150,7 @@ module NewRelic
81
150
  stats
82
151
  end
83
152
 
84
- # Returns a stat if one exists, otherwise returns nil. If you
85
- # want auto-initialization, use one of get_stats or get_stats_no_scope
153
+ # Returns a stat if one exists, otherwise returns nil.
86
154
  def lookup_stats(metric_name, scope_name = '')
87
155
  spec = NewRelic::MetricSpec.new(metric_name, scope_name)
88
156
  with_stats_lock do
@@ -90,29 +158,11 @@ module NewRelic
90
158
  end
91
159
  end
92
160
 
93
- # Helper method for timing supportability metrics
94
- def record_supportability_metric_timed(metric)
95
- start_time = Time.now
96
- yield
97
- ensure
98
- duration = (Time.now - start_time).to_f
99
- record_supportability_metric(metric, duration)
100
- end
101
-
102
161
  # Helper for recording a straight value into the count
103
- def record_supportability_metric_count(metric, value)
104
- record_supportability_metric(metric) do |stat|
105
- stat.call_count = value
106
- end
107
- end
108
-
109
- # Helper method for recording supportability metrics consistently
110
- def record_supportability_metric(metric, value=nil)
162
+ def tl_record_supportability_metric_count(metric, value)
111
163
  real_name = "Supportability/#{metric}"
112
- if block_given?
113
- record_metrics(real_name) { |stat| yield stat }
114
- else
115
- record_metrics(real_name, value)
164
+ tl_record_unscoped_metrics(real_name) do |stat|
165
+ stat.call_count = value
116
166
  end
117
167
  end
118
168
 
@@ -136,6 +186,12 @@ module NewRelic
136
186
  end
137
187
  end
138
188
 
189
+ def merge_transaction_metrics!(txn_metrics, scope)
190
+ with_stats_lock do
191
+ @stats_hash.merge_transaction_metrics!(txn_metrics, scope)
192
+ end
193
+ end
194
+
139
195
  def harvest!
140
196
  now = Time.now
141
197
  snapshot = reset!
@@ -187,14 +243,6 @@ module NewRelic
187
243
  def metric_specs
188
244
  with_stats_lock { @stats_hash.keys }
189
245
  end
190
-
191
- def in_transaction?
192
- !!transaction_stats_hash
193
- end
194
-
195
- def transaction_stats_hash
196
- Transaction.current && Transaction.current.stats_hash
197
- end
198
246
  end
199
247
  end
200
248
  end