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
@@ -1,9 +1,12 @@
1
1
  require 'new_relic/agent'
2
2
  require 'new_relic/control'
3
3
  require 'new_relic/agent/transaction_sample_builder'
4
+
4
5
  module NewRelic
5
6
  module Agent
6
7
 
8
+ # This class contains the logic of sampling a transaction -
9
+ # creation and modification of transaction samples
7
10
  class TransactionSampler
8
11
 
9
12
  # Module defining methods stubbed out when the agent is disabled
@@ -17,12 +20,16 @@ module NewRelic
17
20
  BUILDER_KEY = :transaction_sample_builder
18
21
 
19
22
  attr_accessor :stack_trace_threshold, :random_sampling, :sampling_rate
23
+ attr_accessor :explain_threshold, :explain_enabled, :transaction_threshold
24
+ attr_accessor :slow_capture_threshold
20
25
  attr_reader :samples, :last_sample, :disabled
21
26
 
22
27
  def initialize
28
+
23
29
  # @samples is an array of recent samples up to @max_samples in
24
30
  # size - it's only used by developer mode
25
31
  @samples = []
32
+ @force_persist = []
26
33
  @max_samples = 100
27
34
 
28
35
  # @harvest_count is a count of harvests used for random
@@ -30,14 +37,8 @@ module NewRelic
30
37
  @harvest_count = 0
31
38
  @random_sample = nil
32
39
  @sampling_rate = 10
33
-
34
- # @segment_limit and @stack_trace_threshold come from the
35
- # configuration file, with built-in defaults that should
36
- # suffice for most customers
37
- config = NewRelic::Control.instance
38
- sampler_config = config.fetch('transaction_tracer', {})
39
- @segment_limit = sampler_config.fetch('limit_segments', 4000)
40
- @stack_trace_threshold = sampler_config.fetch('stack_trace_threshold', 0.500).to_f
40
+ @slow_capture_threshold = 2.0
41
+ configure!
41
42
 
42
43
  # This lock is used to synchronize access to the @last_sample
43
44
  # and related variables. It can become necessary on JRuby or
@@ -45,6 +46,30 @@ module NewRelic
45
46
  @samples_lock = Mutex.new
46
47
  end
47
48
 
49
+ def configure!
50
+ # @segment_limit and @stack_trace_threshold come from the
51
+ # configuration file, with built-in defaults that should
52
+ # suffice for most customers
53
+
54
+ # enable if config.fetch('enabled', true)
55
+
56
+ @segment_limit = config.fetch('limit_segments', 4000)
57
+ @stack_trace_threshold = config.fetch('stack_trace_threshold', 0.500).to_f
58
+ @explain_threshold = config.fetch('explain_threshold', 0.5).to_f
59
+ @explain_enabled = config.fetch('explain_enabled', true)
60
+ @transaction_threshold = config.fetch('transation_threshold', 2.0)
61
+
62
+ # Configure the sample storage policy. Create a list of methods to be called.
63
+ @store_sampler_methods = [ :store_random_sample, :store_slowest_sample ]
64
+ if NewRelic::Control.instance.developer_mode?
65
+ @store_sampler_methods << :store_sample_for_developer_mode
66
+ end
67
+ end
68
+
69
+ def config
70
+ NewRelic::Control.instance.fetch('transaction_tracer', {})
71
+ end
72
+
48
73
  # Returns the current sample id, delegated from `builder`
49
74
  def current_sample_id
50
75
  b=builder
@@ -65,6 +90,10 @@ module NewRelic
65
90
  NewRelic::Agent.instance.stats_engine.remove_transaction_sampler(self)
66
91
  end
67
92
 
93
+ def enabled?
94
+ !@disabled
95
+ end
96
+
68
97
  # Set with an integer value n, this takes one in every n
69
98
  # harvested samples. It also resets the harvest count to a
70
99
  # random integer between 0 and (n-1)
@@ -137,7 +166,6 @@ module NewRelic
137
166
  # It sets various instance variables to the finished sample,
