newrelic_rpm 2.13.0.beta5 → 2.13.1

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 (86) hide show
  1. data/CHANGELOG +4 -0
  2. data/lib/new_relic/agent.rb +50 -50
  3. data/lib/new_relic/agent/agent.rb +24 -19
  4. data/lib/new_relic/agent/busy_calculator.rb +22 -22
  5. data/lib/new_relic/agent/chained_call.rb +3 -3
  6. data/lib/new_relic/agent/error_collector.rb +19 -19
  7. data/lib/new_relic/agent/instrumentation/active_record_instrumentation.rb +11 -11
  8. data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +2 -2
  9. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +43 -43
  10. data/lib/new_relic/agent/instrumentation/data_mapper.rb +6 -6
  11. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +2 -2
  12. data/lib/new_relic/agent/instrumentation/memcache.rb +8 -8
  13. data/lib/new_relic/agent/instrumentation/merb/controller.rb +4 -4
  14. data/lib/new_relic/agent/instrumentation/metric_frame.rb +307 -303
  15. data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +8 -8
  16. data/lib/new_relic/agent/instrumentation/rack.rb +2 -2
  17. data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +10 -10
  18. data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +3 -3
  19. data/lib/new_relic/agent/instrumentation/rails/errors.rb +5 -5
  20. data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +5 -5
  21. data/lib/new_relic/agent/instrumentation/sinatra.rb +5 -5
  22. data/lib/new_relic/agent/instrumentation/sunspot.rb +1 -1
  23. data/lib/new_relic/agent/method_tracer.rb +55 -55
  24. data/lib/new_relic/agent/sampler.rb +42 -38
  25. data/lib/new_relic/agent/samplers/cpu_sampler.rb +4 -4
  26. data/lib/new_relic/agent/samplers/delayed_job_lock_sampler.rb +7 -7
  27. data/lib/new_relic/agent/samplers/memory_sampler.rb +11 -11
  28. data/lib/new_relic/agent/samplers/object_sampler.rb +1 -1
  29. data/lib/new_relic/agent/shim_agent.rb +20 -16
  30. data/lib/new_relic/agent/stats_engine.rb +3 -3
  31. data/lib/new_relic/agent/stats_engine/metric_stats.rb +28 -28
  32. data/lib/new_relic/agent/stats_engine/samplers.rb +16 -16
  33. data/lib/new_relic/agent/stats_engine/transactions.rb +25 -25
  34. data/lib/new_relic/agent/transaction_sampler.rb +68 -69
  35. data/lib/new_relic/agent/worker_loop.rb +13 -13
  36. data/lib/new_relic/collection_helper.rb +6 -6
  37. data/lib/new_relic/command.rb +14 -14
  38. data/lib/new_relic/commands/deployments.rb +19 -19
  39. data/lib/new_relic/commands/install.rb +25 -15
  40. data/lib/new_relic/control.rb +25 -25
  41. data/lib/new_relic/control/configuration.rb +17 -17
  42. data/lib/new_relic/control/frameworks/external.rb +3 -3
  43. data/lib/new_relic/control/frameworks/merb.rb +6 -6
  44. data/lib/new_relic/control/frameworks/rails.rb +17 -17
  45. data/lib/new_relic/control/frameworks/rails3.rb +11 -27
  46. data/lib/new_relic/control/frameworks/ruby.rb +6 -6
  47. data/lib/new_relic/control/frameworks/sinatra.rb +4 -4
  48. data/lib/new_relic/control/instrumentation.rb +8 -8
  49. data/lib/new_relic/control/logging_methods.rb +13 -13
  50. data/lib/new_relic/control/profiling.rb +2 -2
  51. data/lib/new_relic/control/server_methods.rb +17 -17
  52. data/lib/new_relic/delayed_job_injection.rb +1 -1
  53. data/lib/new_relic/histogram.rb +73 -71
  54. data/lib/new_relic/local_environment.rb +45 -45
  55. data/lib/new_relic/merbtasks.rb +1 -1
  56. data/lib/new_relic/metric_data.rb +5 -5
  57. data/lib/new_relic/metric_parser.rb +22 -22
  58. data/lib/new_relic/metric_parser/action_mailer.rb +4 -4
  59. data/lib/new_relic/metric_parser/active_merchant.rb +8 -8
  60. data/lib/new_relic/metric_parser/active_record.rb +2 -2
  61. data/lib/new_relic/metric_parser/apdex.rb +86 -51
  62. data/lib/new_relic/metric_parser/controller.rb +10 -10
  63. data/lib/new_relic/metric_parser/controller_cpu.rb +5 -5
  64. data/lib/new_relic/metric_parser/errors.rb +1 -1
  65. data/lib/new_relic/metric_parser/external.rb +3 -3
  66. data/lib/new_relic/metric_parser/mem_cache.rb +2 -2
  67. data/lib/new_relic/metric_parser/other_transaction.rb +7 -7
  68. data/lib/new_relic/metric_parser/view.rb +5 -5
  69. data/lib/new_relic/metric_parser/web_frontend.rb +1 -1
  70. data/lib/new_relic/metric_parser/web_service.rb +1 -1
  71. data/lib/new_relic/metric_spec.rb +13 -13
  72. data/lib/new_relic/noticed_error.rb +4 -4
  73. data/lib/new_relic/rack/developer_mode.rb +33 -33
  74. data/lib/new_relic/rack/metric_app.rb +2 -2
  75. data/lib/new_relic/recipes.rb +9 -9
  76. data/lib/new_relic/stats.rb +57 -57
  77. data/lib/new_relic/timer_lib.rb +2 -2
  78. data/lib/new_relic/transaction_analysis.rb +19 -19
  79. data/lib/new_relic/transaction_sample.rb +101 -101
  80. data/lib/new_relic/url_rule.rb +3 -3
  81. data/lib/new_relic/version.rb +10 -10
  82. data/lib/newrelic_rpm.rb +6 -4
  83. data/lib/tasks/all.rb +1 -1
  84. data/newrelic_rpm.gemspec +3 -3
  85. data/test/new_relic/rack/episodes_test.rb +1 -0
  86. metadata +24 -42
