newrelic_rpm 3.1.2 → 3.2.0.beta1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of newrelic_rpm might be problematic. Click here for more details.

Files changed (69) hide show
  1. data/CHANGELOG +9 -0
  2. data/lib/new_relic/agent.rb +12 -3
  3. data/lib/new_relic/agent/agent.rb +99 -97
  4. data/lib/new_relic/agent/database.rb +203 -0
  5. data/lib/new_relic/agent/instrumentation/active_merchant.rb +2 -0
  6. data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +2 -0
  7. data/lib/new_relic/agent/instrumentation/authlogic.rb +2 -0
  8. data/lib/new_relic/agent/instrumentation/data_mapper.rb +2 -0
  9. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +2 -0
  10. data/lib/new_relic/agent/instrumentation/memcache.rb +23 -13
  11. data/lib/new_relic/agent/instrumentation/merb/controller.rb +2 -1
  12. data/lib/new_relic/agent/instrumentation/merb/errors.rb +2 -0
  13. data/lib/new_relic/agent/instrumentation/metric_frame.rb +7 -1
  14. data/lib/new_relic/agent/instrumentation/metric_frame/pop.rb +1 -0
  15. data/lib/new_relic/agent/instrumentation/net.rb +2 -0
  16. data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +2 -0
  17. data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +63 -36
  18. data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +2 -0
  19. data/lib/new_relic/agent/instrumentation/rails/active_record_instrumentation.rb +5 -2
  20. data/lib/new_relic/agent/instrumentation/rails/errors.rb +4 -2
  21. data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +56 -2
  22. data/lib/new_relic/agent/instrumentation/rails3/active_record_instrumentation.rb +5 -2
  23. data/lib/new_relic/agent/instrumentation/rails3/errors.rb +3 -1
  24. data/lib/new_relic/agent/instrumentation/sunspot.rb +2 -0
  25. data/lib/new_relic/agent/instrumentation/unicorn_instrumentation.rb +2 -1
  26. data/lib/new_relic/agent/shim_agent.rb +1 -0
  27. data/lib/new_relic/agent/sql_sampler.rb +230 -0
  28. data/lib/new_relic/agent/stats_engine/transactions.rb +10 -0
  29. data/lib/new_relic/agent/transaction_sampler.rb +11 -6
  30. data/lib/new_relic/collection_helper.rb +7 -4
  31. data/lib/new_relic/commands/deployments.rb +1 -1
  32. data/lib/new_relic/commands/install.rb +2 -13
  33. data/lib/new_relic/control/class_methods.rb +4 -3
  34. data/lib/new_relic/control/configuration.rb +21 -0
  35. data/lib/new_relic/control/frameworks/rails.rb +1 -1
  36. data/lib/new_relic/control/logging_methods.rb +17 -6
  37. data/lib/new_relic/delayed_job_injection.rb +1 -1
  38. data/lib/new_relic/local_environment.rb +8 -14
  39. data/lib/new_relic/rack/developer_mode.rb +1 -0
  40. data/lib/new_relic/stats.rb +1 -0
  41. data/lib/new_relic/transaction_sample.rb +5 -60
  42. data/lib/new_relic/transaction_sample/segment.rb +7 -82
  43. data/lib/new_relic/version.rb +3 -3
  44. data/newrelic_rpm.gemspec +8 -3
  45. data/test/new_relic/agent/agent/connect_test.rb +95 -0
  46. data/test/new_relic/agent/agent/start_test.rb +0 -85
  47. data/test/new_relic/agent/agent/start_worker_thread_test.rb +1 -0
  48. data/test/new_relic/agent/agent_test.rb +0 -73
  49. data/test/new_relic/agent/browser_monitoring_test.rb +1 -1
  50. data/test/new_relic/agent/database_test.rb +160 -0
  51. data/test/new_relic/agent/instrumentation/metric_frame/pop_test.rb +3 -0
  52. data/test/new_relic/agent/memcache_instrumentation_test.rb +14 -15
  53. data/test/new_relic/agent/sql_sampler_test.rb +135 -0
  54. data/test/new_relic/agent/transaction_sampler_test.rb +12 -3
  55. data/test/new_relic/collection_helper_test.rb +4 -4
  56. data/test/new_relic/control/configuration_test.rb +31 -0
  57. data/test/new_relic/control/logging_methods_test.rb +20 -4
  58. data/test/new_relic/delayed_job_injection_test.rb +1 -1
  59. data/test/new_relic/rack/developer_mode_helper_test.rb +141 -0
  60. data/test/new_relic/stats_test.rb +3 -3
  61. data/test/new_relic/transaction_sample/segment_test.rb +4 -92
  62. data/test/new_relic/transaction_sample_test.rb +1 -1
  63. data/test/test_helper.rb +1 -1
  64. data/ui/helpers/developer_mode_helper.rb +14 -8
  65. data/ui/helpers/google_pie_chart.rb +0 -1
  66. data/vendor/gems/dependency_detection-0.0.1.build/lib/dependency_detection.rb +5 -0
  67. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/mem_cache.rb +11 -11
  68. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/view.rb +4 -0
  69. metadata +15 -10
