newrelic_rpm 2.10.5 → 2.10.6

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.

data/CHANGELOG CHANGED
@@ -1,9 +1,15 @@
1
+ v2.10.6
2
+ * fix missing URL and referer on some traced errors and transactions
3
+ * gather traced errors *after* executing the rescue chain in ActionController
4
+ * always load controller instrumentation
5
+ * pick up token validation from newrelic.yml
6
+
1
7
  v2.10.5
2
- * Fix bug in delayed_job instrumentation occurring when there was no DJ log
8
+ * fix bug in delayed_job instrumentation occurring when there was no DJ log
3
9
 
4
10
  v2.10.4
5
- * Fix incompatibility with Capistrano 2.5.16
6
- * Strip down URLs reported in transactions and errors to path only
11
+ * fix incompatibility with Capistrano 2.5.16
12
+ * strip down URLs reported in transactions and errors to path only
7
13
 
8
14
  v2.10.3
9
15
  * optimization to reduce overhead: move background samplers into foreground thread
@@ -100,6 +100,8 @@ module NewRelic
100
100
  require 'new_relic/agent/error_collector'
101
101
  require 'new_relic/agent/busy_calculator'
102
102
  require 'new_relic/agent/sampler'
103
+
104
+ require 'new_relic/agent/instrumentation/controller_instrumentation'
103
105
 
104
106
  require 'new_relic/agent/samplers/cpu_sampler'
105
107
  require 'new_relic/agent/samplers/memory_sampler'
@@ -285,11 +287,17 @@ module NewRelic
285
287
  # if there is one.
286
288
  #
287
289
  # * <tt>exception</tt> is the exception which will be recorded
288
- # * <tt>extra_params</tt> is a hash of name value pairs to appear alongside
289
- # the exception in RPM.
290
+ # Options:
291
+ # * <tt>:uri</tt> => The request path, minus any request params or query string.
292
+ # * <tt>:referer</tt> => The URI of the referer
293
+ # * <tt>:metric</tt> => The metric name associated with the transaction
294
+ # * <tt>:request_params</tt> => Request parameters, already filtered if necessary
295
+ # * <tt>:custom_params</tt> => Custom parameters
296
+ #
297
+ # Anything left over is treated as custom params
290
298
  #
291
- def notice_error(exception, extra_params = nil)
292
- NewRelic::Agent::Instrumentation::MetricFrame.notice_error(exception, extra_params)
299
+ def notice_error(exception, options={})
300
+ NewRelic::Agent::Instrumentation::MetricFrame.notice_error(exception, options)
293
301
  end
294
302
 
295
303
  # Add parameters to the current transaction trace on the call stack.
@@ -298,7 +306,9 @@ module NewRelic
298
306
  NewRelic::Agent::Instrumentation::MetricFrame.add_custom_parameters(params)
299
307
  end
300
308
 
301
- alias add_request_parameters add_custom_parameters
309
+ # The #add_request_parameters method is aliased to #add_custom_parameters
310
+ # and is now deprecated.
311
+ alias add_request_parameters add_custom_parameters #:nodoc:
302
312
 
303
313
  # Yield to a block that is run with a database metric name context. This means
304
314
  # the Database instrumentation will use this for the metric name if it does not
@@ -326,8 +326,8 @@ module NewRelic
326
326
  :agent_version => NewRelic::VERSION::STRING,
327
327
  :environment => environment,
328
328
  :settings => control.settings,
329
- :validate_seed => ENV['NR_VALIDATE_SEED'],
330
- :validate_token => ENV['NR_VALIDATE_TOKEN'] }
329
+ :validate_seed => control.validate_seed,
330
+ :validate_token => control.validate_token }
331
331
 
332
332
  host = invoke_remote(:get_redirect_host)
333
333
 
@@ -45,11 +45,13 @@ module NewRelic
45
45
 
46
46
  # Notice the error with the given available options:
47
47
  #
48
- # * :uri => The request path, minus any request params or query string.
49
- # * :referer => The URI of the referer
50
- # * :metric => The metric name associated with the transaction
51
- # * :request_params => Request parameters, already filtered if necessary
52
- # * :custom_params => Custom parameters
48
+ # * <tt>:uri</tt> => The request path, minus any request params or query string.
49
+ # * <tt>:referer</tt> => The URI of the referer
50
+ # * <tt>:metric</tt> => The metric name associated with the transaction
51
+ # * <tt>:request_params</tt> => Request parameters, already filtered if necessary
52
+ # * <tt>:custom_params</tt> => Custom parameters
53
+ #
54
+ # If anything is left over, it's added to custom params
53
55
  def notice_error(exception, options={})
54
56
  return unless @enabled
55
57
  return if @ignore[exception.class.name]
@@ -58,23 +60,22 @@ module NewRelic
58
60
  return if exception.nil?
59
61
  end
60
62
 
61
- action_path = options[:metric] || NewRelic::Agent.instance.stats_engine.scope_name || ''
62
- filtered_params = options[:request_params] || {}
63
-
64
63
  NewRelic::Agent.get_stats("Errors/all").increment_count
65
64
  return unless NewRelic::Agent.instance.should_send_errors
66
-
65
+
67
66
  data = {}
68
-
69
- data[:request_params] = normalize_params(options[:request_params]) if NewRelic::Control.instance.capture_params && options[:request_params]
67
+ data[:request_uri] = options.delete(:uri) || ''
68
+ data[:request_referer] = options.delete(:referer) || ''
70
69
 
71
- data[:custom_params] = normalize_params(options[:custom_params]) if options[:custom_params]
72
-
73
- data[:request_uri] = options[:uri] || ''
74
- data[:request_referer] = options[:referer] || ''
70
+ action_path = options.delete(:metric) || NewRelic::Agent.instance.stats_engine.scope_name || ''
71
+ request_params = options.delete(:request_params)
72
+ custom_params = options.delete(:custom_params) || {}
73
+ # If anything else is left over, treat it like a custom param:
74
+ custom_params.merge! options
75
75
 
