ghazel-newrelic_rpm 3.1.0.1 → 3.4.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (175) hide show
  1. data/CHANGELOG +120 -35
  2. data/LICENSE +29 -2
  3. data/README.rdoc +2 -2
  4. data/bin/mongrel_rpm +0 -0
  5. data/bin/newrelic +0 -0
  6. data/bin/newrelic_cmd +0 -0
  7. data/lib/new_relic/agent.rb +50 -38
  8. data/lib/new_relic/agent/agent.rb +459 -337
  9. data/lib/new_relic/agent/beacon_configuration.rb +71 -11
  10. data/lib/new_relic/agent/browser_monitoring.rb +73 -14
  11. data/lib/new_relic/agent/busy_calculator.rb +11 -3
  12. data/lib/new_relic/agent/chained_call.rb +2 -2
  13. data/lib/new_relic/agent/database.rb +223 -0
  14. data/lib/new_relic/agent/error_collector.rb +231 -183
  15. data/lib/new_relic/agent/instrumentation.rb +2 -2
  16. data/lib/new_relic/agent/instrumentation/active_merchant.rb +10 -2
  17. data/lib/new_relic/agent/instrumentation/active_record.rb +138 -0
  18. data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +7 -1
  19. data/lib/new_relic/agent/instrumentation/authlogic.rb +6 -0
  20. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +46 -14
  21. data/lib/new_relic/agent/instrumentation/data_mapper.rb +8 -2
  22. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +11 -3
  23. data/lib/new_relic/agent/instrumentation/memcache.rb +49 -25
  24. data/lib/new_relic/agent/instrumentation/merb/controller.rb +7 -2
  25. data/lib/new_relic/agent/instrumentation/merb/errors.rb +7 -1
  26. data/lib/new_relic/agent/instrumentation/metric_frame.rb +31 -4
  27. data/lib/new_relic/agent/instrumentation/metric_frame/pop.rb +1 -5
  28. data/lib/new_relic/agent/instrumentation/net.rb +8 -2
  29. data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +5 -2
  30. data/lib/new_relic/agent/instrumentation/queue_time.rb +1 -1
  31. data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +66 -35
  32. data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +7 -1
  33. data/lib/new_relic/agent/instrumentation/rails/errors.rb +7 -1
  34. data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +121 -1
  35. data/lib/new_relic/agent/instrumentation/rails3/errors.rb +7 -1
  36. data/lib/new_relic/agent/instrumentation/rainbows_instrumentation.rb +21 -0
  37. data/lib/new_relic/agent/instrumentation/resque.rb +80 -0
  38. data/lib/new_relic/agent/instrumentation/sinatra.rb +46 -20
  39. data/lib/new_relic/agent/instrumentation/sunspot.rb +6 -0
  40. data/lib/new_relic/agent/instrumentation/unicorn_instrumentation.rb +7 -2
  41. data/lib/new_relic/agent/method_tracer.rb +205 -99
  42. data/lib/new_relic/agent/new_relic_service.rb +221 -0
  43. data/lib/new_relic/agent/pipe_channel_manager.rb +161 -0
  44. data/lib/new_relic/agent/pipe_service.rb +54 -0
  45. data/lib/new_relic/agent/samplers/delayed_job_sampler.rb +89 -0
  46. data/lib/new_relic/agent/samplers/memory_sampler.rb +6 -7
  47. data/lib/new_relic/agent/shim_agent.rb +5 -5
  48. data/lib/new_relic/agent/sql_sampler.rb +282 -0
  49. data/lib/new_relic/agent/stats_engine.rb +2 -0
  50. data/lib/new_relic/agent/stats_engine/gc_profiler.rb +123 -0
  51. data/lib/new_relic/agent/stats_engine/metric_stats.rb +35 -30
  52. data/lib/new_relic/agent/stats_engine/samplers.rb +10 -4
  53. data/lib/new_relic/agent/stats_engine/transactions.rb +28 -87
  54. data/lib/new_relic/agent/transaction_info.rb +74 -0
  55. data/lib/new_relic/agent/transaction_sample_builder.rb +18 -3
  56. data/lib/new_relic/agent/transaction_sampler.rb +108 -20
  57. data/lib/new_relic/agent/worker_loop.rb +14 -6
  58. data/lib/new_relic/collection_helper.rb +19 -11
  59. data/lib/new_relic/command.rb +1 -1
  60. data/lib/new_relic/commands/deployments.rb +2 -2
  61. data/lib/new_relic/commands/install.rb +2 -13
  62. data/lib/new_relic/control.rb +2 -3
  63. data/lib/new_relic/control/class_methods.rb +12 -6
  64. data/lib/new_relic/control/configuration.rb +57 -8
  65. data/lib/new_relic/control/frameworks.rb +10 -0
  66. data/lib/new_relic/control/frameworks/external.rb +4 -4
  67. data/lib/new_relic/control/frameworks/merb.rb +2 -1
  68. data/lib/new_relic/control/frameworks/rails.rb +35 -22
  69. data/lib/new_relic/control/frameworks/rails3.rb +12 -7
  70. data/lib/new_relic/control/frameworks/ruby.rb +5 -5
  71. data/lib/new_relic/control/frameworks/sinatra.rb +1 -4
  72. data/lib/new_relic/control/instance_methods.rb +38 -12
  73. data/lib/new_relic/control/instrumentation.rb +23 -4
  74. data/lib/new_relic/control/logging_methods.rb +70 -15
  75. data/lib/new_relic/control/server_methods.rb +22 -9
  76. data/lib/new_relic/delayed_job_injection.rb +16 -3
  77. data/lib/new_relic/helper.rb +21 -0
  78. data/lib/new_relic/language_support.rb +95 -0
  79. data/lib/new_relic/local_environment.rb +92 -48
  80. data/lib/new_relic/metric_data.rb +7 -2
  81. data/lib/new_relic/metric_spec.rb +12 -9
  82. data/lib/new_relic/noticed_error.rb +6 -1
  83. data/lib/new_relic/rack/browser_monitoring.rb +18 -19
  84. data/lib/new_relic/rack/developer_mode.rb +3 -2
  85. data/lib/new_relic/recipes.rb +8 -4
  86. data/lib/new_relic/stats.rb +17 -60
  87. data/lib/new_relic/transaction_analysis.rb +2 -1
  88. data/lib/new_relic/transaction_analysis/segment_summary.rb +4 -2
  89. data/lib/new_relic/transaction_sample.rb +60 -75
  90. data/lib/new_relic/transaction_sample/segment.rb +31 -79
  91. data/lib/new_relic/version.rb +2 -2
  92. data/lib/newrelic_rpm.rb +1 -1
  93. data/newrelic.yml +2 -2
  94. data/newrelic_rpm.gemspec +46 -54
  95. data/test/active_record_fixtures.rb +3 -3
  96. data/test/config/newrelic.yml +1 -1
  97. data/test/fixtures/proc_cpuinfo.txt +575 -0
  98. data/test/new_relic/agent/agent/connect_test.rb +128 -25
  99. data/test/new_relic/agent/agent/start_test.rb +9 -94
  100. data/test/new_relic/agent/agent/start_worker_thread_test.rb +2 -4
  101. data/test/new_relic/agent/agent_test.rb +51 -78
  102. data/test/new_relic/agent/agent_test_controller.rb +1 -1
  103. data/test/new_relic/agent/agent_test_controller_test.rb +49 -33
  104. data/test/new_relic/agent/beacon_configuration_test.rb +12 -5
  105. data/test/new_relic/agent/browser_monitoring_test.rb +99 -50
  106. data/test/new_relic/agent/database_test.rb +161 -0
  107. data/test/new_relic/agent/error_collector_test.rb +47 -23
  108. data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +96 -42
  109. data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +0 -2
  110. data/test/new_relic/agent/instrumentation/instrumentation_test.rb +1 -1
  111. data/test/new_relic/agent/instrumentation/metric_frame/pop_test.rb +3 -11
  112. data/test/new_relic/agent/instrumentation/net_instrumentation_test.rb +9 -9
  113. data/test/new_relic/agent/instrumentation/queue_time_test.rb +6 -11
  114. data/test/new_relic/agent/memcache_instrumentation_test.rb +54 -18
  115. data/test/new_relic/agent/method_tracer/class_methods/add_method_tracer_test.rb +1 -1
  116. data/test/new_relic/agent/method_tracer/instance_methods/trace_execution_scoped_test.rb +1 -1
  117. data/test/new_relic/agent/method_tracer_test.rb +3 -2
  118. data/test/new_relic/agent/new_relic_service_test.rb +151 -0
  119. data/test/new_relic/agent/pipe_channel_manager_test.rb +114 -0
  120. data/test/new_relic/agent/pipe_service_test.rb +113 -0
  121. data/test/new_relic/agent/rpm_agent_test.rb +4 -31
  122. data/test/new_relic/agent/sql_sampler_test.rb +192 -0
  123. data/test/new_relic/agent/stats_engine/metric_stats_test.rb +19 -18
  124. data/test/new_relic/agent/stats_engine_test.rb +41 -6
  125. data/test/new_relic/agent/transaction_info_test.rb +13 -0
  126. data/test/new_relic/agent/transaction_sample_builder_test.rb +27 -4
  127. data/test/new_relic/agent/transaction_sampler_test.rb +68 -46
  128. data/test/new_relic/agent/worker_loop_test.rb +3 -3
  129. data/test/new_relic/agent_test.rb +242 -0
  130. data/test/new_relic/collection_helper_test.rb +50 -28
  131. data/test/new_relic/control/configuration_test.rb +77 -0
  132. data/test/new_relic/control/logging_methods_test.rb +49 -21
  133. data/test/new_relic/control_test.rb +115 -54
  134. data/test/new_relic/delayed_job_injection_test.rb +21 -0
  135. data/test/new_relic/fake_collector.rb +210 -0
  136. data/test/new_relic/fake_service.rb +44 -0
  137. data/test/new_relic/local_environment_test.rb +14 -1
  138. data/test/new_relic/metric_parser/metric_parser_test.rb +11 -0
  139. data/test/new_relic/rack/browser_monitoring_test.rb +84 -23
  140. data/test/new_relic/rack/developer_mode_helper_test.rb +141 -0
  141. data/test/new_relic/rack/developer_mode_test.rb +31 -0
  142. data/test/new_relic/stats_test.rb +3 -18
  143. data/test/new_relic/transaction_analysis/segment_summary_test.rb +14 -0
  144. data/test/new_relic/transaction_analysis_test.rb +3 -3
  145. data/test/new_relic/transaction_sample/segment_test.rb +15 -80
  146. data/test/new_relic/transaction_sample_test.rb +25 -18
  147. data/test/script/build_test_gem.sh +51 -0
  148. data/test/script/ci.sh +140 -0
  149. data/test/script/ci_agent-tests_runner.sh +82 -0
  150. data/test/script/ci_bench.sh +52 -0
  151. data/test/script/ci_multiverse_runner.sh +63 -0
  152. data/test/test_contexts.rb +1 -0
  153. data/test/test_helper.rb +18 -5
  154. data/ui/helpers/developer_mode_helper.rb +14 -8
  155. data/ui/helpers/google_pie_chart.rb +0 -1
  156. data/ui/views/newrelic/index.rhtml +2 -2
  157. data/vendor/gems/dependency_detection-0.0.1.build/LICENSE +4 -18
  158. data/vendor/gems/dependency_detection-0.0.1.build/lib/dependency_detection.rb +10 -0
  159. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/mem_cache.rb +11 -11
  160. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/metric_parser.rb +17 -4
  161. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/view.rb +4 -0
  162. metadata +50 -36
  163. data/lib/new_relic/agent/instrumentation/rails/active_record_instrumentation.rb +0 -108
  164. data/lib/new_relic/agent/instrumentation/rails3/active_record_instrumentation.rb +0 -112
  165. data/lib/new_relic/agent/samplers/delayed_job_lock_sampler.rb +0 -40
  166. data/lib/new_relic/data_serialization.rb +0 -84
  167. data/lib/new_relic/histogram.rb +0 -91
  168. data/lib/new_relic/rack/metric_app.rb +0 -65
  169. data/lib/new_relic/rack/mongrel_rpm.ru +0 -28
  170. data/lib/new_relic/rack/newrelic.yml +0 -27
  171. data/lib/new_relic/rack_app.rb +0 -6
  172. data/test/new_relic/data_serialization_test.rb +0 -70
  173. data/vendor/gems/dependency_detection-0.0.1.build/README +0 -0
  174. data/vendor/gems/metric_parser-0.1.0.pre1/LICENSE +0 -0
  175. data/vendor/gems/metric_parser-0.1.0.pre1/README +0 -0