@@ -1,4 +1,6 @@
1
1
  DependencyDetection.defer do
2
+ @name = :active_merchant
3
+
2
4
  depends_on do
3
5
  defined?(ActiveMerchant) && defined?(ActiveMerchant::Billing)
4
6
  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
@@ -1,4 +1,6 @@
1
1
  DependencyDetection.defer do
2
+ @name = :authlogic
3
+
2
4
  depends_on do
3
5
  defined?(AuthLogic) &&
4
6
  defined?(AuthLogic::Session) &&
@@ -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
@@ -1,6 +1,8 @@
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
@@ -15,8 +15,8 @@ module NewRelic
15
15
  next unless the_class.method_defined? method_name.to_sym
16
16
  the_class.class_eval <<-EOD
17
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')]
18
+ metrics = ["Memcache/#{method_name}",
19
+ (NewRelic::Agent::Instrumentation::MetricFrame.recording_web_transaction? ? 'Memcache/allWeb' : 'Memcache/allOther')]
20
20
  self.class.trace_execution_scoped(metrics) do
21
21
  t0 = Time.now
22
22
  begin
@@ -41,30 +41,40 @@ module NewRelic
41
41
  end
42
42
 
43
43
  DependencyDetection.defer do
44
+ @name = :memcache
45
+
44
46
  depends_on do
45
47
  !NewRelic::Control.instance['disable_memcache_instrumentation']
46
48
  end
47
-
48
- executes do
49
- NewRelic::Agent.logger.debug 'Installing Memcached instrumentation'
49
+
50
+ depends_on do
51
+ defined?(::MemCache) || defined?(::Memcached) ||
52
+ defined?(::Dalli::Client) || defined?(::Spymemcached)
50
53
  end
51
-
54
+
52
55
  executes do
53
56
  commands = %w[get get_multi set add incr decr delete replace append prepend]
54
57
  if defined? ::MemCache
55
58
  NewRelic::Agent::Instrumentation::Memcache.instrument_methods(::MemCache,
56
- commands)
57
- elsif defined? ::Memcached
59
+ commands)
60
+ NewRelic::Agent.logger.debug 'Installing MemCache instrumentation'
61
+ end
62
+ if defined? ::Memcached
58
63
  commands << 'cas'
59
64
  NewRelic::Agent::Instrumentation::Memcache.instrument_methods(::Memcached,
60
- commands)
61
- elsif defined? ::Dalli::Client
65
+ commands)
66
+ NewRelic::Agent.logger.debug 'Installing Memcached instrumentation'
67
+ end
68
+ if defined? ::Dalli::Client
62
69
  NewRelic::Agent::Instrumentation::Memcache.instrument_methods(::Dalli::Client,
63
- commands)
64
- elsif defined? ::Spymemcached
70
+ commands)
71
+ NewRelic::Agent.logger.debug 'Installing Dalli Memcache instrumentation'
72
+ end
73
+ if defined? ::Spymemcached
65
74
  commands << 'multiget'
66
75
  NewRelic::Agent::Instrumentation::Memcache.instrument_methods(::Spymemcached,
67
- commands)
76
+ commands)
77
+ NewRelic::Agent.logger.debug 'Installing Spymemcached instrumentation'
68
78
  end
69
79
  end
70
80
  end
@@ -1,7 +1,8 @@
1
1
  require 'set'
2
2
 
3
3
  DependencyDetection.defer do
4
-
4
+ @name = :merb_controller
5
+
5
6
  depends_on do
6
7
  defined?(Merb) && defined?(Merb::Controller)
7
8
  end
@@ -1,4 +1,6 @@
1
1
  DependencyDetection.defer do
2
+ @name = :merb_error
3
+
2
4
  depends_on do
3
5
  defined?(Merb) && defined?(Merb::Dispatcher) && defined?(Merb::Dispatcher::DefaultException)
4
6
  end