76
+ data[:request_params] = normalize_params(request_params) if NewRelic::Control.instance.capture_params && request_params
77
+ data[:custom_params] = normalize_params(custom_params) unless custom_params.empty?
76
78
  data[:rails_root] = NewRelic::Control.instance.root
77
-
78
79
  data[:file_name] = exception.file_name if exception.respond_to?('file_name')
79
80
  data[:line_number] = exception.line_number if exception.respond_to?('line_number')
80
81
 
@@ -2,23 +2,29 @@
2
2
  # each with slightly different API's and semantics.
3
3
  # See:
4
4
  # http://www.deveiate.org/code/Ruby-MemCache/ (Gem: Ruby-MemCache)
5
- # http://dev.robotcoop.com/Libraries/memcache-client/ (Gem: memcache-client)
5
+ # http://seattlerb.rubyforge.org/memcache-client/ (Gem: memcache-client)
6
6
  unless NewRelic::Control.instance['disable_memcache_instrumentation']
7
- MemCache.class_eval do
8
- add_method_tracer :get, 'MemCache/read' if self.method_defined? :get
9
- add_method_tracer :get_multi, 'MemCache/read' if self.method_defined? :get_multi
10
- %w[set add incr decr delete].each do | method |
11
- add_method_tracer method, 'MemCache/write' if self.method_defined? method
12
- end
13
- end if defined? MemCache
14
7
 
8
+ # This is in the memcache-client implementation and has never existed in Ruby-MemCache
9
+ def self.instrument_method(the_class, method_name)
10
+ return unless the_class.method_defined? method_name.to_sym
11
+ the_class.class_eval <<-EOD
12
+ def #{method_name}_with_newrelic_trace(*args)
13
+ metrics = ["MemCache/#{method_name}",
14
+ (NewRelic::Agent::Instrumentation::MetricFrame.recording_web_transaction? ? 'MemCache/allWeb' : 'MemCache/allOther')]
15
+ self.class.trace_execution_scoped(metrics) do
16
+ #{method_name}_without_newrelic_trace(*args)
17
+ end
18
+ end
19
+ alias #{method_name}_without_newrelic_trace #{method_name}
20
+ alias #{method_name} #{method_name}_with_newrelic_trace
21
+ EOD
22
+ end
15
23
  # Support for libmemcached through Evan Weaver's memcached wrapper
16
24
  # http://blog.evanweaver.com/files/doc/fauna/memcached/classes/Memcached.html
17
- Memcached.class_eval do
18
- add_method_tracer :get, 'MemCache/read' if self.method_defined? :get
19
- %w[set add increment decrement delete replace append prepend cas].each do | method |
20
- add_method_tracer method, "MemCache/write" if self.method_defined? method
21
- end
22
- end if defined? Memcached
25
+ %w[get get_multi set add incr decr delete replace append prepand cas].each do | method_name |
26
+ instrument_method(::MemCache, method_name) if defined? ::MemCache
27
+ instrument_method(::Memcached, method_name) if defined? ::Memcached
28
+ end
23
29
 
24
30
  end
@@ -63,22 +63,14 @@ module NewRelic::Agent::Instrumentation
63
63
 
64
64
  # For the current web transaction, return the path of the URI minus the host part and query string, or nil.
65
65
  def uri