138
167
  # depending on which settings are active. See `store_sample`
139
168
  def notice_scope_empty(time=Time.now)
140
-
141
169
  last_builder = builder
142
170
  return unless last_builder
143
171
 
@@ -158,9 +186,11 @@ module NewRelic
158
186
  # @samples array, and the @slowest_sample variable if it is
159
187
  # slower than the current occupant of that slot
160
188
  def store_sample(sample)
161
- store_random_sample(sample)
162
- store_sample_for_developer_mode(sample)
163
- store_slowest_sample(sample)
189
+ @store_sampler_methods.each{|sym| send sym, sample}
190
+ if NewRelic::Agent::TransactionInfo.get.force_persist_sample?(sample)
191
+ store_force_persist(sample)
192
+ end
193
+
164
194
  end
165
195
 
166
196
  # Only active when random sampling is true - this is very rarely
@@ -172,6 +202,16 @@ module NewRelic
172
202
  end
173
203
  end
174
204
 
205
+ def store_force_persist(sample)
206
+ @force_persist << sample
207
+
208
+ # WARNING - this clamp should be configurable
209
+ if @force_persist.length > 15
210
+ @force_persist.sort! {|a,b| b.duration <=> a.duration}
211
+ @force_persist = @force_persist[0..14]
212
+ end
213
+ end
214
+
175
215
  # Samples take up a ton of memory, so we only store a lot of
176
216
  # them in developer mode - we truncate to @max_samples
177
217
  def store_sample_for_developer_mode(sample)
@@ -184,7 +224,9 @@ module NewRelic
184
224
  # Sets @slowest_sample to the passed in sample if it is slower
185
225
  # than the current sample in @slowest_sample
186
226
  def store_slowest_sample(sample)
187
- @slowest_sample = sample if slowest_sample?(@slowest_sample, sample)
227
+ if slowest_sample?(@slowest_sample, sample)
228
+ @slowest_sample = sample
229
+ end
188
230
  end
189
231
 
190
232
  # Checks to see if the old sample exists, or if it's duration is
@@ -234,7 +276,14 @@ module NewRelic
234
276
  return unless builder
235
277
  segment = builder.current_segment
236
278
  if segment
237
- segment[key] = truncate_message(append_new_message(segment[key], message))
279
+ new_message = truncate_message(append_new_message(segment[key],
280
+ message))
281
+ if key == :sql && config.respond_to?(:has_key?) && config.has_key?(:adapter)
282
+ segment[key] = Database::Statement.new(new_message)
283
+ segment[key].adapter = config[:adapter]
284
+ else
285
+ segment[key] = new_message
286
+ end
238
287
  segment[config_key] = config if config_key
239
288
  append_backtrace(segment, duration)
240
289
  end
@@ -266,7 +315,7 @@ module NewRelic
266
315
  # Appends a backtrace to a segment if that segment took longer
267
316
  # than the specified duration
268
317
  def append_backtrace(segment, duration)
269
- segment[:backtrace] = caller.join("\n") if duration >= @stack_trace_threshold
318
+ segment[:backtrace] = caller.join("\n") if (duration >= @stack_trace_threshold || Thread.current[:capture_deep_tt])
270
319
  end
271
320
 
272
321
  # some statements (particularly INSERTS with large BLOBS
@@ -298,24 +347,41 @@ module NewRelic
298
347
  @harvest_count += 1
299
348
  if (@harvest_count.to_i % @sampling_rate.to_i) == 0
300
349
  result << @random_sample if @random_sample
350
+ @harvest_count = 0
301
351
  end
302
- result.uniq!
303
352
  nil # don't assume this method returns anything
304
353
  end
305
354
 
355
+ def add_force_persist_to(result)
356
+ result.concat(@force_persist)
357
+ @force_persist = []
358
+ end
359
+
306
360
  # Returns an array of slow samples, with either one or two
307
361
  # elements - one element unless random sampling is enabled. The