@@ -87,15 +87,20 @@ module NewRelic
87
87
  def transaction_sampler
88
88
  agent.transaction_sampler
89
89
  end
90
+
91
+ def sql_sampler
92
+ agent.sql_sampler
93
+ end
90
94
 
91
95
  private :agent
92
96
  private :transaction_sampler
93
-
97
+ private :sql_sampler
94
98
 
95
99
  # Indicate that we are entering a measured controller action or task.
96
100
  # Make sure you unwind every push with a pop call.
97
101
  def push(m)
98
102
  transaction_sampler.notice_first_scope_push(start)
103
+ sql_sampler.notice_first_scope_push(start)
99
104
  @path_stack.push NewRelic::MetricParser::MetricParser.for_metric_named(m)
100
105
  end
101
106
 
@@ -127,6 +132,7 @@ module NewRelic
127
132
  # Only push the transaction context info once, on entry:
128
133
  if @path_stack.size == 1
129
134
  transaction_sampler.notice_transaction(metric_name, uri, filtered_params)
135
+ sql_sampler.notice_transaction(metric_name, uri, filtered_params)
130
136
  end
131
137
  end
132
138
 
@@ -19,6 +19,7 @@ module NewRelic
19
19
 
20
20
  def notice_scope_empty
21
21
  transaction_sampler.notice_scope_empty
22
+ sql_sampler.notice_scope_empty
22
23
  end
23
24
 
24
25
  def record_transaction_cpu
@@ -1,4 +1,6 @@
1
1
  DependencyDetection.defer do
2
+ @name = :net
3
+
2
4
  depends_on do
3
5
  defined?(Net) && defined?(Net::HTTP)
4
6
  end
@@ -1,4 +1,6 @@
1
1
  DependencyDetection.defer do
2
+ @name = :passenger
3
+
2
4
  depends_on do
3
5
  defined?(PhusionPassenger)
4
6
  end
@@ -1,77 +1,104 @@
1
- # FIXME: this should be a separate dependency block for each kind of
2
- # view instrumentation
3
1
  DependencyDetection.defer do
2
+ @name = :rails21_view
3
+
4
4
  depends_on do
5
- defined?(ActionController) && defined?(ActionController::Base)
5
+ !NewRelic::Control.instance['disable_view_instrumentation'] &&
6
+ defined?(ActionController) && defined?(ActionController::Base) && defined?(ActionView::PartialTemplate) && defined?(ActionView::Template) &&
7
+ defined?(Rails::VERSION::STRING) && Rails::VERSION::STRING =~ /^2\.1\./ # Rails 2.1 &&
8
+ end
9
+
10
+ executes do
11
+ NewRelic::Agent.logger.debug 'Installing Rails 2.1 View instrumentation'
12
+ end
13
+
14
+ executes do
15
+ ActionView::PartialTemplate.class_eval do
16
+ add_method_tracer :render, 'View/#{path_without_extension[%r{^(/.*/)?(.*)$},2]}.#{@view.template_format}.#{extension}/Partial'
17
+ end
18
+ # this is for template rendering, as opposed to partial rendering.
19
+ ActionView::Template.class_eval do
20
+ add_method_tracer :render, 'View/#{(path_without_extension || @view.controller.newrelic_metric_path)[%r{^(/.*/)?(.*)$},2]}.#{@view.template_format}.#{extension}/Rendering'
21
+ end
6
22
  end
23
+ end
7
24
 
25
+ DependencyDetection.defer do
26
+ @name = :old_rails_view
27
+
8
28
  depends_on do
9
- defined?(Rails) && Rails::VERSION::MAJOR.to_i == 2
29
+ !NewRelic::Control.instance['disable_view_instrumentation'] &&
30
+ defined?(ActionController) && defined?(ActionController::Base) &&
31
+ defined?(Rails::VERSION::STRING) && Rails::VERSION::STRING =~ /^(1\.|2\.0)/ # Rails 1.* - 2.0
32
+ end
33
+
34
+ executes do
35
+ NewRelic::Agent.logger.debug 'Installing Rails 1.* - 2.0 View instrumentation'
36
+ end
37
+
38
+ executes do
39
+ ActionController::Base.class_eval do
40
+ add_method_tracer :render, 'View/#{newrelic_metric_path}/Rendering'
41
+ end
42
+
10
43
  end
44
+ end
11
45
 
46
+ DependencyDetection.defer do
47
+ @name = :rails23_view
48
+
12
49
  depends_on do