66
- return @uri if @uri || @request.nil?
67
- approximate_uri = case
68
- when @request.respond_to?(:fullpath) then @request.fullpath
69
- when @request.respond_to?(:path) then @request.path
70
- when @request.respond_to?(:uri) then @request.uri
71
- when @request.respond_to?(:url) then @request.url
72
- end
73
- @uri = approximate_uri[%r{^(https?://.*?)?(/[^?]*)}, 2] || '/' if approximate_uri
66
+ @uri ||= self.class.uri_from_request(@request) unless @request.nil?
74
67
  end
75
68
 
76
69
  # For the current web transaction, return the full referer, minus the host string, or nil.
77
70
  def referer
78
- return @referer if @referer || @request.nil? || !@request.respond_to?(:referer) || !@request.referer
79
- @referer = @request.referer.split('?').first
71
+ @referer ||= self.class.referer_from_request(@request)
80
72
  end
81
-
73
+
82
74
  # Call this to ensure that the current transaction is not saved
83
75
  def abort_transaction!
84
76
  NewRelic::Agent.instance.transaction_sampler.ignore_transaction
@@ -130,17 +122,37 @@ module NewRelic::Agent::Instrumentation
130
122
  end
131
123
 
132
124
  # If we have an active metric frame, notice the error and increment the error metric.
133
- def self.notice_error(e, custom_params=nil)
125
+ # Options:
126
+ # * <tt>:request</tt> => Request object to get the uri and referer
127
+ # * <tt>:uri</tt> => The request path, minus any request params or query string.
128
+ # * <tt>:referer</tt> => The URI of the referer
129
+ # * <tt>:metric</tt> => The metric name associated with the transaction
130
+ # * <tt>:request_params</tt> => Request parameters, already filtered if necessary
131
+ # * <tt>:custom_params</tt> => Custom parameters
132
+ # Anything left over is treated as custom params
133
+
134
+ def self.notice_error(e, options={})
135
+ if request = options.delete(:request)
136
+ options[:referer] = referer_from_request(request)
137
+ options[:uri] = uri_from_request(request)
138
+ end
134
139
  if current
135
- current.notice_error(e, custom_params)
140
+ current.notice_error(e, options)
136
141
  else
137
- NewRelic::Agent.instance.error_collector.notice_error(e, :custom_params => custom_params)
142
+ NewRelic::Agent.instance.error_collector.notice_error(e, options)
138
143
  end
139
144
  end
140
145
 
141
- def notice_error(e, custom_params=nil)
146
+ # Do not call this. Invoke the class method instead.
147
+ def notice_error(e, options={}) # :nodoc:
148
+ params = custom_parameters
149
+ options[:referer] = referer if referer
150
+ options[:request_params] = filtered_params if filtered_params
151
+ options[:uri] = uri if uri
152
+ options[:metric] = metric_name
153
+ options.merge!(custom_parameters)
142
154
  if exception != e
143
- NewRelic::Agent.instance.error_collector.notice_error(e, :referer => referer, :uri => uri, :metric => metric_name, :request_params => filtered_params, :custom_params => custom_params)
155
+ NewRelic::Agent.instance.error_collector.notice_error(e, options)
144
156
  self.exception = e
145
157
  end
146
158
  end
@@ -160,8 +172,8 @@ module NewRelic::Agent::Instrumentation
160
172
  ending = Time.now.to_f
161
173
  summary_stat = NewRelic::Agent.instance.stats_engine.get_custom_stats("Apdex", NewRelic::ApdexStats)
162
174
  controller_stat = NewRelic::Agent.instance.stats_engine.get_custom_stats("Apdex/#{path}", NewRelic::ApdexStats)
163
- update_apdex(summary_stat, ending - apdex_start, exception)
164
- update_apdex(controller_stat, ending - start, exception)
175
+ self.class.update_apdex(summary_stat, ending - apdex_start, exception)
176
+ self.class.update_apdex(controller_stat, ending - start, exception)
165
177
  end
166
178
 
167
179
  def metric_name
@@ -223,9 +235,29 @@ module NewRelic::Agent::Instrumentation
223
235
  0 == cat.index("Controller")
224
236
  end
225
237
 
226
- private
238
+ # Make a safe attempt to get the referer from a request object, generally successful when
239
+ # it's a Rack request.
240
+ def self.referer_from_request(request)
241
+ if request && request.respond_to?(:referer)
242
+ request.referer.to_s.split('?').first
243
+ end
244
+ end
245
+
246
+ # Make a safe attempt to get the URI, without the host and query string.
247
+ def self.uri_from_request(request)
248
+ approximate_uri = case
249
+ when request.respond_to?(:fullpath) then request.fullpath
250
+ when request.respond_to?(:path) then request.path
251
+ when request.respond_to?(:request_uri) then request.request_uri
252
+ when request.respond_to?(:uri) then request.uri
253
+ when request.respond_to?(:url) then request.url
254
+ end
255
+ return approximate_uri[%r{^(https?://.*?)?(/[^?]*)}, 2] || '/' if approximate_uri
256
+ end
227
257
 
228
- def update_apdex(stat, duration, failed)
258
+ # Record an apdex value for the given stat. non-nil 'failed'
259
+ # the apdex should be recorded as a failure regardless of duration.
260
+ def self.update_apdex(stat, duration, failed)
229
261
  apdex_t = NewRelic::Control.instance.apdex_t
230
262
  case
231
263
  when failed
@@ -239,6 +271,8 @@ module NewRelic::Agent::Instrumentation
239
271
  end
240
272
  end
241
273
 
274
+ private
275
+
242
276
  def process_cpu
243
277
  return nil if defined? JRuby
244
278
  p = Process.times
@@ -12,6 +12,7 @@ module NewRelic
12
12
  # NewRelic::Agent::Instrumentation::ControllerInstrumentation::ClassMethods#add_transaction_tracer
13
13
  #
14
14
  # Example:
15
+ # require 'newrelic_rpm'
15
16
  # require 'new_relic/agent/instrumentation/rack'
16
17
  # class Middleware
17
18
  # def call(env)
@@ -26,6 +27,7 @@ module NewRelic
26
27
  # If you are using Metal, be sure and extend the your Metal class with the
27
28
  # Rack instrumentation:
28
29
  #
30
+ # require 'newrelic_rpm'
29
31
  # require 'new_relic/agent/instrumentation/rack'
30
32
  # class MetalApp
31
33
  # def self.call(env)
@@ -41,6 +43,7 @@ module NewRelic
41
43
  # be more specific and pass in name, then omit including the Rack instrumentation
42
44
  # and instead follow this example:
43
45
  #
46
+ # require 'newrelic_rpm'
44
47
  # require 'new_relic/agent/instrumentation/controller_instrumentation'
45
48
  # class Middleware
46
49
  # include NewRelic::Agent::Instrumentation::ControllerInstrumentation
@@ -1,17 +1,17 @@
1
1
 
2
2
  ActionController::Base.class_eval do
3
3
 
4
- # Make a note of an exception associated with the currently executin
4
+ # Make a note of an exception associated with the currently executing
5
5
  # controller action. Note that this used to be available on Object
6
6
  # but we replaced that global method with NewRelic::Agent#notice_error.
7
7
  # Use that one outside of controller actions.
8
8
  def newrelic_notice_error(exception, custom_params = {})
9
- NewRelic::Agent::Instrumentation::MetricFrame.notice_error exception, custom_params
9
+ NewRelic::Agent::Instrumentation::MetricFrame.notice_error exception, :custom_params => custom_params, :request => request
10
10
  end
11
11
 
12
12
  def rescue_action_with_newrelic_trace(exception)
13
- NewRelic::Agent::Instrumentation::MetricFrame.notice_error exception
14
13
  rescue_action_without_newrelic_trace exception
14
+ NewRelic::Agent::Instrumentation::MetricFrame.notice_error exception, :request => request
15
15
  end
16
16
 
17
17
  # Compare with #alias_method_chain, which is not available in
@@ -214,6 +214,12 @@ module NewRelic
214
214
  def app_names
215
215
  self['app_name'] ? self['app_name'].split(';') : []
216
216
  end
217
+ def validate_seed
218
+ self['validate_seed'] || ENV['NR_VALIDATE_SEED']
219
+ end
220
+ def validate_token
221
+ self['validate_token'] || ENV['NR_VALIDATE_TOKEN']
222
+ end
217
223
 
218
224
  def use_ssl?
219
225
  @use_ssl ||= fetch('ssl', false)
@@ -440,7 +446,10 @@ module NewRelic
440
446
  require File.join(newrelic_root, "test", "config", "test_control.rb")
441
447
  NewRelic::Control::Test.new @local_env
442
448
  else
443
- require "new_relic/control/#{@local_env.framework}.rb"
449
+ begin
450
+ require "new_relic/control/#{@local_env.framework}.rb"
451
+ rescue LoadError
452
+ end
444
453
  NewRelic::Control.const_get(@local_env.framework.to_s.capitalize).new @local_env
445
454
  end
446
455
  end
@@ -15,9 +15,7 @@ Delayed::Worker.class_eval do
15
15
  when self.class.respond_to?(:default_name) then self.class.default_name
16
16
  end
17
17
  dispatcher_instance_id = worker_name || "host:#{Socket.gethostname} pid:#{Process.pid}" rescue "pid:#{Process.pid}"
18
- if self.class.logger
19
- self.class.logger.info "RPM Monitoring DJ worker #{dispatcher_instance_id}"
20
- end
18
+ say "RPM Monitoring DJ worker #{dispatcher_instance_id}"
21
19
  NewRelic::Agent.manual_start :dispatcher => :delayed_job, :dispatcher_instance_id => dispatcher_instance_id
22
20
  NewRelic::DelayedJobInjection.worker_name = worker_name
23
21
  end
@@ -23,6 +23,13 @@ module NewRelic
23
23
  alias environment dispatcher
24
24
 
25
25
  def initialize
26
+ # Extend self with any any submodules of LocalEnvironment. These can override
27
+ # the discover methods to discover new framworks and dispatchers.
28
+ NewRelic::LocalEnvironment.constants.each do | const |
29
+ mod = NewRelic::LocalEnvironment.const_get const
30
+ self.extend mod if mod.instance_of? Module
31
+ end
32
+
26
33
  discover_framework
27
34
  discover_dispatcher
28
35
  @dispatcher = nil if @dispatcher == :none
@@ -155,7 +162,7 @@ module NewRelic
155
162
  # Although you can override the framework with NEWRELIC_DISPATCHER this
156
163
  # is not advisable since it implies certain api's being available.
157
164
  def discover_dispatcher
158
- @dispatcher = ENV['NEWRELIC_DISPATCHER'] && ENV['NEWRELIC_DISPATCHER'].to_sym
165
+ @dispatcher ||= ENV['NEWRELIC_DISPATCHER'] && ENV['NEWRELIC_DISPATCHER'].to_sym
159
166
  dispatchers = %w[passenger torquebox glassfish thin mongrel litespeed webrick fastcgi unicorn sinatra]
160
167
  while dispatchers.any? && @dispatcher.nil?
161
168
  send 'check_for_'+(dispatchers.shift)
@@ -168,7 +175,7 @@ module NewRelic
168
175
  #
169
176
  # Note that the odd defined? sequence is necessary to work around a bug in an older version
170
177
  # of JRuby.
171
- @framework = case
178
+ @framework ||= case
172
179
  when ENV['NEWRELIC_FRAMEWORK'] then ENV['NEWRELIC_FRAMEWORK'].to_sym
173
180
  when defined?(::NewRelic::TEST) then :test
174
181
  when defined?(::Merb) && defined?(::Merb::Plugins) then :merb
@@ -99,6 +99,7 @@ module NewRelic
99
99
  def segment_2; segments[2]; end
100
100
  def segment_3; segments[3]; end
101
101
  def segment_4; segments[4]; end
102
+ def segment_5; segments[5]; end
102
103
  def last_segment; segments.last; end
103
104
 
104
105
  # This is the suffix used for call rate or throughput. By default, it's cpm
@@ -9,4 +9,42 @@ class NewRelic::MetricParser::MemCache < NewRelic::MetricParser
9
9
  def developer_name
10
10
  "MemCache #{segments[1..-1].join '/'}"
11
11
  end
12
+
13
+ def all?
14
+ segments[1]['all'] == 0
15
+ end
16
+ def operation
17
+ all? ? 'All Operations' : segments[1]
18
+ end
19
+ def legend_name
20
+ case segments[1]
21
+ when 'allWeb'
22
+ "MemCache"
23
+ when 'allOther'
24
+ "Non-web MemCache"
25
+ else
26
+ "MemCache #{operation} operations"
27
+ end
28
+ end
29
+ def tooltip_name
30
+ case segments[1]
31
+ when 'allWeb'
32
+ "MemCache calls from web transactions"
33
+ when 'allOther'
34
+ "MemCache calls from non-web transactions"
35
+ else
36
+ "MemCache #{operation} operations"
37
+ end
38
+
39
+ end
40
+ def developer_name
41
+ case segments[1]
42
+ when 'allWeb'
43
+ "Web MemCache"
44
+ when 'allOther'
45
+ "Non-web MemCache"
46
+ else
47
+ "MemCache #{operation}"
48
+ end
49
+ end
12
50
  end
@@ -26,7 +26,24 @@ module NewRelic
26
26
  return 0 if call_count == 0
27
27
  total_exclusive_time / call_count
28
28
  end
29
-
29
+
30
+ # merge by adding to average response time
31
+ # - used to compose multiple metrics e.g. dispatcher time + mongrel queue time
32
+ def sum_merge! (other_stats)
33
+ Array(other_stats).each do |s|
34
+ self.total_call_time += s.total_call_time
35
+ self.total_exclusive_time += s.total_exclusive_time
36
+ self.min_call_time += s.min_call_time
37
+ self.max_call_time += s.max_call_time
38
+ #self.call_count += s.call_count - do not add call count because we are stacking these times on top of each other
39
+ self.sum_of_squares += s.sum_of_squares if s.sum_of_squares
40
+ self.begin_time = s.begin_time if s.begin_time.to_f < begin_time.to_f || begin_time.to_f == 0.0
41
+ self.end_time = s.end_time if s.end_time.to_f > end_time.to_f
42
+ end
43
+
44
+ self
45
+ end
46
+
30
47
  def merge! (other_stats)
31
48
  Array(other_stats).each do |s|
32
49
  self.total_call_time += s.total_call_time
@@ -172,7 +189,7 @@ module NewRelic
172
189
  # Summary string to facilitate testing
173
190
  def summary
174
191
  format = "%m/%d %I:%M%p"
175
- "[#{Time.at(begin_time).strftime(format)}, #{duration}s. #{call_count} calls; #{to_ms(average_call_time)}ms]"
192
+ "[#{Time.at(begin_time).strftime(format)}, #{'%2.3fs' % duration}; #{'%4i' % call_count} calls #{'%4i' % to_ms(average_call_time)} ms]"
176
193
  end
177
194
 
178
195
  # round all of the values to n decimal points
@@ -3,7 +3,7 @@ module NewRelic
3
3
  module VERSION #:nodoc:
4
4
  MAJOR = 2
5
5
  MINOR = 10
6
- TINY = 5
6
+ TINY = 6
7
7
  EXPERIMENTAL = nil
8
8
  STRING = [MAJOR, MINOR, TINY, EXPERIMENTAL].compact.join('.')
9
9
  end
@@ -0,0 +1,210 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{newrelic_rpm}
8
+ s.version = "2.10.6"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Bill Kayser"]
12
+ s.date = %q{2010-03-05}
13
+ s.description = %q{New Relic RPM is a Ruby performance management system, developed by
14
+ New Relic, Inc (http://www.newrelic.com). RPM provides you with deep
15
+ information about the performance of your Ruby on Rails or Merb
16
+ application as it runs in production. The New Relic Agent is
17
+ dual-purposed as a either a Rails plugin or a Gem, hosted on
18
+ http://github.com/newrelic/rpm/tree/master.
19
+ }
20
+ s.email = %q{support@newrelic.com}
21
+ s.executables = ["mongrel_rpm", "newrelic_cmd"]
22
+ s.extra_rdoc_files = [
23
+ "CHANGELOG",
24
+ "LICENSE"
25
+ ]
26
+ s.files = [
27
+ "CHANGELOG",
28
+ "LICENSE",
29
+ "README.md",
30
+ "bin/mongrel_rpm",
31
+ "bin/newrelic_cmd",
32
+ "cert/cacert.pem",
33
+ "install.rb",
34
+ "lib/new_relic/agent.rb",
35
+ "lib/new_relic/agent/agent.rb",
36
+ "lib/new_relic/agent/busy_calculator.rb",
37
+ "lib/new_relic/agent/chained_call.rb",
38
+ "lib/new_relic/agent/collection_helper.rb",
39
+ "lib/new_relic/agent/error_collector.rb",
40
+ "lib/new_relic/agent/instrumentation/active_merchant.rb",
41
+ "lib/new_relic/agent/instrumentation/active_record_instrumentation.rb",
42
+ "lib/new_relic/agent/instrumentation/authlogic.rb",
43
+ "lib/new_relic/agent/instrumentation/controller_instrumentation.rb",
44
+ "lib/new_relic/agent/instrumentation/data_mapper.rb",
45
+ "lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb",
46
+ "lib/new_relic/agent/instrumentation/memcache.rb",
47
+ "lib/new_relic/agent/instrumentation/merb/controller.rb",
48
+ "lib/new_relic/agent/instrumentation/merb/errors.rb",
49
+ "lib/new_relic/agent/instrumentation/metric_frame.rb",
50
+ "lib/new_relic/agent/instrumentation/net.rb",
51
+ "lib/new_relic/agent/instrumentation/passenger_instrumentation.rb",
52
+ "lib/new_relic/agent/instrumentation/rack.rb",
53
+ "lib/new_relic/agent/instrumentation/rails/action_controller.rb",
54
+ "lib/new_relic/agent/instrumentation/rails/action_web_service.rb",
55
+ "lib/new_relic/agent/instrumentation/rails/errors.rb",
56
+ "lib/new_relic/agent/instrumentation/sinatra.rb",
57
+ "lib/new_relic/agent/method_tracer.rb",
58
+ "lib/new_relic/agent/sampler.rb",
59
+ "lib/new_relic/agent/samplers/cpu_sampler.rb",
60
+ "lib/new_relic/agent/samplers/delayed_job_lock_sampler.rb",
61
+ "lib/new_relic/agent/samplers/memory_sampler.rb",
62
+ "lib/new_relic/agent/samplers/object_sampler.rb",
63
+ "lib/new_relic/agent/shim_agent.rb",
64
+ "lib/new_relic/agent/stats_engine.rb",
65
+ "lib/new_relic/agent/stats_engine/metric_stats.rb",
66
+ "lib/new_relic/agent/stats_engine/samplers.rb",
67
+ "lib/new_relic/agent/stats_engine/transactions.rb",
68
+ "lib/new_relic/agent/transaction_sampler.rb",
69
+ "lib/new_relic/agent/worker_loop.rb",
70
+ "lib/new_relic/commands/deployments.rb",
71
+ "lib/new_relic/commands/new_relic_commands.rb",
72
+ "lib/new_relic/control.rb",
73
+ "lib/new_relic/control/external.rb",
74
+ "lib/new_relic/control/merb.rb",
75
+ "lib/new_relic/control/rails.rb",
76
+ "lib/new_relic/control/ruby.rb",
77
+ "lib/new_relic/control/sinatra.rb",
78
+ "lib/new_relic/delayed_job_injection.rb",
79
+ "lib/new_relic/histogram.rb",
80
+ "lib/new_relic/local_environment.rb",
81
+ "lib/new_relic/merbtasks.rb",
82
+ "lib/new_relic/metric_data.rb",
83
+ "lib/new_relic/metric_parser.rb",
84
+ "lib/new_relic/metric_parser/action_mailer.rb",
85
+ "lib/new_relic/metric_parser/active_merchant.rb",
86
+ "lib/new_relic/metric_parser/active_record.rb",
87
+ "lib/new_relic/metric_parser/controller.rb",
88
+ "lib/new_relic/metric_parser/controller_cpu.rb",
89
+ "lib/new_relic/metric_parser/errors.rb",
90
+ "lib/new_relic/metric_parser/external.rb",
91
+ "lib/new_relic/metric_parser/mem_cache.rb",
92
+ "lib/new_relic/metric_parser/other_transaction.rb",
93
+ "lib/new_relic/metric_parser/view.rb",
94
+ "lib/new_relic/metric_parser/web_frontend.rb",
95
+ "lib/new_relic/metric_parser/web_service.rb",
96
+ "lib/new_relic/metric_spec.rb",
97
+ "lib/new_relic/metrics.rb",
98
+ "lib/new_relic/noticed_error.rb",
99
+ "lib/new_relic/rack/metric_app.rb",
100
+ "lib/new_relic/rack/mongrel_rpm.ru",
101
+ "lib/new_relic/rack/newrelic.yml",
102
+ "lib/new_relic/rack_app.rb",
103
+ "lib/new_relic/recipes.rb",
104
+ "lib/new_relic/stats.rb",
105
+ "lib/new_relic/transaction_analysis.rb",
106
+ "lib/new_relic/transaction_sample.rb",
107
+ "lib/new_relic/version.rb",
108
+ "lib/new_relic_api.rb",
109
+ "lib/newrelic_rpm.rb",
110
+ "lib/tasks/all.rb",
111
+ "lib/tasks/install.rake",
112
+ "lib/tasks/tests.rake",
113
+ "newrelic.yml",
114
+ "newrelic_rpm.gemspec",
115
+ "recipes/newrelic.rb",
116
+ "test/active_record_fixtures.rb",
117
+ "test/config/newrelic.yml",
118
+ "test/config/test_control.rb",
119
+ "test/new_relic/agent/active_record_instrumentation_test.rb",
120
+ "test/new_relic/agent/agent_controller_test.rb",
121
+ "test/new_relic/agent/agent_test_controller.rb",
122
+ "test/new_relic/agent/busy_calculator_test.rb",
123
+ "test/new_relic/agent/collection_helper_test.rb",
124
+ "test/new_relic/agent/error_collector_test.rb",
125
+ "test/new_relic/agent/memcache_instrumentation_test.rb",
126
+ "test/new_relic/agent/method_tracer_test.rb",
127
+ "test/new_relic/agent/metric_data_test.rb",
128
+ "test/new_relic/agent/metric_frame_test.rb",
129
+ "test/new_relic/agent/mock_ar_connection.rb",
130
+ "test/new_relic/agent/mock_scope_listener.rb",
131
+ "test/new_relic/agent/net_instrumentation_test.rb",
132
+ "test/new_relic/agent/rpm_agent_test.rb",
133
+ "test/new_relic/agent/stats_engine/metric_stats_test.rb",
134
+ "test/new_relic/agent/stats_engine/samplers_test.rb",
135
+ "test/new_relic/agent/stats_engine/stats_engine_test.rb",
136
+ "test/new_relic/agent/task_instrumentation_test.rb",
137
+ "test/new_relic/agent/testable_agent.rb",
138
+ "test/new_relic/agent/transaction_sample_builder_test.rb",
139
+ "test/new_relic/agent/transaction_sample_test.rb",
140
+ "test/new_relic/agent/transaction_sampler_test.rb",
141
+ "test/new_relic/agent/worker_loop_test.rb",
142
+ "test/new_relic/control_test.rb",
143
+ "test/new_relic/deployments_api_test.rb",
144
+ "test/new_relic/environment_test.rb",
145
+ "test/new_relic/metric_parser_test.rb",
146
+ "test/new_relic/metric_spec_test.rb",
147
+ "test/new_relic/shim_agent_test.rb",
148
+ "test/new_relic/stats_test.rb",
149
+ "test/new_relic/version_number_test.rb",
150
+ "test/test_helper.rb",
151
+ "test/ui/newrelic_controller_test.rb",
152
+ "test/ui/newrelic_helper_test.rb",
153
+ "ui/controllers/newrelic_controller.rb",
154
+ "ui/helpers/google_pie_chart.rb",
155
+ "ui/helpers/newrelic_helper.rb",
156
+ "ui/views/layouts/newrelic_default.rhtml",
157
+ "ui/views/newrelic/_explain_plans.rhtml",
158
+ "ui/views/newrelic/_sample.rhtml",
159
+ "ui/views/newrelic/_segment.rhtml",
160
+ "ui/views/newrelic/_segment_limit_message.rhtml",
161
+ "ui/views/newrelic/_segment_row.rhtml",
162
+ "ui/views/newrelic/_show_sample_detail.rhtml",
163
+ "ui/views/newrelic/_show_sample_sql.rhtml",
164
+ "ui/views/newrelic/_show_sample_summary.rhtml",
165
+ "ui/views/newrelic/_sql_row.rhtml",
166
+ "ui/views/newrelic/_stack_trace.rhtml",
167
+ "ui/views/newrelic/_table.rhtml",
168
+ "ui/views/newrelic/explain_sql.rhtml",
169
+ "ui/views/newrelic/images/arrow-close.png",
170
+ "ui/views/newrelic/images/arrow-open.png",
171
+ "ui/views/newrelic/images/blue_bar.gif",
172
+ "ui/views/newrelic/images/file_icon.png",
173
+ "ui/views/newrelic/images/gray_bar.gif",
174
+ "ui/views/newrelic/images/new-relic-rpm-desktop.gif",
175
+ "ui/views/newrelic/images/new_relic_rpm_desktop.gif",
176
+ "ui/views/newrelic/images/textmate.png",
177
+ "ui/views/newrelic/index.rhtml",
178
+ "ui/views/newrelic/javascript/prototype-scriptaculous.js",
179
+ "ui/views/newrelic/javascript/transaction_sample.js",
180
+ "ui/views/newrelic/sample_not_found.rhtml",
181
+ "ui/views/newrelic/show_sample.rhtml",
182
+ "ui/views/newrelic/show_source.rhtml",
183
+ "ui/views/newrelic/stylesheets/style.css",
184
+ "ui/views/newrelic/threads.rhtml"
185
+ ]
186
+ s.homepage = %q{http://www.github.com/newrelic/rpm}
187
+ s.post_install_message = %q{
188
+ Please see http://support.newrelic.com/faqs/docs/ruby-agent-release-notes
189
+ for a complete description of the features and enhancements available
190
+ in version 2.10 of the Ruby Agent.
191
+
192
+ For details on this specific release, refer to the CHANGELOG file.
193
+
194
+ }
195
+ s.rdoc_options = ["--charset=UTF-8", "--line-numbers", "--inline-source", "--title", "New Relic RPM"]
196
+ s.require_paths = ["lib"]
197
+ s.rubygems_version = %q{1.3.6}
198
+ s.summary = %q{New Relic Ruby Performance Monitoring Agent}
199
+
200
+ if s.respond_to? :specification_version then
201
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
202
+ s.specification_version = 3
203
+
204
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
205
+ else
206
+ end
207
+ else
208
+ end
209
+ end
210
+
@@ -0,0 +1,103 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper'))
2
+
3
+ class NewRelic::Agent::MemcacheInstrumentationTest < Test::Unit::TestCase
4
+ include NewRelic::Agent::Instrumentation::ControllerInstrumentation
5
+
6
+ # This implementation: http://seattlerb.rubyforge.org/memcache-client/
7
+ def using_memcache_client?
8
+ ::MemCache.method_defined? :cache_get
9
+ end
10
+
11
+ def setup
12
+ NewRelic::Agent.manual_start
13
+ @engine = NewRelic::Agent.instance.stats_engine
14
+
15
+ if using_memcache_client?
16
+ @cache = ::MemCache.new('localhost')
17
+ else
18
+ server = ::MemCache::Server.new('localhost')
19
+ @cache = ::MemCache.new(server)
20
+ end
21
+ @key = 'schluessel'
22
+ end
23
+
24
+ def _call_test_method_in_web_transaction(method, *args)
25
+ @engine.clear_stats
26
+ begin
27
+ perform_action_with_newrelic_trace(:name=>'action', :category => :controller) do
28
+ @cache.send(method.to_sym, *[@key, *args])
29
+ end
30
+ rescue ::MemCache::MemCacheError
31
+ # There's probably no memcached around
32
+ end
33
+ end
34
+
35
+ def _call_test_method_in_background_task(method, *args)
36
+ @engine.clear_stats
37
+ begin
38
+ perform_action_with_newrelic_trace(:name => 'bg_task', :category => :task) do
39
+ @cache.send(method.to_sym, *[@key, *args])
40
+ end
41
+ rescue ::MemCache::MemCacheError
42
+ # There's probably no memcached around
43
+ end
44
+ end
45
+
46
+ def test_reads__web
47
+ %w[get get_multi].each do |method|
48
+ if @cache.class.method_defined?(method)
49
+ _call_test_method_in_web_transaction(method)
50
+ compare_metrics ["MemCache/#{method}", "MemCache/allWeb", "MemCache/#{method}:Controller/NewRelic::Agent::MemcacheInstrumentationTest/action"],
51
+ @engine.metrics.select{|m| m =~ /^memcache.*/i}
52
+ end
53
+ end
54
+ end
55
+
56
+ def test_writes__web
57
+ %w[incr decr delete].each do |method|
58
+ if @cache.class.method_defined?(method)
59
+ _call_test_method_in_web_transaction(method)
60
+ expected_metrics = ["MemCache/#{method}", "MemCache/allWeb", "MemCache/#{method}:Controller/NewRelic::Agent::MemcacheInstrumentationTest/action"]
61
+ compare_metrics expected_metrics, @engine.metrics.select{|m| m =~ /^memcache.*/i}
62
+ end
63
+ end
64
+
65
+ %w[set add].each do |method|
66
+ if @cache.class.method_defined?(method)
67
+ expected_metrics = ["MemCache/#{method}", "MemCache/allWeb", "MemCache/#{method}:Controller/NewRelic::Agent::MemcacheInstrumentationTest/action"]
68
+ _call_test_method_in_web_transaction(method, 'value')
69
+ compare_metrics expected_metrics, @engine.metrics.select{|m| m =~ /^memcache.*/i}
70
+ end
71
+ end
72
+ end
73
+
74
+ def test_reads__background
75
+ %w[get get_multi].each do |method|
76
+ if @cache.class.method_defined?(method)
77
+ _call_test_method_in_background_task(method)
78
+ compare_metrics ["MemCache/#{method}", "MemCache/allOther", "MemCache/#{method}:OtherTransaction/Background/NewRelic::Agent::MemcacheInstrumentationTest/bg_task"],
79
+ @engine.metrics.select{|m| m =~ /^memcache.*/i}
80
+ end
81
+ end
82
+ end
83
+
84
+ def test_writes__background
85
+
86
+ %w[incr decr delete].each do |method|
87
+ expected_metrics = ["MemCache/#{method}", "MemCache/allOther", "MemCache/#{method}:OtherTransaction/Background/NewRelic::Agent::MemcacheInstrumentationTest/bg_task"]
88
+ if @cache.class.method_defined?(method)
89
+ _call_test_method_in_background_task(method)
90
+ compare_metrics expected_metrics, @engine.metrics.select{|m| m =~ /^memcache.*/i}
91
+ end
92
+ end
93
+
94
+ %w[set add].each do |method|
95
+ expected_metrics = ["MemCache/#{method}", "MemCache/allOther", "MemCache/#{method}:OtherTransaction/Background/NewRelic::Agent::MemcacheInstrumentationTest/bg_task"]
96
+ if @cache.class.method_defined?(method)
97
+ _call_test_method_in_background_task(method, 'value')
98
+ compare_metrics expected_metrics, @engine.metrics.select{|m| m =~ /^memcache.*/i}
99
+ end
100
+ end
101
+ end
102
+
103
+ end if defined? MemCache
@@ -130,6 +130,21 @@ class TaskInstrumentationTest < Test::Unit::TestCase
130
130
  end
131
131
  end
132
132
 
133
+ def test_custom_params
134
+ NewRelic::Agent.instance.stubs(:should_send_errors).returns(true)
135
+ @agent.error_collector.ignore_error_filter
136
+ @agent.error_collector.harvest_errors([])
137
+ assert_equal @agent.error_collector, NewRelic::Agent.instance.error_collector
138
+ assert_raise RuntimeError do
139
+ run_task_exception
140
+ end
141
+ error = @agent.error_collector.harvest_errors([]).first
142
+ assert_equal "Controller/TaskInstrumentationTest/run_task_exception", error.path
143
+ assert_not_nil error.params[:stack_trace]
144
+ assert_not_nil error.params[:custom_params]
145
+
146
+ end
147
+
133
148
  def test_instrument_bg
134
149
  run_background_job
135
150
  stat_names = %w[OtherTransaction/Background/TaskInstrumentationTest/run_background_job
@@ -160,6 +175,7 @@ class TaskInstrumentationTest < Test::Unit::TestCase
160
175
  end
161
176
 
162
177
  def run_task_exception
178
+ NewRelic::Agent.add_custom_parameters(:custom_one => 'one custom val')
163
179
  assert_equal 1, NewRelic::Agent::BusyCalculator.busy_count
164
180
  raise "This is an error"
165
181
  end
@@ -102,12 +102,12 @@ class NewRelic::Agent::TransactionSamplerTest < Test::Unit::TestCase
102
102
 
103
103
  run_sample_trace
104
104
  run_sample_trace
105
- run_sample_trace { sleep 0.5 }
105
+ run_sample_trace { sleep 0.51 }
106
106
  run_sample_trace
107
107
  run_sample_trace
108
108
 
109
109
  slowest = @sampler.harvest(nil, 0)[0]
110
- assert slowest.duration >= 0.5
110
+ assert slowest.duration >= 0.5, "sample duration: #{slowest.duration}"
111
111
 
112
112
  run_sample_trace { sleep 0.2 }
113
113
  not_as_slow = @sampler.harvest(slowest, 0)[0]
@@ -47,7 +47,7 @@ class NewrelicController < ActionController::Base
47
47
  end
48
48
 
49
49
  def file
50
- file_name=params[:file].join
50
+ file_name=Array(params[:file]).join
51
51
  file_name=~/^.*[.]([^.]*)$/
52
52
  ext=$1
53
53
  case ext
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: newrelic_rpm
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.10.5
4
+ prerelease: false
5
+ segments:
6
+ - 2
7
+ - 10
8
+ - 6
9
+ version: 2.10.6
5
10
  platform: ruby
6
11
  authors:
7
12
  - Bill Kayser
@@ -9,7 +14,7 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2010-02-19 00:00:00 -08:00
17
+ date: 2010-03-05 00:00:00 -08:00
13
18
  default_executable:
14
19
  dependencies: []
15
20
 
@@ -30,7 +35,6 @@ extensions: []
30
35
  extra_rdoc_files:
31
36
  - CHANGELOG
32
37
  - LICENSE
33
- - README.md
34
38
  files:
35
39
  - CHANGELOG
36
40
  - LICENSE
@@ -119,6 +123,7 @@ files:
119
123
  - lib/tasks/install.rake
120
124
  - lib/tasks/tests.rake
121
125
  - newrelic.yml
126
+ - newrelic_rpm.gemspec
122
127
  - recipes/newrelic.rb
123
128
  - test/active_record_fixtures.rb
124
129
  - test/config/newrelic.yml
@@ -129,6 +134,7 @@ files:
129
134
  - test/new_relic/agent/busy_calculator_test.rb
130
135
  - test/new_relic/agent/collection_helper_test.rb
131
136
  - test/new_relic/agent/error_collector_test.rb
137
+ - test/new_relic/agent/memcache_instrumentation_test.rb
132
138
  - test/new_relic/agent/method_tracer_test.rb
133
139
  - test/new_relic/agent/metric_data_test.rb
134
140
  - test/new_relic/agent/metric_frame_test.rb
@@ -212,18 +218,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
212
218
  requirements:
213
219
  - - ">="
214
220
  - !ruby/object:Gem::Version
221
+ segments:
222
+ - 0
215
223
  version: "0"
216
- version:
217
224
  required_rubygems_version: !ruby/object:Gem::Requirement
218
225
  requirements:
219
226
  - - ">="
220
227
  - !ruby/object:Gem::Version
228
+ segments:
229
+ - 0
221
230
  version: "0"
222
- version:
223
231
  requirements: []
224
232
 
225
233
  rubyforge_project:
226
- rubygems_version: 1.3.5
234
+ rubygems_version: 1.3.6
227
235
  signing_key:
228
236
  specification_version: 3
229
237
  summary: New Relic Ruby Performance Monitoring Agent