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.
- data/CHANGELOG +120 -35
- data/LICENSE +29 -2
- data/README.rdoc +2 -2
- data/bin/mongrel_rpm +0 -0
- data/bin/newrelic +0 -0
- data/bin/newrelic_cmd +0 -0
- data/lib/new_relic/agent.rb +50 -38
- data/lib/new_relic/agent/agent.rb +459 -337
- data/lib/new_relic/agent/beacon_configuration.rb +71 -11
- data/lib/new_relic/agent/browser_monitoring.rb +73 -14
- data/lib/new_relic/agent/busy_calculator.rb +11 -3
- data/lib/new_relic/agent/chained_call.rb +2 -2
- data/lib/new_relic/agent/database.rb +223 -0
- data/lib/new_relic/agent/error_collector.rb +231 -183
- data/lib/new_relic/agent/instrumentation.rb +2 -2
- data/lib/new_relic/agent/instrumentation/active_merchant.rb +10 -2
- data/lib/new_relic/agent/instrumentation/active_record.rb +138 -0
- data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +7 -1
- data/lib/new_relic/agent/instrumentation/authlogic.rb +6 -0
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +46 -14
- data/lib/new_relic/agent/instrumentation/data_mapper.rb +8 -2
- data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +11 -3
- data/lib/new_relic/agent/instrumentation/memcache.rb +49 -25
- data/lib/new_relic/agent/instrumentation/merb/controller.rb +7 -2
- data/lib/new_relic/agent/instrumentation/merb/errors.rb +7 -1
- data/lib/new_relic/agent/instrumentation/metric_frame.rb +31 -4
- data/lib/new_relic/agent/instrumentation/metric_frame/pop.rb +1 -5
- data/lib/new_relic/agent/instrumentation/net.rb +8 -2
- data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +5 -2
- data/lib/new_relic/agent/instrumentation/queue_time.rb +1 -1
- data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +66 -35
- data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +7 -1
- data/lib/new_relic/agent/instrumentation/rails/errors.rb +7 -1
- data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +121 -1
- data/lib/new_relic/agent/instrumentation/rails3/errors.rb +7 -1
- data/lib/new_relic/agent/instrumentation/rainbows_instrumentation.rb +21 -0
- data/lib/new_relic/agent/instrumentation/resque.rb +80 -0
- data/lib/new_relic/agent/instrumentation/sinatra.rb +46 -20
- data/lib/new_relic/agent/instrumentation/sunspot.rb +6 -0
- data/lib/new_relic/agent/instrumentation/unicorn_instrumentation.rb +7 -2
- data/lib/new_relic/agent/method_tracer.rb +205 -99
- data/lib/new_relic/agent/new_relic_service.rb +221 -0
- data/lib/new_relic/agent/pipe_channel_manager.rb +161 -0
- data/lib/new_relic/agent/pipe_service.rb +54 -0
- data/lib/new_relic/agent/samplers/delayed_job_sampler.rb +89 -0
- data/lib/new_relic/agent/samplers/memory_sampler.rb +6 -7
- data/lib/new_relic/agent/shim_agent.rb +5 -5
- data/lib/new_relic/agent/sql_sampler.rb +282 -0
- data/lib/new_relic/agent/stats_engine.rb +2 -0
- data/lib/new_relic/agent/stats_engine/gc_profiler.rb +123 -0
- data/lib/new_relic/agent/stats_engine/metric_stats.rb +35 -30
- data/lib/new_relic/agent/stats_engine/samplers.rb +10 -4
- data/lib/new_relic/agent/stats_engine/transactions.rb +28 -87
- data/lib/new_relic/agent/transaction_info.rb +74 -0
- data/lib/new_relic/agent/transaction_sample_builder.rb +18 -3
- data/lib/new_relic/agent/transaction_sampler.rb +108 -20
- data/lib/new_relic/agent/worker_loop.rb +14 -6
- data/lib/new_relic/collection_helper.rb +19 -11
- data/lib/new_relic/command.rb +1 -1
- data/lib/new_relic/commands/deployments.rb +2 -2
- data/lib/new_relic/commands/install.rb +2 -13
- data/lib/new_relic/control.rb +2 -3
- data/lib/new_relic/control/class_methods.rb +12 -6
- data/lib/new_relic/control/configuration.rb +57 -8
- data/lib/new_relic/control/frameworks.rb +10 -0
- data/lib/new_relic/control/frameworks/external.rb +4 -4
- data/lib/new_relic/control/frameworks/merb.rb +2 -1
- data/lib/new_relic/control/frameworks/rails.rb +35 -22
- data/lib/new_relic/control/frameworks/rails3.rb +12 -7
- data/lib/new_relic/control/frameworks/ruby.rb +5 -5
- data/lib/new_relic/control/frameworks/sinatra.rb +1 -4
- data/lib/new_relic/control/instance_methods.rb +38 -12
- data/lib/new_relic/control/instrumentation.rb +23 -4
- data/lib/new_relic/control/logging_methods.rb +70 -15
- data/lib/new_relic/control/server_methods.rb +22 -9
- data/lib/new_relic/delayed_job_injection.rb +16 -3
- data/lib/new_relic/helper.rb +21 -0
- data/lib/new_relic/language_support.rb +95 -0
- data/lib/new_relic/local_environment.rb +92 -48
- data/lib/new_relic/metric_data.rb +7 -2
- data/lib/new_relic/metric_spec.rb +12 -9
- data/lib/new_relic/noticed_error.rb +6 -1
- data/lib/new_relic/rack/browser_monitoring.rb +18 -19
- data/lib/new_relic/rack/developer_mode.rb +3 -2
- data/lib/new_relic/recipes.rb +8 -4
- data/lib/new_relic/stats.rb +17 -60
- data/lib/new_relic/transaction_analysis.rb +2 -1
- data/lib/new_relic/transaction_analysis/segment_summary.rb +4 -2
- data/lib/new_relic/transaction_sample.rb +60 -75
- data/lib/new_relic/transaction_sample/segment.rb +31 -79
- data/lib/new_relic/version.rb +2 -2
- data/lib/newrelic_rpm.rb +1 -1
- data/newrelic.yml +2 -2
- data/newrelic_rpm.gemspec +46 -54
- data/test/active_record_fixtures.rb +3 -3
- data/test/config/newrelic.yml +1 -1
- data/test/fixtures/proc_cpuinfo.txt +575 -0
- data/test/new_relic/agent/agent/connect_test.rb +128 -25
- data/test/new_relic/agent/agent/start_test.rb +9 -94
- data/test/new_relic/agent/agent/start_worker_thread_test.rb +2 -4
- data/test/new_relic/agent/agent_test.rb +51 -78
- data/test/new_relic/agent/agent_test_controller.rb +1 -1
- data/test/new_relic/agent/agent_test_controller_test.rb +49 -33
- data/test/new_relic/agent/beacon_configuration_test.rb +12 -5
- data/test/new_relic/agent/browser_monitoring_test.rb +99 -50
- data/test/new_relic/agent/database_test.rb +161 -0
- data/test/new_relic/agent/error_collector_test.rb +47 -23
- data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +96 -42
- data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +0 -2
- data/test/new_relic/agent/instrumentation/instrumentation_test.rb +1 -1
- data/test/new_relic/agent/instrumentation/metric_frame/pop_test.rb +3 -11
- data/test/new_relic/agent/instrumentation/net_instrumentation_test.rb +9 -9
- data/test/new_relic/agent/instrumentation/queue_time_test.rb +6 -11
- data/test/new_relic/agent/memcache_instrumentation_test.rb +54 -18
- data/test/new_relic/agent/method_tracer/class_methods/add_method_tracer_test.rb +1 -1
- data/test/new_relic/agent/method_tracer/instance_methods/trace_execution_scoped_test.rb +1 -1
- data/test/new_relic/agent/method_tracer_test.rb +3 -2
- data/test/new_relic/agent/new_relic_service_test.rb +151 -0
- data/test/new_relic/agent/pipe_channel_manager_test.rb +114 -0
- data/test/new_relic/agent/pipe_service_test.rb +113 -0
- data/test/new_relic/agent/rpm_agent_test.rb +4 -31
- data/test/new_relic/agent/sql_sampler_test.rb +192 -0
- data/test/new_relic/agent/stats_engine/metric_stats_test.rb +19 -18
- data/test/new_relic/agent/stats_engine_test.rb +41 -6
- data/test/new_relic/agent/transaction_info_test.rb +13 -0
- data/test/new_relic/agent/transaction_sample_builder_test.rb +27 -4
- data/test/new_relic/agent/transaction_sampler_test.rb +68 -46
- data/test/new_relic/agent/worker_loop_test.rb +3 -3
- data/test/new_relic/agent_test.rb +242 -0
- data/test/new_relic/collection_helper_test.rb +50 -28
- data/test/new_relic/control/configuration_test.rb +77 -0
- data/test/new_relic/control/logging_methods_test.rb +49 -21
- data/test/new_relic/control_test.rb +115 -54
- data/test/new_relic/delayed_job_injection_test.rb +21 -0
- data/test/new_relic/fake_collector.rb +210 -0
- data/test/new_relic/fake_service.rb +44 -0
- data/test/new_relic/local_environment_test.rb +14 -1
- data/test/new_relic/metric_parser/metric_parser_test.rb +11 -0
- data/test/new_relic/rack/browser_monitoring_test.rb +84 -23
- data/test/new_relic/rack/developer_mode_helper_test.rb +141 -0
- data/test/new_relic/rack/developer_mode_test.rb +31 -0
- data/test/new_relic/stats_test.rb +3 -18
- data/test/new_relic/transaction_analysis/segment_summary_test.rb +14 -0
- data/test/new_relic/transaction_analysis_test.rb +3 -3
- data/test/new_relic/transaction_sample/segment_test.rb +15 -80
- data/test/new_relic/transaction_sample_test.rb +25 -18
- data/test/script/build_test_gem.sh +51 -0
- data/test/script/ci.sh +140 -0
- data/test/script/ci_agent-tests_runner.sh +82 -0
- data/test/script/ci_bench.sh +52 -0
- data/test/script/ci_multiverse_runner.sh +63 -0
- data/test/test_contexts.rb +1 -0
- data/test/test_helper.rb +18 -5
- data/ui/helpers/developer_mode_helper.rb +14 -8
- data/ui/helpers/google_pie_chart.rb +0 -1
- data/ui/views/newrelic/index.rhtml +2 -2
- data/vendor/gems/dependency_detection-0.0.1.build/LICENSE +4 -18
- data/vendor/gems/dependency_detection-0.0.1.build/lib/dependency_detection.rb +10 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/mem_cache.rb +11 -11
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/metric_parser.rb +17 -4
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/view.rb +4 -0
- metadata +50 -36
- data/lib/new_relic/agent/instrumentation/rails/active_record_instrumentation.rb +0 -108
- data/lib/new_relic/agent/instrumentation/rails3/active_record_instrumentation.rb +0 -112
- data/lib/new_relic/agent/samplers/delayed_job_lock_sampler.rb +0 -40
- data/lib/new_relic/data_serialization.rb +0 -84
- data/lib/new_relic/histogram.rb +0 -91
- data/lib/new_relic/rack/metric_app.rb +0 -65
- data/lib/new_relic/rack/mongrel_rpm.ru +0 -28
- data/lib/new_relic/rack/newrelic.yml +0 -27
- data/lib/new_relic/rack_app.rb +0 -6
- data/test/new_relic/data_serialization_test.rb +0 -70
- data/vendor/gems/dependency_detection-0.0.1.build/README +0 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/LICENSE +0 -0
- 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
|
-
|
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
|
-
|
162
|
-
|
163
|
-
|
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
|
-
|
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
|
-
|
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
|
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=
|
4
|
-
DEFAULT_ARRAY_TRUNCATION_SIZE=
|
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.
|
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.
|
45
|
+
backtrace = backtrace.collect {|line| line.gsub(/_without_(newrelic|trace)/, "")}
|
38
46
|
end
|
39
47
|
backtrace
|
40
48
|
end
|
data/lib/new_relic/command.rb
CHANGED
@@ -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
|
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
|
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
|
data/lib/new_relic/control.rb
CHANGED
@@ -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
|
-
|
6
|
-
|
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}"
|