13
- !NewRelic::Control.instance['disable_view_instrumentation']
50
+ !NewRelic::Control.instance['disable_view_instrumentation'] &&
51
+ defined?(ActionView) && defined?(ActionView::Template) && defined?(ActionView::RenderablePartial) &&
52
+ defined?(Rails::VERSION::STRING) && Rails::VERSION::STRING =~ /^2\.[23]/
14
53
  end
15
54
 
55
+ executes do
56
+ NewRelic::Agent.logger.debug 'Installing Rails 2.2 - 2.3 View instrumentation'
57
+ end
58
+
16
59
  executes do
17
- case Rails::VERSION::STRING
18
-
19
- when /^(1\.|2\.0)/ # Rails 1.* - 2.0
20
- ActionController::Base.class_eval do
21
- add_method_tracer :render, 'View/#{newrelic_metric_path}/Rendering'
22
- end
23
-
24
- when /^2\.1\./ # Rails 2.1
25
- ActionView::PartialTemplate.class_eval do
26
- add_method_tracer :render, 'View/#{path_without_extension[%r{^(/.*/)?(.*)$},2]}.#{@view.template_format}.#{extension}/Partial'
27
- end
28
- # this is for template rendering, as opposed to partial rendering.
29
- ActionView::Template.class_eval do
30
- add_method_tracer :render, 'View/#{(path_without_extension || @view.controller.newrelic_metric_path)[%r{^(/.*/)?(.*)$},2]}.#{@view.template_format}.#{extension}/Rendering'
31
- end
32
-
33
- when /^2\./ # Rails 2.2-2.*
34
- ActionView::RenderablePartial.module_eval do
35
- add_method_tracer :render_partial, 'View/#{path[%r{^(/.*/)?(.*)$},2]}/Partial'
36
- end
37
- ActionView::Template.class_eval do
38
- add_method_tracer :render, 'View/#{path[%r{^(/.*/)?(.*)$},2]}/Rendering'
39
- end
60
+ ActionView::RenderablePartial.module_eval do
61
+ add_method_tracer :render_partial, 'View/#{path[%r{^(/.*/)?(.*)$},2]}/Partial'
40
62
  end
41
- end
63
+ ActionView::Template.class_eval do
64
+ add_method_tracer :render, 'View/#{path[%r{^(/.*/)?(.*)$},2]}/Rendering'
65
+ end
66
+ end
42
67
  end
43
68
 
44
69
  DependencyDetection.defer do
70
+ @name = :rails2_controller
71
+
45
72
  depends_on do
46
73
  defined?(ActionController) && defined?(ActionController::Base)
47
74
  end
48
-
75
+
49
76
  depends_on do
50
77
  defined?(Rails) && Rails::VERSION::MAJOR.to_i == 2
51
78
  end
52
79
 
53
80
  executes do
54
- NewRelic::Agent.logger.debug 'Installing Rails Controller instrumentation'
81
+ NewRelic::Agent.logger.debug 'Installing Rails 2 Controller instrumentation'
55
82
  end
56
-
83
+
57
84
  executes do
58
85
  ActionController::Base.class_eval do
59
86
  include NewRelic::Agent::Instrumentation::ControllerInstrumentation
60
-
87
+
61
88
  # Compare with #alias_method_chain, which is not available in
62
89
  # Rails 1.1:
63
90
  alias_method :perform_action_without_newrelic_trace, :perform_action
64
91
  alias_method :perform_action, :perform_action_with_newrelic_trace
65
92
  private :perform_action
66
-
93
+
67
94
  def self.newrelic_write_attr(attr_name, value) # :nodoc:
68
95
  write_inheritable_attribute(attr_name, value)
69
96
  end
70
-
97
+
71
98
  def self.newrelic_read_attr(attr_name) # :nodoc:
72
99
  read_inheritable_attribute(attr_name)
73
100
  end
74
-
101
+
75
102
  # determine the path that is used in the metric name for
76
103
  # the called controller action
77
104
  def newrelic_metric_path(action_name_override = nil)
@@ -1,4 +1,6 @@
1
1
  DependencyDetection.defer do
2
+ @name = :rails_action_web_service
3
+
2
4
  depends_on do
3
5
  defined?(ActionWebService)
4
6
  end
@@ -62,6 +62,7 @@ module NewRelic
62
62
  log_without_newrelic_instrumentation(sql, name, &block)
63
63
  ensure
64
64
  NewRelic::Agent.instance.transaction_sampler.notice_sql(sql, supported_config, (Time.now - t0).to_f)