308
362
  # sample returned will be the slowest sample among those
309
363
  # available during this harvest
310
364
  def add_samples_to(result, slow_threshold)
365
+ # pull out force persist
366
+ force_persist = result.select {|sample| sample.force_persist} || []
367
+ result.reject! {|sample| sample.force_persist}
368
+
369
+ force_persist.each {|sample| store_force_persist(sample)}
370
+
371
+
372
+ # Now get the slowest sample
311
373
  if @slowest_sample && @slowest_sample.duration >= slow_threshold
312
374
  result << @slowest_sample
313
375
  end
376
+
314
377
  result.compact!
315
378
  result = result.sort_by { |x| x.duration }
316
- result = result[-1..-1] || []
379
+ result = result[-1..-1] || [] # take the slowest sample
380
+
317
381
  add_random_sample_to(result)
318
- result
382
+ add_force_persist_to(result)
383
+
384
+ result.uniq
319
385
  end
320
386
 
321
387
  # get the set of collected samples, merging into previous samples,
@@ -325,19 +391,43 @@ module NewRelic
325
391
  def harvest(previous = [], slow_threshold = 2.0)
326
392
  return [] if disabled
327
393
  result = Array(previous)
394
+
328
395
  @samples_lock.synchronize do
329
396
  result = add_samples_to(result, slow_threshold)
397
+
330
398
  # clear previous transaction samples
331
399
  @slowest_sample = nil
332
400
  @random_sample = nil
333
401
  @last_sample = nil
334
402
  end
403
+
404
+ # Clamp the number of TTs we'll keep in memory and send
405
+ #
406
+ result = clamp_number_tts(result, 20) if result.length > 20
407
+
335
408
  # Truncate the samples at 2100 segments. The UI will clamp them at 2000 segments anyway.
336
409
  # This will save us memory and bandwidth.
337
410
  result.each { |sample| sample.truncate(@segment_limit) }
338
411
  result
339
412
  end
340
413
 
414
+ # JON - THIS CODE NEEDS A UNIT TEST
415
+ def clamp_number_tts(tts, limit)
416
+ tts.sort! do |a,b|
417
+ if a.force_persist && b.force_persist
418
+ b.duration <=> a.duration
419
+ elsif a.force_persist
420
+ -1
421
+ elsif b.force_persist
422
+ 1
423
+ else
424
+ b.duration <=> a.duration
425
+ end
426
+ end
427
+
428
+ tts[0..(limit-1)]
429
+ end
430
+
341
431
  # reset samples without rebooting the web server
342
432
  def reset!
343
433
  @samples = []
@@ -346,8 +436,6 @@ module NewRelic
346
436
  @slowest_sample = nil
347
437
  end
348
438
 
349
- private
350
-
351
439
  # Checks to see if the transaction sampler is disabled, if
352
440
  # transaction trace recording is disabled by a thread local, or
353
441
  # if execution is untraced - if so it clears the transaction
@@ -12,14 +12,17 @@ module NewRelic
12
12
  @next_invocation_time = Time.now
13
13
  @period = 60.0
14
14
  end
15
-
15
+
16
+ # returns a class-level memoized mutex to make sure we don't run overlapping
16
17
  def lock
17
18
  @@lock ||= Mutex.new
18
19
  end
19
-
20
+
21
+ # a helper to access the NewRelic::Control.instance.log
20
22
  def log
21
23
  NewRelic::Control.instance.log
22
24
  end
25
+
23
26
  # Run infinitely, calling the registered tasks at their specified
24
27
  # call periods. The caller is responsible for creating the thread
25
28
  # that runs this worker loop. This will run the task immediately.
@@ -38,15 +41,20 @@ module NewRelic
38
41
  run_task if keep_running
39
42
  end
40
43
  end
41
-
44
+
45
+ # a simple accessor for @should_run
42
46
  def keep_running
43
47
  @should_run
44
48
  end
45
-
49
+
50
+ # Sets @should_run to false. Returns false
46
51
  def stop
