newrelic_rpm 3.1.0 → 3.1.1.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of newrelic_rpm might be problematic. Click here for more details.
- data/CHANGELOG +3 -0
- data/lib/new_relic/agent.rb +29 -12
- data/lib/new_relic/agent/agent.rb +355 -78
- data/lib/new_relic/agent/beacon_configuration.rb +49 -7
- data/lib/new_relic/agent/browser_monitoring.rb +20 -1
- 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/error_collector.rb +229 -183
- data/lib/new_relic/agent/instrumentation.rb +2 -2
- data/lib/new_relic/agent/instrumentation/active_merchant.rb +5 -1
- data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +5 -1
- data/lib/new_relic/agent/instrumentation/authlogic.rb +4 -0
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +16 -5
- data/lib/new_relic/agent/instrumentation/data_mapper.rb +5 -1
- data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +5 -1
- data/lib/new_relic/agent/instrumentation/memcache.rb +5 -1
- data/lib/new_relic/agent/instrumentation/merb/controller.rb +5 -1
- data/lib/new_relic/agent/instrumentation/merb/errors.rb +5 -1
- data/lib/new_relic/agent/instrumentation/metric_frame/pop.rb +0 -5
- data/lib/new_relic/agent/instrumentation/net.rb +5 -1
- data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +7 -3
- data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +5 -1
- data/lib/new_relic/agent/instrumentation/rails/active_record_instrumentation.rb +5 -1
- data/lib/new_relic/agent/instrumentation/rails/errors.rb +4 -0
- data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +4 -0
- data/lib/new_relic/agent/instrumentation/rails3/active_record_instrumentation.rb +13 -6
- data/lib/new_relic/agent/instrumentation/rails3/errors.rb +4 -0
- data/lib/new_relic/agent/instrumentation/sinatra.rb +4 -0
- data/lib/new_relic/agent/instrumentation/sunspot.rb +4 -0
- data/lib/new_relic/agent/instrumentation/unicorn_instrumentation.rb +5 -1
- data/lib/new_relic/agent/method_tracer.rb +205 -99
- data/lib/new_relic/agent/shim_agent.rb +0 -1
- data/lib/new_relic/agent/stats_engine.rb +1 -0
- data/lib/new_relic/agent/stats_engine/metric_stats.rb +23 -7
- data/lib/new_relic/agent/stats_engine/samplers.rb +8 -2
- data/lib/new_relic/agent/stats_engine/transactions.rb +26 -12
- data/lib/new_relic/agent/transaction_sampler.rb +3 -1
- data/lib/new_relic/agent/worker_loop.rb +13 -5
- data/lib/new_relic/collection_helper.rb +6 -3
- data/lib/new_relic/control.rb +1 -3
- data/lib/new_relic/control/class_methods.rb +8 -3
- data/lib/new_relic/control/configuration.rb +24 -5
- 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 +1 -0
- data/lib/new_relic/control/frameworks/rails.rb +5 -5
- data/lib/new_relic/control/frameworks/rails3.rb +5 -3
- 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 +23 -7
- data/lib/new_relic/control/instrumentation.rb +22 -3
- data/lib/new_relic/control/logging_methods.rb +25 -7
- data/lib/new_relic/control/server_methods.rb +16 -6
- data/lib/new_relic/data_serialization.rb +83 -14
- data/lib/new_relic/delayed_job_injection.rb +7 -1
- data/lib/new_relic/local_environment.rb +55 -25
- data/lib/new_relic/metric_data.rb +7 -2
- data/lib/new_relic/metric_spec.rb +5 -3
- data/lib/new_relic/stats.rb +16 -7
- 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 +33 -7
- data/lib/new_relic/transaction_sample/segment.rb +21 -3
- data/lib/new_relic/version.rb +2 -2
- data/newrelic_rpm.gemspec +7 -11
- data/test/config/newrelic.yml +1 -1
- data/test/new_relic/agent/agent/start_worker_thread_test.rb +1 -4
- data/test/new_relic/agent/agent_test.rb +16 -0
- data/test/new_relic/agent/agent_test_controller.rb +1 -1
- data/test/new_relic/agent/agent_test_controller_test.rb +14 -19
- data/test/new_relic/agent/beacon_configuration_test.rb +2 -2
- data/test/new_relic/agent/browser_monitoring_test.rb +7 -3
- data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +13 -4
- data/test/new_relic/agent/instrumentation/metric_frame/pop_test.rb +0 -10
- data/test/new_relic/agent/method_tracer/instance_methods/trace_execution_scoped_test.rb +1 -1
- data/test/new_relic/agent_test.rb +168 -0
- data/test/new_relic/collection_helper_test.rb +21 -3
- data/test/new_relic/control/configuration_test.rb +25 -0
- data/test/new_relic/data_serialization_test.rb +58 -3
- data/test/new_relic/delayed_job_injection_test.rb +17 -0
- 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 +11 -0
- data/test/test_helper.rb +1 -1
- data/vendor/gems/dependency_detection-0.0.1.build/LICENSE +4 -18
- metadata +13 -13
- 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/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
@@ -15,7 +15,13 @@ DependencyDetection.defer do
|
|
15
15
|
depends_on do
|
16
16
|
defined?(::Delayed) && defined?(::Delayed::Worker)
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
|
+
executes do
|
20
|
+
if NewRelic::Agent.respond_to?(:logger)
|
21
|
+
NewRelic::Agent.logger.debug 'Installing DelayedJob instrumentation hooks'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
19
25
|
executes do
|
20
26
|
Delayed::Worker.class_eval do
|
21
27
|
def initialize_with_new_relic(*args)
|
@@ -14,12 +14,16 @@ module NewRelic
|
|
14
14
|
#
|
15
15
|
# NewRelic::LocalEnvironment should be accessed through NewRelic::Control#env (via the NewRelic::Control singleton).
|
16
16
|
class LocalEnvironment
|
17
|
-
|
18
|
-
|
19
|
-
attr_accessor :
|
20
|
-
|
21
|
-
|
22
|
-
|
17
|
+
|
18
|
+
# mongrel, thin, webrick, or possibly nil
|
19
|
+
attr_accessor :dispatcher
|
20
|
+
# used to distinguish instances of a dispatcher from each other, may be nil
|
21
|
+
attr_writer :dispatcher_instance_id
|
22
|
+
# rails, rails3, merb, external, ruby, test, etc
|
23
|
+
attr_accessor :framework
|
24
|
+
# The number of cpus, if detected, or nil - many platforms do not
|
25
|
+
# support this :(
|
26
|
+
attr_reader :processors
|
23
27
|
alias environment dispatcher
|
24
28
|
|
25
29
|
def initialize
|
@@ -49,21 +53,27 @@ module NewRelic
|
|
49
53
|
# puts "#{e}\n #{e.backtrace.join("\n ")}"
|
50
54
|
raise if @framework == :test
|
51
55
|
end
|
52
|
-
|
56
|
+
|
57
|
+
# yields to the block and appends the returned value to the list
|
58
|
+
# of gems - this catches errors that might be raised in the block
|
53
59
|
def append_gem_list
|
54
60
|
@gems += yield
|
55
61
|
rescue Exception => e
|
56
62
|
# puts "#{e}\n #{e.backtrace.join("\n ")}"
|
57
63
|
raise if @framework == :test
|
58
64
|
end
|
59
|
-
|
65
|
+
|
66
|
+
# yields to the block and appends the returned value to the list
|
67
|
+
# of plugins - this catches errors that might be raised in the block
|
60
68
|
def append_plugin_list
|
61
69
|
@plugins += yield
|
62
70
|
rescue Exception
|
63
71
|
# puts "#{e}\n #{e.backtrace.join("\n ")}"
|
64
72
|
raise if @framework == :test
|
65
73
|
end
|
66
|
-
|
74
|
+
|
75
|
+
# An instance id pulled from either @dispatcher_instance_id or by
|
76
|
+
# splitting out the first part of the running file
|
67
77
|
def dispatcher_instance_id
|
68
78
|
if @dispatcher_instance_id.nil?
|
69
79
|
if @dispatcher.nil?
|
@@ -72,7 +82,9 @@ module NewRelic
|
|
72
82
|
end
|
73
83
|
@dispatcher_instance_id
|
74
84
|
end
|
75
|
-
|
85
|
+
|
86
|
+
# Interrogates some common ruby constants for useful information
|
87
|
+
# about what kind of ruby environment the agent is running in
|
76
88
|
def gather_ruby_info
|
77
89
|
append_environment_value('Ruby version'){ RUBY_VERSION }
|
78
90
|
append_environment_value('Ruby description'){ RUBY_DESCRIPTION } if defined? ::RUBY_DESCRIPTION
|
@@ -83,13 +95,14 @@ module NewRelic
|
|
83
95
|
gather_jruby_info
|
84
96
|
end
|
85
97
|
end
|
86
|
-
|
98
|
+
|
99
|
+
# like gather_ruby_info but for the special case of JRuby
|
87
100
|
def gather_jruby_info
|
88
101
|
append_environment_value('JRuby version') { JRUBY_VERSION }
|
89
102
|
append_environment_value('Java VM version') { ENV_JAVA['java.vm.version']}
|
90
103
|
end
|
91
104
|
|
92
|
-
# See what the number of cpus is, works only on linux
|
105
|
+
# See what the number of cpus is, works only on some linux variants
|
93
106
|
def gather_cpu_info
|
94
107
|
return unless File.readable? '/proc/cpuinfo'
|
95
108
|
@processors = append_environment_value('Processors') do
|
@@ -98,25 +111,30 @@ module NewRelic
|
|
98
111
|
processors
|
99
112
|
end
|
100
113
|
end
|
101
|
-
|
114
|
+
|
115
|
+
# Grabs the architecture string from either `uname -p` or the env
|
116
|
+
# variable PROCESSOR_ARCHITECTURE
|
102
117
|
def gather_architecture_info
|
103
118
|
append_environment_value('Arch') { `uname -p` } ||
|
104
119
|
append_environment_value('Arch') { ENV['PROCESSOR_ARCHITECTURE'] }
|
105
120
|
end
|
106
|
-
|
121
|
+
|
122
|
+
# gathers OS info from either `uname -v`, `uname -s`, or the OS
|
123
|
+
# env variable
|
107
124
|
def gather_os_info
|
108
125
|
append_environment_value('OS version') { `uname -v` }
|
109
126
|
append_environment_value('OS') { `uname -s` } ||
|
110
127
|
append_environment_value('OS') { ENV['OS'] }
|
111
128
|
end
|
112
|
-
|
129
|
+
|
130
|
+
# Gathers the architecture and cpu info
|
113
131
|
def gather_system_info
|
114
132
|
gather_architecture_info
|
115
133
|
gather_cpu_info
|
116
134
|
end
|
117
|
-
|
135
|
+
|
136
|
+
# Looks for a capistrano file indicating the current revision
|
118
137
|
def gather_revision_info
|
119
|
-
# Look for a capistrano file indicating the current revision:
|
120
138
|
rev_file = File.join(NewRelic::Control.instance.root, "REVISION")
|
121
139
|
if File.readable?(rev_file) && File.size(rev_file) < 64
|
122
140
|
append_environment_value('Revision') do
|
@@ -124,9 +142,11 @@ module NewRelic
|
|
124
142
|
end
|
125
143
|
end
|
126
144
|
end
|
127
|
-
|
145
|
+
|
146
|
+
# The name of the AR database adapter for the current environment and
|
147
|
+
# the current schema version
|
128
148
|
def gather_ar_adapter_info
|
129
|
-
|
149
|
+
|
130
150
|
append_environment_value 'Database adapter' do
|
131
151
|
if defined?(ActiveRecord) && defined?(ActiveRecord::Base) &&
|
132
152
|
ActiveRecord::Base.respond_to?(:configurations)
|
@@ -140,14 +160,17 @@ module NewRelic
|
|
140
160
|
ActiveRecord::Migrator.current_version
|
141
161
|
end
|
142
162
|
end
|
143
|
-
|
163
|
+
|
164
|
+
# Datamapper version
|
144
165
|
def gather_dm_adapter_info
|
145
166
|
append_environment_value 'DataMapper version' do
|
146
167
|
require 'dm-core/version'
|
147
168
|
DataMapper::VERSION
|
148
169
|
end
|
149
170
|
end
|
150
|
-
|
171
|
+
|
172
|
+
# sensing for which adapter is defined, then appends the relevant
|
173
|
+
# config information
|
151
174
|
def gather_db_info
|
152
175
|
# room here for more database adapters, when.
|
153
176
|
if defined? ::ActiveRecord
|
@@ -181,17 +204,22 @@ module NewRelic
|
|
181
204
|
i << [ 'Gems', @gems.to_a] if not @gems.empty?
|
182
205
|
i
|
183
206
|
end
|
184
|
-
|
207
|
+
|
208
|
+
# it's a working jruby if it has the runtime method, and object
|
209
|
+
# space is enabled
|
185
210
|
def working_jruby?
|
186
211
|
!(defined?(::JRuby) && JRuby.respond_to?(:runtime) && !JRuby.runtime.is_object_space_enabled)
|
187
212
|
end
|
188
|
-
|
213
|
+
|
214
|
+
# Runs through all the objects in ObjectSpace to find the first one that
|
215
|
+
# match the provided class
|
189
216
|
def find_class_in_object_space(klass)
|
190
217
|
ObjectSpace.each_object(klass) do |x|
|
191
218
|
return x
|
192
219
|
end
|
193
220
|
end
|
194
|
-
|
221
|
+
|
222
|
+
# Sets the @mongrel instance variable if we can find a Mongrel::HttpServer
|
195
223
|
def mongrel
|
196
224
|
return @mongrel if @mongrel
|
197
225
|
if defined?(::Mongrel) && defined?(::Mongrel::HttpServer) && working_jruby?
|
@@ -199,7 +227,8 @@ module NewRelic
|
|
199
227
|
end
|
200
228
|
@mongrel
|
201
229
|
end
|
202
|
-
|
230
|
+
|
231
|
+
# sets the @unicorn instance variable if we can find a Unicorn::HttpServer
|
203
232
|
def unicorn
|
204
233
|
return @unicorn if @unicorn
|
205
234
|
if (defined?(::Unicorn) && defined?(::Unicorn::HttpServer)) && working_jruby?
|
@@ -379,6 +408,7 @@ module NewRelic
|
|
379
408
|
end
|
380
409
|
|
381
410
|
public
|
411
|
+
# outputs a human-readable description
|
382
412
|
def to_s
|
383
413
|
s = "LocalEnvironment["
|
384
414
|
s << @framework.to_s
|
@@ -1,7 +1,10 @@
|
|
1
1
|
module NewRelic
|
2
2
|
class MetricData
|
3
|
+
# nil, or a NewRelic::MetricSpec object if we have no cached ID
|
3
4
|
attr_accessor :metric_spec
|
5
|
+
# nil or a cached integer ID for the metric from the collector.
|
4
6
|
attr_accessor :metric_id
|
7
|
+
# the actual statistics object
|
5
8
|
attr_accessor :stats
|
6
9
|
|
7
10
|
def initialize(metric_spec, stats, metric_id)
|
@@ -17,7 +20,9 @@ module NewRelic
|
|
17
20
|
def original_spec
|
18
21
|
@original_spec || @metric_spec
|
19
22
|
end
|
20
|
-
|
23
|
+
|
24
|
+
# assigns a new metric spec, and retains the old metric spec as
|
25
|
+
# @original_spec if it exists currently
|
21
26
|
def metric_spec= new_spec
|
22
27
|
@original_spec = @metric_spec if @metric_spec
|
23
28
|
@metric_spec = new_spec
|
@@ -31,7 +36,7 @@ module NewRelic
|
|
31
36
|
def to_json(*a)
|
32
37
|
%Q[{"metric_spec":#{metric_id ? 'null' : metric_spec.to_json},"stats":{"total_exclusive_time":#{stats.total_exclusive_time},"min_call_time":#{stats.min_call_time},"call_count":#{stats.call_count},"sum_of_squares":#{stats.sum_of_squares},"total_call_time":#{stats.total_call_time},"max_call_time":#{stats.max_call_time}},"metric_id":#{metric_id ? metric_id : 'null'}}]
|
33
38
|
end
|
34
|
-
|
39
|
+
|
35
40
|
def to_s
|
36
41
|
if metric_spec
|
37
42
|
"#{metric_spec.name}(#{metric_spec.scope}): #{stats}"
|
@@ -3,7 +3,8 @@
|
|
3
3
|
class NewRelic::MetricSpec
|
4
4
|
attr_accessor :name
|
5
5
|
attr_accessor :scope
|
6
|
-
|
6
|
+
|
7
|
+
# the maximum length of a metric name or metric scope
|
7
8
|
MAX_LENGTH = 255
|
8
9
|
# Need a "zero-arg" constructor so it can be instantiated from java (using
|
9
10
|
# jruby) for sending responses to ruby agents from the java collector.
|
@@ -12,12 +13,13 @@ class NewRelic::MetricSpec
|
|
12
13
|
self.name = (metric_name || '') && metric_name[0...MAX_LENGTH]
|
13
14
|
self.scope = metric_scope && metric_scope[0...MAX_LENGTH]
|
14
15
|
end
|
15
|
-
|
16
|
+
|
17
|
+
# truncates the name and scope to the MAX_LENGTH
|
16
18
|
def truncate!
|
17
19
|
self.name = name[0...MAX_LENGTH] if name && name.size > MAX_LENGTH
|
18
20
|
self.scope = scope[0...MAX_LENGTH] if scope && scope.size > MAX_LENGTH
|
19
21
|
end
|
20
|
-
|
22
|
+
|
21
23
|
def ==(o)
|
22
24
|
self.eql?(o)
|
23
25
|
end
|
data/lib/new_relic/stats.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
|
2
2
|
module NewRelic
|
3
3
|
module Stats
|
4
|
-
|
4
|
+
|
5
|
+
# a stat is absent if its call count equals zero
|
5
6
|
def absent?
|
6
|
-
# guess on absent values
|
7
7
|
call_count == 0
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
|
+
# outputs a useful human-readable time given a value in milliseconds
|
10
11
|
def time_str(value_ms)
|
11
12
|
case
|
12
13
|
when value_ms >= 10000
|
@@ -26,7 +27,7 @@ module NewRelic
|
|
26
27
|
numerator.to_f / denominator
|
27
28
|
end
|
28
29
|
end
|
29
|
-
|
30
|
+
|
30
31
|
def average_call_time
|
31
32
|
checked_calculation(total_call_time, call_count)
|
32
33
|
end
|
@@ -336,7 +337,10 @@ module NewRelic
|
|
336
337
|
end
|
337
338
|
|
338
339
|
alias trace_call record_data_point
|
339
|
-
|
340
|
+
|
341
|
+
# Records multiple data points as one method call - this handles
|
342
|
+
# all the aggregation that would be done with multiple
|
343
|
+
# record_data_point calls
|
340
344
|
def record_multiple_data_points(total_value, count=1)
|
341
345
|
return record_data_point(total_value) if count == 1
|
342
346
|
@call_count += count
|
@@ -348,11 +352,13 @@ module NewRelic
|
|
348
352
|
@sum_of_squares += (avg_val * avg_val) * count
|
349
353
|
self
|
350
354
|
end
|
351
|
-
|
355
|
+
|
356
|
+
# increments the call_count by one
|
352
357
|
def increment_count(value = 1)
|
353
358
|
@call_count += value
|
354
359
|
end
|
355
|
-
|
360
|
+
|
361
|
+
# outputs a human-readable version of the MethodTraceStats object
|
356
362
|
def inspect
|
357
363
|
"#<NewRelic::MethodTraceStats #{summary} >"
|
358
364
|
end
|
@@ -369,6 +375,9 @@ module NewRelic
|
|
369
375
|
unscoped_stats.trace_call call_time, exclusive_time
|
370
376
|
super call_time, exclusive_time
|
371
377
|
end
|
378
|
+
# Records multiple data points as one method call - this handles
|
379
|
+
# all the aggregation that would be done with multiple
|
380
|
+
# trace_call calls
|
372
381
|
def record_multiple_data_points(total_value, count=1)
|
373
382
|
unscoped_stats.record_multiple_data_points(total_value, count)
|
374
383
|
super total_value, count
|
@@ -15,11 +15,12 @@ module NewRelic
|
|
15
15
|
# limit the data set to the top n
|
16
16
|
def breakdown_data(limit = nil)
|
17
17
|
metric_hash = {}
|
18
|
-
|
18
|
+
each_segment_with_nest_tracking do |segment|
|
19
19
|
unless segment == root_segment
|
20
20
|
metric_name = segment.metric_name
|
21
21
|
metric_hash[metric_name] ||= SegmentSummary.new(metric_name, self)
|
22
22
|
metric_hash[metric_name] << segment
|
23
|
+
metric_hash[metric_name]
|
23
24
|
end
|
24
25
|
end
|
25
26
|
|
@@ -3,11 +3,12 @@ module NewRelic
|
|
3
3
|
# summarizes performance data for all calls to segments
|
4
4
|
# with the same metric_name
|
5
5
|
class SegmentSummary
|
6
|
-
attr_accessor :metric_name, :total_time, :exclusive_time, :call_count
|
6
|
+
attr_accessor :metric_name, :total_time, :exclusive_time, :call_count, :current_nest_count
|
7
7
|
def initialize(metric_name, sample)
|
8
8
|
@metric_name = metric_name
|
9
9
|
@total_time, @exclusive_time, @call_count = 0,0,0
|
10
10
|
@sample = sample
|
11
|
+
@current_nest_count = 0
|
11
12
|
end
|
12
13
|
|
13
14
|
def <<(segment)
|
@@ -15,7 +16,8 @@ module NewRelic
|
|
15
16
|
raise ArgumentError, "Metric Name Mismatch: #{segment.metric_name} != #{metric_name}"
|
16
17
|
end
|
17
18
|
|
18
|
-
|
19
|
+
# a nested segment should use the sum of the top level totals
|
20
|
+
@total_time += segment.duration if current_nest_count == 0
|
19
21
|
@exclusive_time += segment.exclusive_duration
|
20
22
|
@call_count += 1
|
21
23
|
end
|
@@ -3,8 +3,11 @@ require 'new_relic/transaction_sample/summary_segment'
|
|
3
3
|
require 'new_relic/transaction_sample/fake_segment'
|
4
4
|
require 'new_relic/transaction_sample/composite_segment'
|
5
5
|
module NewRelic
|
6
|
+
# the number of segments that need to exist before we roll them up
|
7
|
+
# into one segment with multiple executions
|
6
8
|
COLLAPSE_SEGMENTS_THRESHOLD = 2
|
7
9
|
|
10
|
+
# columns for a mysql explain plan
|
8
11
|
MYSQL_EXPLAIN_COLUMNS = [
|
9
12
|
"Id",
|
10
13
|
"Select Type",
|
@@ -34,7 +37,11 @@ module NewRelic
|
|
34
37
|
def obfuscate_sql(sql)
|
35
38
|
NewRelic::Agent.instance.obfuscator.call(sql)
|
36
39
|
end
|
37
|
-
|
40
|
+
|
41
|
+
# Returns a cached connection for a given ActiveRecord
|
42
|
+
# configuration - these are stored or reopened as needed, and if
|
43
|
+
# we cannot get one, we ignore it and move on without explaining
|
44
|
+
# the sql
|
38
45
|
def get_connection(config)
|
39
46
|
@@connections ||= {}
|
40
47
|
|
@@ -51,7 +58,8 @@ module NewRelic
|
|
51
58
|
nil
|
52
59
|
end
|
53
60
|
end
|
54
|
-
|
61
|
+
|
62
|
+
# Closes all the connections in the internal connection cache
|
55
63
|
def close_connections
|
56
64
|
@@connections ||= {}
|
57
65
|
@@connections.values.each do |connection|
|
@@ -77,7 +85,10 @@ module NewRelic
|
|
77
85
|
def count_segments
|
78
86
|
@root_segment.count_segments - 1 # don't count the root segment
|
79
87
|
end
|
80
|
-
|
88
|
+
|
89
|
+
# Truncates the transaction sample to a maximum length determined
|
90
|
+
# by the passed-in parameter. Operates recursively on the entire
|
91
|
+
# tree of transaction segments in a depth-first manner
|
81
92
|
def truncate(max)
|
82
93
|
count = count_segments
|
83
94
|
return if count < max
|
@@ -85,7 +96,9 @@ module NewRelic
|
|
85
96
|
|
86
97
|
ensure_segment_count_set(count)
|
87
98
|
end
|
88
|
-
|
99
|
+
|
100
|
+
# makes sure that the parameter cache for segment count is set to
|
101
|
+
# the correct value
|
89
102
|
def ensure_segment_count_set(count)
|
90
103
|
params[:segment_count] ||= count
|
91
104
|
end
|
@@ -122,15 +135,25 @@ module NewRelic
|
|
122
135
|
def duration
|
123
136
|
root_segment.duration
|
124
137
|
end
|
125
|
-
|
138
|
+
|
139
|
+
# Iterates recursively over each segment in the entire transaction
|
140
|
+
# sample tree
|
126
141
|
def each_segment(&block)
|
127
142
|
@root_segment.each_segment(&block)
|
128
143
|
end
|
129
144
|
|
145
|
+
# Iterates recursively over each segment in the entire transaction
|
146
|
+
# sample tree while keeping track of nested segments
|
147
|
+
def each_segment_with_nest_tracking(&block)
|
148
|
+
@root_segment.each_segment_with_nest_tracking(&block)
|
149
|
+
end
|
150
|
+
|
130
151
|
def to_s_compact
|
131
152
|
@root_segment.to_s_compact
|
132
153
|
end
|
133
|
-
|
154
|
+
|
155
|
+
# Searches the tree recursively for the segment with the given
|
156
|
+
# id. note that this is an internal id, not an ActiveRecord id
|
134
157
|
def find_segment(id)
|
135
158
|
@root_segment.find_segment(id)
|
136
159
|
end
|
@@ -202,7 +225,8 @@ module NewRelic
|
|
202
225
|
end
|
203
226
|
|
204
227
|
private
|
205
|
-
|
228
|
+
|
229
|
+
# This is badly in need of refactoring
|
206
230
|
def build_segment_with_omissions(new_sample, time_delta, source_segment, target_segment, regex)
|
207
231
|
source_segment.called_segments.each do |source_called_segment|
|
208
232
|
# if this segment's metric name matches the given regular expression, bail
|
@@ -233,6 +257,8 @@ module NewRelic
|
|
233
257
|
end
|
234
258
|
|
235
259
|
# see prepare_to_send for what we do with options
|
260
|
+
#
|
261
|
+
# This is badly in need of refactoring
|
236
262
|
def build_segment_for_transfer(new_sample, source_segment, target_segment, options)
|
237
263
|
source_segment.called_segments.each do |source_called_segment|
|
238
264
|
target_called_segment = new_sample.create_segment(
|