@@ -3,4 +3,4 @@ class NewRelic::MetricParser::Errors < NewRelic::MetricParser
3
3
  def short_name
4
4
  segments[2..-1].join(NewRelic::MetricParser::SEPARATOR)
5
5
  end
6
- end
6
+ end
@@ -1,5 +1,5 @@
1
1
  class NewRelic::MetricParser::External < NewRelic::MetricParser
2
-
2
+
3
3
  def all?
4
4
  host == 'all' || host == 'allWeb' || host == 'allOther'
5
5
  end
@@ -36,7 +36,7 @@ class NewRelic::MetricParser::External < NewRelic::MetricParser
36
36
  end
37
37
  end
38
38
  def developer_name
39
- case
39
+ case
40
40
  when all?
41
41
  'All External'
42
42
  when hosts_all?
@@ -47,4 +47,4 @@ class NewRelic::MetricParser::External < NewRelic::MetricParser
47
47
  "#{library}[#{host}]"
48
48
  end
49
49
  end
50
- end
50
+ end
@@ -1,6 +1,6 @@
1
1
  class NewRelic::MetricParser::MemCache < NewRelic::MetricParser
2
2
  def is_memcache?; true; end
3
-
3
+
4
4
  # for MemCache metrics, the short name is actually
5
5
  # the full name
6
6
  def short_name
@@ -47,4 +47,4 @@ class NewRelic::MetricParser::MemCache < NewRelic::MetricParser
47
47
  "MemCache #{operation}"
48
48
  end
49
49
  end
50
- end
50
+ end
@@ -2,30 +2,30 @@
2
2
  # Task is "Background", "Resque", "DelayedJob" etc.
3
3
 
4
4
  class NewRelic::MetricParser::OtherTransaction < NewRelic::MetricParser
5
-
5
+
6
6
  def is_transaction?
7
7
  true
8
8
  end
9
9
  def task
10
10
  segments[1]
11
11
  end
12
-
12
+
13
13
  def developer_name
14
14
  segments[2..-1].join(NewRelic::MetricParser::SEPARATOR)
15
15
  end
16
-
16
+
17
17
  def short_name
18
18
  developer_name
19
19
  end
20
-
20
+
21
21
  def drilldown_url(metric_id)
22
22
  {:controller => '/v2/background_tasks', :action => 'index', :task => task, :anchor => "id=#{metric_id}"}
23
23
  end
24
-
24
+
25
25
  def path
26
26
  segments[2..-1].join "/"
27
27
  end
28
-
28
+
29
29
  def summary_metrics
30
30
  if segments.size > 2