@@ -0,0 +1,138 @@
1
+ module NewRelic
2
+ module Agent
3
+ module Instrumentation
4
+ module ActiveRecord
5
+ def self.included(instrumented_class)
6
+ instrumented_class.class_eval do
7
+ unless instrumented_class.method_defined?(:log_without_newrelic_instrumentation)
8
+ alias_method :log_without_newrelic_instrumentation, :log
9
+ alias_method :log, :log_with_newrelic_instrumentation
10
+ protected :log
11
+ end
12
+ end
13
+ end
14
+
15
+ def log_with_newrelic_instrumentation(*args, &block)
16
+ if !NewRelic::Agent.is_execution_traced?
17
+ return log_without_newrelic_instrumentation(*args, &block)
18
+ end
19
+
20
+ sql, name, binds = args
21
+ metric = metric_for_name(NewRelic::Helper.correctly_encoded(name)) ||
22
+ metric_for_sql(NewRelic::Helper.correctly_encoded(sql))
23
+
24
+ if !metric
25
+ log_without_newrelic_instrumentation(*args, &block)
26
+ else
27
+ metrics = [metric, remote_service_metric].compact
28
+ metrics += rollup_metrics_for(metric)
29
+ self.class.trace_execution_scoped(metrics) do
30
+ t0 = Time.now
31
+ begin
32
+ log_without_newrelic_instrumentation(*args, &block)
33
+ ensure
34
+ elapsed_time = (Time.now - t0).to_f
35
+ NewRelic::Agent.instance.transaction_sampler.notice_sql(sql,
36
+ @config, elapsed_time)
37
+ NewRelic::Agent.instance.sql_sampler.notice_sql(sql, metric,
38
+ @config, elapsed_time)
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ def remote_service_metric
45
+ if @config && @config[:adapter]
46
+ type = @config[:adapter].sub(/\d*/, '')
47
+ host = @config[:host] || 'localhost'
48
+ "RemoteService/sql/#{type}/#{host}"
49
+ end
50
+ end
51
+
52
+ def metric_for_name(name)
53
+ if name && (parts = name.split " ") && parts.size == 2
54
+ model = parts.first
55
+ operation = parts.last.downcase
56
+ op_name = case operation
57
+ when 'load', 'count', 'exists' then 'find'
58
+ when 'indexes', 'columns' then nil # fall back to DirectSQL
59
+ when 'destroy', 'find', 'save', 'create' then operation
60
+ when 'update' then 'save'
61
+ else
62
+ if model == 'Join'
63
+ operation
64
+ end
65
+ end
66
+ "ActiveRecord/#{model}/#{op_name}" if op_name
67
+ end
68
+ end
69
+
70
+ def metric_for_sql(sql)
71
+ metric = NewRelic::Agent::Instrumentation::MetricFrame.database_metric_name
72
+ if metric.nil?
73
+ if sql =~ /^(select|update|insert|delete|show)/i
74
+ # Could not determine the model/operation so let's find a better
75
+ # metric. If it doesn't match the regex, it's probably a show
76
+ # command or some DDL which we'll ignore.
77
+ metric = "Database/SQL/#{$1.downcase}"
78
+ else
79
+ metric = "Database/SQL/other"
80
+ end
81
+ end
82
+ metric
83
+ end
84
+
85
+ def rollup_metrics_for(metric)
86
+ metrics = ["ActiveRecord/all"]
87
+ metrics << "ActiveRecord/#{$1}" if metric =~ /ActiveRecord\/\w+\/(\w+)/
88
+ metrics
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ DependencyDetection.defer do
96
+ @name = :active_record
97
+
98
+ depends_on do
99
+ defined?(ActiveRecord) && defined?(ActiveRecord::Base)
100
+ end
101
+
102
+ depends_on do
103
+ !NewRelic::Control.instance['skip_ar_instrumentation']
104
+ end
105
+
106
+ depends_on do
107
+ !NewRelic::Control.instance['disable_activerecord_instrumentation']
108
+ end
109
+
110
+ executes do
111
+ NewRelic::Agent.logger.debug 'Installing ActiveRecord instrumentation'
112
+ end
113
+
114
+ executes do
115
+ if defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 3
116
+ Rails.configuration.after_initialize do
117
+ insert_instrumentation
118
+ end
119
+ else
120
+ insert_instrumentation
121
+ end
122
+ end
123
+
124
+ def insert_instrumentation
125
+ ActiveRecord::ConnectionAdapters::AbstractAdapter.module_eval do
126
+ include ::NewRelic::Agent::Instrumentation::ActiveRecord
127
+ end
128
+
129
+ ActiveRecord::Base.class_eval do
130
+ class << self
131
+ add_method_tracer(:find_by_sql, 'ActiveRecord/#{self.name}/find_by_sql',
132
+ :metric => false)
133
+ add_method_tracer(:transaction, 'ActiveRecord/#{self.name}/transaction',
134
+ :metric => false)
135
+ end
136
+ end
137
+ end
138
+ end
@@ -18,6 +18,8 @@ module NewRelic
18
18
  end