47
52
  @should_run = false
48
53
  end
49
-
54
+
55
+ # Executes the block given to the worker loop, and handles many
56
+ # possible errors. Also updates the execution time so that the
57
+ # next run occurs on schedule, even if we execute at some odd time
50
58
  def run_task
51
59
  begin
52
60
  lock.synchronize do
@@ -66,7 +74,7 @@ module NewRelic
66
74
  # Want to ignore these because they are handled already
67
75
  rescue SystemExit, NoMemoryError, SignalException
68
76
  raise
69
- rescue Exception => e
77
+ rescue => e
70
78
  # Don't blow out the stack for anything that hasn't already propagated
71
79
  log.error "Error running task in Agent Worker Loop '#{e}': #{e.backtrace.first}"
72
80
  log.debug e.backtrace.join("\n")
@@ -1,23 +1,27 @@
1
+ require 'new_relic/control'
2
+
1
3
  module NewRelic
2
4
  module CollectionHelper
3
- DEFAULT_TRUNCATION_SIZE=256
4
- DEFAULT_ARRAY_TRUNCATION_SIZE=1024
5
+ DEFAULT_TRUNCATION_SIZE=16 * 1024
6
+ DEFAULT_ARRAY_TRUNCATION_SIZE=128
5
7
  # Transform parameter hash into a hash whose values are strictly
6
8
  # strings
7
9
  def normalize_params(params)
8
10
  case params
11
+ when Hash
12
+ # optimize for empty hash since that is often what this is called with.
13
+ return params if params.empty?
14
+ new_params = {}
15
+ params.each do | key, value |
16
+ new_params[truncate(normalize_params(key),64)] = normalize_params(value)
17
+ end
18
+ new_params
9
19
  when Symbol, FalseClass, TrueClass, nil
10
20
  params
11
21
  when Numeric
12
22
  truncate(params.to_s)
13
23
  when String
14
24
  truncate(params)
15
- when Hash
16
- new_params = {}
17
- params.each do | key, value |
18
- new_params[truncate(normalize_params(key),32)] = normalize_params(value)
19
- end
20
- new_params
21
25
  when Array
22
26
  params.first(DEFAULT_ARRAY_TRUNCATION_SIZE).map{|item| normalize_params(item)}
23
27
  else
@@ -29,12 +33,16 @@ module NewRelic
29
33
  # Return nil if there is no backtrace
30
34
 
31
35
  def strip_nr_from_backtrace(backtrace)
32
- if backtrace
36
+ if backtrace && !NewRelic::Control.instance.disable_backtrace_cleanup?
33
37
  # this is for 1.9.1, where strings no longer have Enumerable
34
38
  backtrace = backtrace.split("\n") if String === backtrace
35
- backtrace = backtrace.reject {|line| line =~ /new_?relic/ }
39
+ backtrace = backtrace.map &:to_s
40
+ backtrace = backtrace.reject do |line|
41
+ line.include?(NewRelic::Control.newrelic_root) or
42
+ line =~ /^newrelic_rpm\s/
43
+ end
36
44
  # rename methods back to their original state
37
- backtrace = backtrace.collect {|line| line.to_s.gsub(/_without_(newrelic|trace)/, "")}
45
+ backtrace = backtrace.collect {|line| line.gsub(/_without_(newrelic|trace)/, "")}
38
46
  end
39
47
  backtrace
40
48
  end
@@ -38,7 +38,7 @@ module NewRelic
38
38
  @leftover = @options.parse(command_line_args)
39
39
  end
40
40
  rescue OptionParser::ParseError => e
41
- raise CommandFailure.new e.message, @options
41
+ raise CommandFailure.new(e.message, @options)
42
42
  end
43
43
 
44
44
  @commands = []
@@ -17,7 +17,7 @@ class NewRelic::Command::Deployments < NewRelic::Command
17
17
  # Initialize the deployment uploader with command line args.
18
18
  # Use -h to see options.
19
19
  # When command_line_args is a hash, we are invoking directly and