65
+ NewRelic::Agent.instance.sql_sampler.notice_sql(sql, metric, supported_config, (Time.now - t0).to_f)
65
66
  end
66
67
  end
67
68
  end
@@ -73,12 +74,14 @@ module NewRelic
73
74
  end
74
75
 
75
76
  DependencyDetection.defer do
77
+ @name = :rails2_active_record
78
+
76
79
  depends_on do
77
80
  defined?(ActiveRecord) && defined?(ActiveRecord::Base)
78
81
  end
79
82
 
80
83
  depends_on do
81
- defined?(Rails) && Rails::VERSION::MAJOR.to_i == 2
84
+ defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 2
82
85
  end
83
86
 
84
87
  depends_on do
@@ -90,7 +93,7 @@ DependencyDetection.defer do
90
93
  end
91
94
 
92
95
  executes do
93
- NewRelic::Agent.logger.debug 'Installing Rails ActiveRecord instrumentation'
96
+ NewRelic::Agent.logger.debug 'Installing Rails 2 ActiveRecord instrumentation'
94
97
  end
95
98
 
96
99
  executes do
@@ -1,14 +1,16 @@
1
1
  DependencyDetection.defer do
2
+ @name = :rails2_error
3
+
2
4
  depends_on do
3
5
  defined?(ActionController) && defined?(ActionController::Base)
4
6
  end
5
7
 
6
8
  depends_on do
7
- defined?(Rails) && Rails::VERSION::MAJOR.to_i == 2
9
+ defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 2
8
10
  end
9
11
 
10
12
  executes do
11
- NewRelic::Agent.logger.debug 'Installing Rails Error instrumentation'
13
+ NewRelic::Agent.logger.debug 'Installing Rails 2 Error instrumentation'
12
14
  end
13
15
 
14
16
  executes do
@@ -36,14 +36,27 @@ module NewRelic
36
36
  end
37
37
 
38
38
  end
39
+
40
+ module ActionView
41
+ def _render_template(template, layout = nil, options = {}) #:nodoc:
42
+ NewRelic::Agent.trace_execution_scoped "View/#{template.virtual_path}/Rendering" do
43
+ super
44
+ end
45
+ end
46
+
47
+ module PartialRenderer
48
+ end
49
+ end
39
50
  end
40
51
  end
41
52
  end
42
53
  end
43
54
 
44
55
  DependencyDetection.defer do
56
+ @name = :rails3_controller
57
+
45
58
  depends_on do
46
- defined?(Rails) && Rails::VERSION::MAJOR.to_i == 3
59
+ defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 3
47
60
  end
48
61
 
49
62
  depends_on do
@@ -51,7 +64,7 @@ DependencyDetection.defer do
51
64
  end
52
65
 
53
66
  executes do
54
- NewRelic::Agent.logger.debug 'Installing Rails3 Controller instrumentation'
67
+ NewRelic::Agent.logger.debug 'Installing Rails 3 Controller instrumentation'
55
68
  end
56
69
 
57
70
  executes do
@@ -62,3 +75,44 @@ DependencyDetection.defer do
62
75
  end
63
76
  end
64
77
 
78
+ DependencyDetection.defer do
79
+ @name = :rails3_view
80
+
81
+ depends_on do
82
+ defined?(ActionView) && defined?(ActionView::Base) && defined?(ActionView::Partials)
83
+ end
84
+
85
+ depends_on do
86
+ defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 3 && ::Rails::VERSION::MINOR.to_i >= 1
87
+ end
88
+
89
+ depends_on do
90
+ !NewRelic::Control.instance['disable_view_instrumentation']
91
+ end
92
+
93
+ executes do
94
+ NewRelic::Agent.logger.debug 'Installing Rails 3 view instrumentation'
95
+ end
96
+
97
+ executes do
98
+ class ActionView::Base
99
+ include NewRelic::Agent::Instrumentation::Rails3::ActionView
100
+ end
101
+ old_klass = ActionView::Partials::PartialRenderer
102
+ ActionView::Partials::PartialRenderer = Class.new(old_klass)
103
+ class ActionView::Partials::PartialRenderer
104
+ def render_partial(*args)
105
+ NewRelic::Agent.trace_execution_scoped "View/#{@template.virtual_path}/Partial" do
106
+ super
107
+ end
108
+ end
109
+
110
+ def render_collection(*args)
111
+ name = @template ? @template.virtual_path : "Mixed"
112
+ NewRelic::Agent.trace_execution_scoped "View/#{name}/Collection" do
113
+ super
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end