19
19
 
20
20
  DependencyDetection.defer do
21
+ @name = :acts_as_solr
22
+
21
23
  depends_on do
22
24
  defined?(ActsAsSolr)
23
25
  end
@@ -33,7 +35,11 @@ DependencyDetection.defer do
33
35
  depends_on do
34
36
  defined?(ActsAsSolr::CommonMethods)
35
37
  end
36
-
38
+
39
+ executes do
40
+ NewRelic::Agent.logger.debug 'Installing ActsAsSolr instrumentation'
41
+ end
42
+
37
43
  executes do
38
44
  ActsAsSolr::ParserMethods.module_eval do
39
45
  include NewRelic::Instrumentation::ActsAsSolrInstrumentation::ParserMethodsInstrumentation
@@ -1,10 +1,16 @@
1
1
  DependencyDetection.defer do
2
+ @name = :authlogic
3
+
2
4
  depends_on do
3
5
  defined?(AuthLogic) &&
4
6
  defined?(AuthLogic::Session) &&
5
7
  defined?(AuthLogic::Session::Base)
6
8
  end
7
9
 
10
+ executes do
11
+ NewRelic::Agent.logger.debug 'Installing AuthLogic instrumentation'
12
+ end
13
+
8
14
  executes do
9
15
  AuthLogic::Session::Base.class_eval do