20
- # it's treated as an options with optional sttring values for
20
+ # it's treated as an options with optional string values for
21
21
  # :user, :description, :appname, :revision, :environment,
22
22
  # and :changes.
23
23
  #
@@ -72,7 +72,7 @@ class NewRelic::Command::Deployments < NewRelic::Command
72
72
  raise NewRelic::Command::CommandFailure.new(err_string)
73
73
  rescue NewRelic::Command::CommandFailure
74
74
  raise
75
- rescue Exception => e
75
+ rescue => e
76
76
  err "Unexpected error attempting to connect to #{config.api_server}"
77
77
  info "#{e}: #{e.backtrace.join("\n ")}"
78
78
  raise NewRelic::Command::CommandFailure.new(e.to_s)
@@ -52,21 +52,10 @@ at www.newrelic.com, and replace the newrelic.yml file with the one
52
52
  you receive upon registration.
53
53
  EOF
54
54
  puts <<-EOF unless quiet
55
-
55
+
56
56
  E-mail support@newrelic.com with any problems or questions.
57
-
58
- EOF
59
- puts <<-EOF
60
-
61
- Installing the plugin from Rubyforge is deprecated. This repository will not be updated after January 2011
62
-
63
- Please use one of the following options:
64
-
65
- Gems: gem install newrelic_rpm
66
-
67
- Github! git clone git://github.com/newrelic/rpm.git vendor/plugins/newrelic_rpm
68
-
69
57
  EOF
58
+
70
59
  end
71
60
 
72
61
  def content
@@ -2,12 +2,14 @@ require 'yaml'
2
2
  require 'conditional_vendored_metric_parser'
3
3
  require 'conditional_vendored_dependency_detection'
4
4
  require 'new_relic/local_environment'
5
+ require 'new_relic/helper'
5
6
 
6
7
  require 'singleton'
7
8
  require 'erb'
8
9
  require 'socket'
9
10
  require 'net/https'
10
11
  require 'logger'
12
+ require 'new_relic/control/frameworks'
11
13
  require 'new_relic/control/profiling'
12
14
  require 'new_relic/control/logging_methods'
13
15
  require 'new_relic/control/configuration'
@@ -30,9 +32,6 @@ module NewRelic
30
32
  # The Control also implements some of the public API for the agent.
31
33
  #
32
34
  class Control
33
- # used for framework-specific subclasses
34
- module Frameworks; end
35
-
36
35
  # done in a subfile for load order purposes
37
36
  # extend ClassMethods
38
37
  # include InstanceMethods
@@ -1,16 +1,20 @@
1
1
  module NewRelic
2
2
  class Control
3
+ # class-level methods for lazy creation of NewRelic::Control and
4
+ # NewRelic::LocalEnvironment instances.
3
5
  module ClassMethods
4
- # Access the Control singleton, lazy initialized
5
- def instance
6
- @instance ||= new_instance
6
+ # Access the Control singleton, lazy initialized. Default will instantiate a new
7
+ # instance or pass false to defer
8
+ def instance(create=true)
9
+ @instance ||= create && new_instance
7
10
  end
8
-
11
+
12
+ # Access the LocalEnvironment singleton, lazy initialized
9
13
  def local_env
10
14
  @local_env ||= NewRelic::LocalEnvironment.new
11
15
  end
12
16
 
13
- # Create the concrete class for environment specific behavior:
17
+ # Create the concrete class for environment specific behavior
14
18
  def new_instance
15
19
  if local_env.framework == :test
16
20
  load_test_framework
@@ -25,7 +29,9 @@ module NewRelic
25
29
  require "config/test_control"
26
30
  NewRelic::Control::Frameworks::Test.new(local_env, config)
27
31
  end
28
-
32
+
33
+ # Loads the specified framework class from the
34
+ # NewRelic::Control::Frameworks module
29
35
  def load_framework_class(framework)
30
36
  begin
31
37
  require "new_relic/control/frameworks/#{framework}"