31
31
  %W[OtherTransaction/#{task}/all OtherTransaction/all]
@@ -33,4 +33,4 @@ class NewRelic::MetricParser::OtherTransaction < NewRelic::MetricParser
33
33
  []
34
34
  end
35
35
  end
36
- end
36
+ end
@@ -15,7 +15,7 @@ class NewRelic::MetricParser::View < NewRelic::MetricParser
15
15
  "#{file_name(segments[-2])} Partial"
16
16
  when ".rhtml Processing"
17
17
  "ERB compilation"
18
- else
18
+ else
19
19
  segments[1..-1]
20
20
  end
21
21
  end
@@ -27,15 +27,15 @@ class NewRelic::MetricParser::View < NewRelic::MetricParser
27
27
  "#{file_name(segments[1..-2].join(NewRelic::MetricParser::SEPARATOR))} Partial"
28
28
  when ".rhtml Processing"
29
29
  "ERB compilation"
30
- else
30
+ else
31
31
  segments[1..-1].join("/")
32
32
  end
33
33
  end
34
-
34
+
35
35
  def short_name
36
36
  segments[1..-2].join(NewRelic::MetricParser::SEPARATOR)
37
37
  end
38
-
38
+
39
39
  def controller_name
40
40
  template_label
41
41
  end
@@ -48,7 +48,7 @@ class NewRelic::MetricParser::View < NewRelic::MetricParser
48
48
  def developer_name
49
49
  template_label
50
50
  end
51
-
51
+
52
52
  def url
53
53
  '/' + file_name(segments[1..-2].join('/'))
54
54
  end
@@ -11,4 +11,4 @@ class NewRelic::MetricParser::WebFrontend < NewRelic::MetricParser
11
11
  def legend_name
12
12
  'Mongrel Wait'
13
13
  end
14
- end
14
+ end
@@ -6,4 +6,4 @@ class NewRelic::MetricParser::WebService < NewRelic::MetricParser
6
6
  def webservice_call_rate_suffix
7
7
  'rpm'
8
8
  end
9
- end
9
+ end
@@ -3,7 +3,7 @@
3
3
  class NewRelic::MetricSpec
4
4
  attr_accessor :name
5
5
  attr_accessor :scope
6
-
6
+
7
7
  MAX_LENGTH = 255
8
8
  # Need a "zero-arg" constructor so it can be instantiated from java (using
9
9
  # jruby) for sending responses to ruby agents from the java collector.
@@ -12,23 +12,23 @@ class NewRelic::MetricSpec
12
12
  self.name = (metric_name || '') && metric_name[0...MAX_LENGTH]
13
13
  self.scope = metric_scope && metric_scope[0...MAX_LENGTH]
14
14
  end
15
-
15
+
16
16
  def truncate!
17
17
  self.name = name[0...MAX_LENGTH] if name && name.size > MAX_LENGTH
18
18
  self.scope = scope[0...MAX_LENGTH] if scope && scope.size > MAX_LENGTH
19
19
  end
20
-
20
+
21
21
  def ==(o)
22
22
  self.eql?(o)
23
23
  end
24
-
24
+
25
25
  def eql? o
26
26
  self.class == o.class &&
27
- name.eql?(o.name) &&
27
+ name.eql?(o.name) &&
28
28
  # coerce scope to a string and compare
29
29
  (scope || '') == (o.scope || '')
30
30
  end
31
-
31
+
32
32
  def hash
33
33
  h = name.hash
34
34
  h ^= scope.hash unless scope.nil?
@@ -37,28 +37,28 @@ class NewRelic::MetricSpec
37
37
  # return a new metric spec if the given regex
38
38
  # matches the name or scope.
39
39
  def sub(pattern, replacement, apply_to_scope = true)
40
- return nil if name !~ pattern &&
40
+ return nil if name !~ pattern &&
41
41
  (!apply_to_scope || scope.nil? || scope !~ pattern)
42
42
  new_name = name.sub(pattern, replacement)[0...MAX_LENGTH]
43
-
43
+
44
44
  if apply_to_scope
45
45
  new_scope = (scope && scope.sub(pattern, replacement)[0...MAX_LENGTH])
46
46
  else
47
47
  new_scope = scope
48
48
  end
49
-
49
+
50
50
  self.class.new new_name, new_scope
51
51
  end
52
-
52
+
53
53
  def to_s
54
54
  "#{name}:#{scope}"
55
55
  end
56
-
56
+
57
57
  def to_json(*a)
58
- {'name' => name,
58
+ {'name' => name,
59
59
  'scope' => scope}.to_json(*a)
60
60
  end
61
-
61
+
62
62
  def <=>(o)
63
63
  namecmp = self.name <=> o.name
64
64
  return namecmp if namecmp != 0
@@ -2,19 +2,19 @@
2
2
  class NewRelic::NoticedError
3
3
  extend NewRelic::CollectionHelper
4
4
  attr_accessor :path, :timestamp, :params, :exception_class, :message
5
-
5
+
6
6
  def initialize(path, data, exception, timestamp = Time.now)
7
7
  self.path = path
8
8
  self.params = NewRelic::NoticedError.normalize_params(data)
9
-
9
+
10
10
  self.exception_class = exception.is_a?(Exception) ? exception.class.name : 'Error'
11
-
11
+
12
12
  if exception.respond_to?('original_exception')
13
13
  self.message = exception.original_exception.message.to_s
14
14
  else
15
15
  self.message = (exception || '<no message>').to_s
16
16
  end
17
-
17
+
18
18
  # clamp long messages to 4k so that we don't send a lot of
19
19
  # overhead across the wire
20
20
  self.message = self.message[0..4095] if self.message.length > 4096
@@ -5,7 +5,7 @@ require 'rack/file'
5
5
 
6
6
  module NewRelic::Rack
7
7
  class DeveloperMode
8
-
8
+
9
9
  VIEW_PATH = File.expand_path('../../../../ui/views/', __FILE__)
10
10
  HELPER_PATH = File.expand_path('../../../../ui/helpers/', __FILE__)
11
11
  require File.join(HELPER_PATH, 'developer_mode_helper.rb')
@@ -22,7 +22,7 @@ class DeveloperMode
22
22
  end
23
23
 
24
24
  protected
25
-
25
+
26
26
  def _call(env)
27
27
  @req = Rack::Request.new(env)
28
28
  @rendered = false
@@ -53,9 +53,9 @@ class DeveloperMode
53
53
  @app.call(env)
54
54
  end
55
55
  end
56
-
56
+
57
57
  private
58
-
58
+
59
59
  def index
60
60
  get_samples
61
61
  render(:index)
@@ -69,18 +69,18 @@ class DeveloperMode
69
69
  def explain_sql
70
70
  get_segment
71
71
 
72
- return render(:sample_not_found) unless @sample
72
+ return render(:sample_not_found) unless @sample
73
73
 
74
74
  @sql = @segment[:sql]
75
75
  @trace = @segment[:backtrace]
76
-
77
- if NewRelic::Agent.agent.record_sql == :obfuscated
76
+
77
+ if NewRelic::Agent.agent.record_sql == :obfuscated
78
78
  @obfuscated_sql = @segment.obfuscated_sql
79
79
  end
80
-
80
+
81
81
  explanations = @segment.explain_sql
82
82
  if explanations
83
- @explanation = explanations.first
83
+ @explanation = explanations.first
84
84
  if !@explanation.blank?
85
85
  first_row = @explanation.first
86
86
  # Show the standard headers if it looks like a mysql explain plan
@@ -99,11 +99,11 @@ class DeveloperMode
99
99
  NewRelic::Control.instance.profiling = params['start'] == 'true'
100
100
  index
101
101
  end
102
-
102
+
103
103
  def threads
104
104
  render(:threads)
105
105
  end
106
-
106
+
107
107
  def render(view, layout=true)
108
108
  add_rack_array = true
109
109
  if view.is_a? Hash
@@ -117,13 +117,13 @@ class DeveloperMode
117
117
  render({:partial => view[:partial], :object => object})
118
118
  end.join(' ')
119
119
  end
120
-
120
+
121
121
  if view[:partial]
122
122
  add_rack_array = false
123
123
  view = "_#{view[:partial]}"
124
124
  end
125
125
  end
126
- binding = Proc.new {}
126
+ binding = Proc.new {}.binding
127
127
  if layout
128
128
  body = render_with_layout(view) do
129
129
  render_without_layout(view, binding)
@@ -142,7 +142,7 @@ class DeveloperMode
142
142
  # that block are interpolated into the layout
143
143
  def render_with_layout(view)
144
144
  body = ERB.new(File.read(File.join(VIEW_PATH, 'layouts/newrelic_default.rhtml')))
145
- body.result(Proc.new {})
145
+ body.result(Proc.new {}.binding)
146
146
  end
147
147
 
148
148
  # you have to pass a binding to this (a proc) so that ERB can have
@@ -150,7 +150,7 @@ class DeveloperMode
150
150
  def render_without_layout(view, binding)
151
151
  ERB.new(File.read(File.join(VIEW_PATH, 'newrelic', view.to_s + '.rhtml')), nil, nil, 'frobnitz').result(binding)
152
152
  end
153
-
153
+
154
154
  def content_tag(tag, contents, opts={})
155
155
  opt_values = opts.map {|k, v| "#{k}=\"#{v}\"" }.join(' ')
156
156
  "<#{tag} #{opt_values}>#{contents}</#{tag}>"
@@ -159,7 +159,7 @@ class DeveloperMode
159
159
  def sample
160
160
  @sample || @samples[0]
161
161
  end
162
-
162
+
163
163
  def params
164
164
  @req.params
165
165
  end
@@ -167,13 +167,13 @@ class DeveloperMode
167
167
  def segment
168
168
  @segment
169
169
  end
170
-
170
+
171
171
 
172
172
  # show the selected source file with the highlighted selected line
173
173
  def show_source
174
174
  @filename = params['file']
175
175
  line_number = params['line'].to_i
176
-
176
+
177
177
  if !File.readable?(@filename)
178
178
  @source="<p>Unable to read #{@filename}.</p>"
179
179
  return
@@ -185,7 +185,7 @@ class DeveloperMode
185
185
  return
186
186
  end
187
187
  @source = ""
188
-
188
+
189
189
  @source << "<pre>"
190
190
  file.each_line do |line|
191
191
  # place an anchor 6 lines above the selected line (if the line # < 6)
@@ -193,7 +193,7 @@ class DeveloperMode
193
193
  @source << "</pre><pre id = 'selected_line'>"
194
194
  @source << line.rstrip
195
195
  @source << "</pre><pre>"
196
-
196
+
197
197
  # highlight the selected line
198
198
  elsif file.lineno == line_number
199
199
  @source << "</pre><pre class = 'selected_source_line'>"
@@ -204,36 +204,36 @@ class DeveloperMode
204
204
  end
205
205
  end
206
206
  render(:show_source)
207
- end
208
-
207
+ end
208
+
209
209
  def show_sample_data
210
210
  get_sample
211
-
212
- return render(:sample_not_found) unless @sample
213
-
211
+
212
+ return render(:sample_not_found) unless @sample
213
+
214
214
  @request_params = @sample.params['request_params'] || {}
215
215
  @custom_params = @sample.params['custom_params'] || {}
216
216
 
217
217
  controller_metric = @sample.root_segment.called_segments.first.metric_name
218
-
218
+
219
219
  metric_parser = NewRelic::MetricParser.for_metric_named controller_metric
220
220
  @sample_controller_name = metric_parser.controller_name
221
221
  @sample_action_name = metric_parser.action_name
222
-
222
+
223
223
  render(:show_sample)
224
224
  end
225
-
225
+
226
226
  def get_samples
227
227
  @samples = NewRelic::Agent.instance.transaction_sampler.samples.select do |sample|
228
228
  sample.params[:path] != nil
229
229
  end
230
-
230
+
231
231
  return @samples = @samples.sort{|x,y| y.omit_segments_with('(Rails/Application Code Loading)|(Database/.*/.+ Columns)').duration <=>
232
232
  x.omit_segments_with('(Rails/Application Code Loading)|(Database/.*/.+ Columns)').duration} if params['h']
233
233
  return @samples = @samples.sort{|x,y| x.params[:uri] <=> y.params[:uri]} if params['u']
234
234
  @samples = @samples.reverse
235
235
  end
236
-
236
+
237
237
  def get_sample
238
238
  get_samples
239
239
  id = params['id']
@@ -245,13 +245,13 @@ class DeveloperMode
245
245
  end
246
246
  end
247
247
  end
248
-
248
+
249
249
  def get_segment
250
250
  get_sample
251
251
  return unless @sample
252
-
252
+
253
253
  segment_id = params['segment'].to_i
254
254
  @segment = @sample.find_segment(segment_id)
255
- end
255
+ end
256
256
  end
257
257
  end
@@ -5,9 +5,9 @@ module NewRelic
5
5
  def initialize(options)
6
6
  if options[:install]
7
7
  src = File.join(File.dirname(__FILE__), "newrelic.yml")
8
- require 'new_relic/command'
8
+ require 'new_relic/command'
9
9
  begin
10
- NewRelic::Command::Install.new(:quiet => true, :src_file => src).run
10
+ NewRelic::Command::Install.new(:quiet => true, :src_file => src).run
11
11
  NewRelic::Agent.logger.info "A newrelic.yml template was copied to #{File.expand_path('.')}."
12
12
  NewRelic::Agent.logger.info "Please add a license key to the file and restart #{$0}"
13
13
  exit 0