10
16
  add_method_tracer :find, 'Custom/Authlogic/find'
@@ -138,15 +138,17 @@ module NewRelic
138
138
  end
139
139
  options_arg << %Q[:#{key} => #{valuestr}]
140
140
  end
141
+ traced_method, punctuation = method.to_s.sub(/([?!=])$/, ''), $1
142
+
141
143
  class_eval <<-EOC
142
- def #{method.to_s}_with_newrelic_transaction_trace(*args, &block)
144
+ def #{traced_method.to_s}_with_newrelic_transaction_trace#{punctuation}(*args, &block)
143
145
  perform_action_with_newrelic_trace(#{options_arg.join(',')}) do
144
- #{method.to_s}_without_newrelic_transaction_trace(*args, &block)
146
+ #{traced_method.to_s}_without_newrelic_transaction_trace#{punctuation}(*args, &block)
145
147
  end
146
148
  end
147
149
  EOC
148
- alias_method "#{method.to_s}_without_newrelic_transaction_trace", method.to_s
149
- alias_method method.to_s, "#{method.to_s}_with_newrelic_transaction_trace"
150
+ alias_method "#{traced_method.to_s}_without_newrelic_transaction_trace#{punctuation}", method.to_s
151
+ alias_method method.to_s, "#{traced_method.to_s}_with_newrelic_transaction_trace#{punctuation}"
150
152
  NewRelic::Control.instance.log.debug("Traced transaction: class = #{self.name}, method = #{method.to_s}, options = #{options.inspect}")
151
153
  end
152
154
  end
@@ -231,6 +233,8 @@ module NewRelic
231
233
  # If a single argument is passed in, it is treated as a metric
232
234
  # path. This form is deprecated.
233
235
  def perform_action_with_newrelic_trace(*args, &block)
236
+ request = newrelic_request(args)
237
+ NewRelic::Agent::TransactionInfo.reset(request)
234
238
 
235
239
  # Skip instrumentation based on the value of 'do_not_trace' and if
236
240
  # we aren't calling directly with a block.
@@ -254,7 +258,7 @@ module NewRelic
254
258
  else
255
259
  perform_action_without_newrelic_trace(*args)
256
260
  end
257
- rescue Exception => e
261
+ rescue => e
258
262
  frame_data.notice_error(e)
259
263
  raise
260
264
  end
@@ -270,24 +274,48 @@ module NewRelic
270
274
  end
271
275
 
272
276
  protected
277
+
278
+ def newrelic_request(args)
279
+ opts = args.first
280
+ # passed as a parameter to add_transaction_tracer
281
+ if opts.respond_to?(:keys) && opts.respond_to?(:[]) && opts[:request]
282
+ opts[:request]
283
+ # in a Rack app
284
+ elsif opts.respond_to?(:keys) && opts.respond_to?(:[]) &&
285
+ opts['rack.version']
286
+ Rack::Request.new(args)
287
+ # in a Rails app
288
+ elsif self.respond_to?(:request)
289
+ self.request
290
+ end
291
+ end
292
+
273
293
  # Should be implemented in the dispatcher class
274
294
  def newrelic_response_code; end
275
295
 
276
296
  def newrelic_request_headers
277
297
  self.respond_to?(:request) && self.request.respond_to?(:headers) && self.request.headers
278
298
  end
279
-
299
+
300
+ # overrideable method to determine whether to trace an action
301
+ # or not - you may override this in your controller and supply
302
+ # your own logic for ignoring transactions.
280
303
  def do_not_trace?
281
304
  _is_filtered?('do_not_trace')
282
305
  end
283
-
306
+
307
+ # overrideable method to determine whether to trace an action
308
+ # for purposes of apdex measurement - you can use this to
309
+ # ignore things like api calls or other fast non-user-facing
310
+ # actions
284
311
  def ignore_apdex?
285
312
  _is_filtered?('ignore_apdex')
286
313
  end
287
314
 
288
315
  private
289
316
 
290
- # Profile the instrumented call. Dev mode only. Experimental.
317
+ # Profile the instrumented call. Dev mode only. Experimental
318
+ # - should definitely not be used on production applications
291
319
  def perform_action_with_newrelic_profile(args)
292
320
  frame_data = _push_metric_frame(block_given? ? args : [])
293
321
  val = nil
@@ -332,7 +360,9 @@ module NewRelic
332
360
  available_params = self.respond_to?(:params) ? self.params : {}
333
361
  end
334
362
  frame_data.request ||= self.request if self.respond_to? :request
335
- frame_data.push(category + '/'+ path)
363
+ transaction_name = category + '/' + path
364
+ frame_data.push(transaction_name)
365
+ NewRelic::Agent::TransactionInfo.get.transaction_name = transaction_name
336
366
  frame_data.filtered_params = (respond_to? :filter_parameters) ? filter_parameters(available_params) : available_params
337
367
  frame_data
338
368
  end
@@ -351,14 +381,15 @@ module NewRelic
351
381
  end
352
382
  unless path = options[:path]
353
383
  action = options[:name] || args.first
354
- metric_class = options[:class_name] || (self.is_a?(Class) ? self.name : self.class.name)
384
+ metric_class = options[:class_name] || ((self.is_a?(Class)||self.is_a?(Module)) ? self.name : self.class.name)
355
385
  path = metric_class
356
386
  path += ('/' + action) if action
357
387
  end
358
388
  [category, path, params]
359
389
  end
360
390
 
361
- # Filter out
391
+ # Filter out a request if it matches one of our parameters for
392
+ # ignoring it - the key is either 'do_not_trace' or 'ignore_apdex'
362
393
  def _is_filtered?(key)
363
394
  ignore_actions = self.class.newrelic_read_attr(key) if self.class.respond_to? :newrelic_read_attr
364
395
  case ignore_actions
@@ -394,15 +425,16 @@ module NewRelic
394
425
  queue_start = nil
395
426
  if newrelic_request_headers
396
427
  queue_start = parse_frontend_headers(newrelic_request_headers)
397
- Thread.current[:newrelic_queue_time] = (now.to_f - queue_start.to_f) if queue_start
398
428
  end
399
429
  queue_start || now
400
- rescue Exception => e
430
+ rescue => e
401
431
  NewRelic::Control.instance.log.error("Error detecting upstream wait time: #{e}")
402
432
  NewRelic::Control.instance.log.debug("#{e.backtrace[0..20]}")
403
433
  now
404
434
  end
405
-
435
+
436
+ # returns the NewRelic::MethodTraceStats object associated
437
+ # with the dispatcher time measurement
406
438
  def _dispatch_stat
407
439
  NewRelic::Agent.agent.stats_engine.get_stats_no_scope 'HttpDispatcher'
408
440
  end
@@ -38,6 +38,8 @@
38
38
  # towards scope) so they don't show up ine normal call graph/trace.
39
39
 
40
40
  DependencyDetection.defer do
41
+ @name = :data_mapper
42
+
41
43
  depends_on do
42
44
  defined?(::DataMapper)
43
45
  end
@@ -53,7 +55,11 @@ DependencyDetection.defer do
53
55
  depends_on do
54
56
  defined?(DataMapper::Collection)
55
57
  end
56
-
58
+
59
+ executes do
60
+ NewRelic::Agent.logger.debug 'Installing DataMapper instrumentation'
61
+ end
62
+
57
63
  executes do
58
64
  DataMapper::Model.class_eval do
59
65
  add_method_tracer :get, 'ActiveRecord/#{self.name}/get'
@@ -191,7 +197,7 @@ module NewRelic
191
197
  # the proper call scope.
192
198
  def log_with_newrelic_instrumentation(msg)
193
199
  return unless NewRelic::Agent.is_execution_traced?
194
- return unless operation = case msg.query
200
+ return unless operation = case NewRelic::Helper.correctly_encoded(msg.query)
195
201
  when /^\s*select/i then 'find'
196
202
  when /^\s*(update|insert)/i then 'save'
197
203
  when /^\s*delete/i then 'destroy'
@@ -1,18 +1,26 @@
1
1
  require 'new_relic/agent/instrumentation/controller_instrumentation'
2
2
 
3
3
  DependencyDetection.defer do
4
+ @name = :delayed_job
5
+
4
6
  depends_on do
5
7
  !NewRelic::Control.instance['disable_dj']
6
8
  end
7
9
 
8
10
  depends_on do
9
- defined?(::Delayed) && defined?(::Delayed::Job)
11
+ # double check because of old JRuby bug
12
+ defined?(::Delayed) && defined?(::Delayed::Job) &&
13
+ Delayed::Job.method_defined?(:invoke_job)
10
14
  end
11
-
15
+
16
+ executes do
17
+ NewRelic::Agent.logger.debug 'Installing DelayedJob instrumentation'
18
+ end
19
+
12
20
  executes do
13
21
  Delayed::Job.class_eval do
14
22
  include NewRelic::Agent::Instrumentation::ControllerInstrumentation
15
- if self.instance_methods.include?('name')
23
+ if self.instance_methods.include?('name') || self.instance_methods.include?(:name)
16
24
  add_transaction_tracer "invoke_job", :category => 'OtherTransaction/DelayedJob', :path => '#{self.name}'
17
25
  else
18
26
  add_transaction_tracer "invoke_job", :category => 'OtherTransaction/DelayedJob'
@@ -10,24 +10,26 @@ module NewRelic
10
10
  module Instrumentation
11
11
  module Memcache
12
12
  module_function
13
- def instrument_method(the_class, method_name)
14
- return unless the_class.method_defined? method_name.to_sym
15
- the_class.class_eval <<-EOD
16
- def #{method_name}_with_newrelic_trace(*args)
17
- metrics = ["MemCache/#{method_name}",
18
- (NewRelic::Agent::Instrumentation::MetricFrame.recording_web_transaction? ? 'MemCache/allWeb' : 'MemCache/allOther')]
19
- self.class.trace_execution_scoped(metrics) do
20
- t0 = Time.now
21
- begin
22
- #{method_name}_without_newrelic_trace(*args)
23
- ensure
24
- #{memcache_key_snippet(method_name)}
25
- end
26
- end
27
- end
28
- alias #{method_name}_without_newrelic_trace #{method_name}
29
- alias #{method_name} #{method_name}_with_newrelic_trace
30
- EOD
13
+ def instrument_methods(the_class, method_names)
14
+ method_names.each do |method_name|
15
+ next unless the_class.method_defined? method_name.to_sym
16
+ the_class.class_eval <<-EOD
17
+ def #{method_name}_with_newrelic_trace(*args, &block)
18
+ metrics = ["Memcache/#{method_name}",
19
+ (NewRelic::Agent::Instrumentation::MetricFrame.recording_web_transaction? ? 'Memcache/allWeb' : 'Memcache/allOther')]
20
+ self.class.trace_execution_scoped(metrics) do
21
+ t0 = Time.now
22
+ begin
23
+ #{method_name}_without_newrelic_trace(*args, &block)
24
+ ensure
25
+ #{memcache_key_snippet(method_name)}
26
+ end
27
+ end
28
+ end
29
+ alias #{method_name}_without_newrelic_trace #{method_name}
30
+ alias #{method_name} #{method_name}_with_newrelic_trace
31
+ EOD
32
+ end
31
33
  end
32
34
  def memcache_key_snippet(method_name)
33
35
  return "" unless NewRelic::Control.instance['capture_memcache_keys']
@@ -38,19 +40,41 @@ module NewRelic
38
40
  end
39
41
  end
40
42
 
41
-
42
-
43
-
44
43
  DependencyDetection.defer do
44
+ @name = :memcache
45
+
45
46
  depends_on do
46
47
  !NewRelic::Control.instance['disable_memcache_instrumentation']
47
48
  end
48
49
 
50
+ depends_on do
51
+ defined?(::MemCache) || defined?(::Memcached) ||
52
+ defined?(::Dalli::Client) || defined?(::Spymemcached)
53
+ end
54
+
49
55
  executes do
50
- %w[get get_multi set add incr decr delete replace append prepend cas].each do | method_name |
51
- NewRelic::Agent::Instrumentation::Memcache.instrument_method(::MemCache, method_name) if defined? ::MemCache
52
- NewRelic::Agent::Instrumentation::Memcache.instrument_method(::Memcached, method_name) if defined? ::Memcached
53
- NewRelic::Agent::Instrumentation::Memcache.instrument_method(::Dalli::Client, method_name) if defined? ::Dalli::Client
56
+ commands = %w[get get_multi set add incr decr delete replace append prepend]
57
+ if defined? ::MemCache
58
+ NewRelic::Agent::Instrumentation::Memcache.instrument_methods(::MemCache,
59
+ commands)
60
+ NewRelic::Agent.logger.debug 'Installing MemCache instrumentation'
61
+ end
62
+ if defined? ::Memcached
63
+ commands << 'cas'
64
+ NewRelic::Agent::Instrumentation::Memcache.instrument_methods(::Memcached,
65
+ commands)
66
+ NewRelic::Agent.logger.debug 'Installing Memcached instrumentation'
67
+ end
68
+ if defined? ::Dalli::Client
69
+ NewRelic::Agent::Instrumentation::Memcache.instrument_methods(::Dalli::Client,
70
+ commands)
71
+ NewRelic::Agent.logger.debug 'Installing Dalli Memcache instrumentation'
72
+ end
73
+ if defined? ::Spymemcached
74
+ commands << 'multiget'
75
+ NewRelic::Agent::Instrumentation::Memcache.instrument_methods(::Spymemcached,
76
+ commands)
77
+ NewRelic::Agent.logger.debug 'Installing Spymemcached instrumentation'
54
78
  end
55
79
  end
56
80
  end