newrelic_rpm 3.4.2.1 → 3.5.0
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 +47 -2
- data/lib/new_relic/agent.rb +5 -5
- data/lib/new_relic/agent/agent.rb +88 -177
- data/lib/new_relic/agent/beacon_configuration.rb +33 -47
- data/lib/new_relic/agent/browser_monitoring.rb +26 -33
- data/lib/new_relic/agent/configuration/defaults.rb +21 -13
- data/lib/new_relic/agent/configuration/manager.rb +28 -14
- data/lib/new_relic/agent/configuration/server_source.rb +8 -5
- data/lib/new_relic/agent/database.rb +37 -22
- data/lib/new_relic/agent/error_collector.rb +32 -31
- data/lib/new_relic/agent/instrumentation/unicorn_instrumentation.rb +4 -3
- data/lib/new_relic/agent/new_relic_service.rb +21 -19
- data/lib/new_relic/agent/pipe_channel_manager.rb +13 -13
- data/lib/new_relic/agent/sql_sampler.rb +9 -28
- data/lib/new_relic/agent/stats_engine/gc_profiler.rb +21 -24
- data/lib/new_relic/agent/stats_engine/transactions.rb +20 -12
- data/lib/new_relic/agent/transaction_sample_builder.rb +5 -3
- data/lib/new_relic/agent/transaction_sampler.rb +43 -47
- data/lib/new_relic/control/frameworks/rails.rb +9 -4
- data/lib/new_relic/control/frameworks/rails3.rb +10 -0
- data/lib/new_relic/noticed_error.rb +18 -8
- data/lib/new_relic/rack.rb +4 -0
- data/lib/new_relic/rack/browser_monitoring.rb +2 -0
- data/lib/new_relic/rack/error_collector.rb +56 -0
- data/lib/new_relic/version.rb +3 -3
- data/newrelic.yml +0 -12
- data/newrelic_rpm.gemspec +6 -3
- data/test/new_relic/agent/agent/connect_test.rb +78 -113
- data/test/new_relic/agent/agent/start_test.rb +2 -2
- data/test/new_relic/agent/agent/start_worker_thread_test.rb +6 -33
- data/test/new_relic/agent/agent_test.rb +20 -6
- data/test/new_relic/agent/agent_test_controller_test.rb +7 -5
- data/test/new_relic/agent/beacon_configuration_test.rb +54 -60
- data/test/new_relic/agent/browser_monitoring_test.rb +88 -74
- data/test/new_relic/agent/configuration/manager_test.rb +21 -21
- data/test/new_relic/agent/configuration/server_source_test.rb +21 -4
- data/test/new_relic/agent/instrumentation/task_instrumentation_test.rb +2 -2
- data/test/new_relic/agent/mock_scope_listener.rb +3 -0
- data/test/new_relic/agent/new_relic_service_test.rb +56 -17
- data/test/new_relic/agent/pipe_channel_manager_test.rb +4 -1
- data/test/new_relic/agent/rpm_agent_test.rb +1 -0
- data/test/new_relic/agent/stats_engine_test.rb +12 -7
- data/test/new_relic/agent/transaction_sampler_test.rb +106 -102
- data/test/new_relic/agent_test.rb +10 -9
- data/test/new_relic/control_test.rb +1 -17
- data/test/new_relic/rack/browser_monitoring_test.rb +11 -5
- data/test/new_relic/rack/error_collector_test.rb +74 -0
- data/test/test_helper.rb +1 -1
- metadata +9 -7
@@ -10,22 +10,19 @@ module NewRelic
|
|
10
10
|
module Shim #:nodoc:
|
11
11
|
def notice_error(*args); end
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
# Maximum possible length of the queue - defaults to 20, may be
|
15
15
|
# made configurable in the future. This is a tradeoff between
|
16
16
|
# memory and data retention
|
17
17
|
MAX_ERROR_QUEUE_LENGTH = 20 unless defined? MAX_ERROR_QUEUE_LENGTH
|
18
18
|
|
19
|
-
attr_accessor :
|
20
|
-
|
21
|
-
|
19
|
+
attr_accessor :errors
|
20
|
+
|
22
21
|
# Returns a new error collector
|
23
22
|
def initialize
|
24
23
|
@errors = []
|
25
24
|
# lookup of exception class names to ignore. Hash for fast access
|
26
25
|
@ignore = {}
|
27
|
-
|
28
|
-
@enabled = @config_enabled = Agent.config[:'error_collector.enabled']
|
29
26
|
@capture_source = Agent.config[:'error_collector.capture_source']
|
30
27
|
|
31
28
|
ignore_errors = Agent.config[:'error_collector.ignore_errors']
|
@@ -33,6 +30,14 @@ module NewRelic
|
|
33
30
|
ignore_errors.each { |error| error.strip! }
|
34
31
|
ignore(ignore_errors)
|
35
32
|
@lock = Mutex.new
|
33
|
+
|
34
|
+
Agent.config.register_callback(:'error_collector.enabled') do |config_enabled|
|
35
|
+
log.debug "Errors will #{config_enabled ? '' : 'not '}be sent to the New Relic service."
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def enabled?
|
40
|
+
Agent.config[:'error_collector.enabled']
|
36
41
|
end
|
37
42
|
|
38
43
|
# Returns the error filter proc that is used to check if an
|
@@ -57,43 +62,38 @@ module NewRelic
|
|
57
62
|
log.debug("Ignoring errors of type '#{error}'")
|
58
63
|
end
|
59
64
|
end
|
60
|
-
|
65
|
+
|
61
66
|
# This module was extracted from the notice_error method - it is
|
62
67
|
# internally tested and can be refactored without major issues.
|
63
68
|
module NoticeError
|
64
|
-
# Whether the error collector is disabled or not
|
65
|
-
def disabled?
|
66
|
-
!@enabled
|
67
|
-
end
|
68
|
-
|
69
69
|
# Checks the provided error against the error filter, if there
|
70
70
|
# is an error filter
|
71
71
|
def filtered_by_error_filter?(error)
|
72
72
|
return unless @ignore_filter
|
73
73
|
!@ignore_filter.call(error)
|
74
74
|
end
|
75
|
-
|
75
|
+
|
76
76
|
# Checks the array of error names and the error filter against
|
77
77
|
# the provided error
|
78
78
|
def filtered_error?(error)
|
79
79
|
@ignore[error.class.name] || filtered_by_error_filter?(error)
|
80
80
|
end
|
81
|
-
|
81
|
+
|
82
82
|
# an error is ignored if it is nil or if it is filtered
|
83
83
|
def error_is_ignored?(error)
|
84
84
|
error && filtered_error?(error)
|
85
85
|
end
|
86
|
-
|
86
|
+
|
87
87
|
# Increments a statistic that tracks total error rate
|
88
88
|
def increment_error_count!
|
89
89
|
NewRelic::Agent.get_stats("Errors/all").increment_count
|
90
90
|
end
|
91
|
-
|
91
|
+
|
92
92
|
# whether we should return early from the notice_error process
|
93
93
|
# - based on whether the error is ignored or the error
|
94
94
|
# collector is disabled
|
95
95
|
def should_exit_notice_error?(exception)
|
96
|
-
if
|
96
|
+
if enabled?
|
97
97
|
if !error_is_ignored?(exception)
|
98
98
|
increment_error_count!
|
99
99
|
return exception.nil? # exit early if the exception is nil
|
@@ -102,12 +102,12 @@ module NewRelic
|
|
102
102
|
# disabled or an ignored error, per above
|
103
103
|
true
|
104
104
|
end
|
105
|
-
|
105
|
+
|
106
106
|
# acts just like Hash#fetch, but deletes the key from the hash
|
107
107
|
def fetch_from_options(options, key, default=nil)
|
108
108
|
options.delete(key) || default
|
109
109
|
end
|
110
|
-
|
110
|
+
|
111
111
|
# returns some basic option defaults pulled from the provided
|
112
112
|
# options hash
|
113
113
|
def uri_ref_and_root(options)
|
@@ -117,13 +117,13 @@ module NewRelic
|
|
117
117
|
:rails_root => NewRelic::Control.instance.root
|
118
118
|
}
|
119
119
|
end
|
120
|
-
|
120
|
+
|
121
121
|
# If anything else is left over, we treat it like a custom param
|
122
122
|
def custom_params_from_opts(options)
|
123
123
|
# If anything else is left over, treat it like a custom param:
|
124
124
|
fetch_from_options(options, :custom_params, {}).merge(options)
|
125
125
|
end
|
126
|
-
|
126
|
+
|
127
127
|
# takes the request parameters out of the options hash, and
|
128
128
|
# returns them if we are capturing parameters, otherwise
|
129
129
|
# returns nil
|
@@ -135,7 +135,7 @@ module NewRelic
|
|
135
135
|
nil
|
136
136
|
end
|
137
137
|
end
|
138
|
-
|
138
|
+
|
139
139
|
# normalizes the request and custom parameters before attaching
|
140
140
|
# them to the error. See NewRelic::CollectionHelper#normalize_params
|
141
141
|
def normalized_request_and_custom_params(options)
|
@@ -144,32 +144,32 @@ module NewRelic
|
|
144
144
|
:custom_params => normalize_params(custom_params_from_opts(options))
|
145
145
|
}
|
146
146
|
end
|
147
|
-
|
147
|
+
|
148
148
|
# Merges together many of the options into something that can
|
149
149
|
# actually be attached to the error
|
150
150
|
def error_params_from_options(options)
|
151
151
|
uri_ref_and_root(options).merge(normalized_request_and_custom_params(options))
|
152
152
|
end
|
153
|
-
|
153
|
+
|
154
154
|
# calls a method on an object, if it responds to it - used for
|
155
155
|
# detection and soft fail-safe. Returns nil if the method does
|
156
156
|
# not exist
|
157
157
|
def sense_method(object, method)
|
158
158
|
object.send(method) if object.respond_to?(method)
|
159
159
|
end
|
160
|
-
|
160
|
+
|
161
161
|
# extracts source from the exception, if the exception supports
|
162
162
|
# that method
|
163
163
|
def extract_source(exception)
|
164
164
|
sense_method(exception, 'source_extract') if @capture_source
|
165
165
|
end
|
166
|
-
|
166
|
+
|
167
167
|
# extracts a stack trace from the exception for debugging purposes
|
168
168
|
def extract_stack_trace(exception)
|
169
169
|
actual_exception = sense_method(exception, 'original_exception') || exception
|
170
170
|
sense_method(actual_exception, 'backtrace') || '<no stack trace>'
|
171
171
|
end
|
172
|
-
|
172
|
+
|
173
173
|
# extracts a bunch of information from the exception to include
|
174
174
|
# in the noticed error - some may or may not be available, but
|
175
175
|
# we try to include all of it
|
@@ -181,7 +181,7 @@ module NewRelic
|
|
181
181
|
:stack_trace => extract_stack_trace(exception)
|
182
182
|
}
|
183
183
|
end
|
184
|
-
|
184
|
+
|
185
185
|
# checks the size of the error queue to make sure we are under
|
186
186
|
# the maximum limit, and logs a warning if we are over the limit.
|
187
187
|
def over_queue_limit?(message)
|
@@ -190,13 +190,14 @@ module NewRelic
|
|
190
190
|
over_limit
|
191
191
|
end
|
192
192
|
|
193
|
-
|
194
193
|
# Synchronizes adding an error to the error queue, and checks if
|
195
194
|
# the error queue is too long - if so, we drop the error on the
|
196
195
|
# floor after logging a warning.
|
197
196
|
def add_to_error_queue(noticed_error)
|
198
197
|
@lock.synchronize do
|
199
|
-
|
198
|
+
if !over_queue_limit?(noticed_error.message) && !@errors.include?(noticed_error)
|
199
|
+
@errors << noticed_error
|
200
|
+
end
|
200
201
|
end
|
201
202
|
end
|
202
203
|
end
|
@@ -220,7 +221,7 @@ module NewRelic
|
|
220
221
|
add_to_error_queue(NewRelic::NoticedError.new(action_path, exception_options, exception))
|
221
222
|
exception
|
222
223
|
rescue => e
|
223
|
-
log.error("Error capturing an error
|
224
|
+
log.error("Error capturing an error #{e}")
|
224
225
|
end
|
225
226
|
|
226
227
|
# Get the errors currently queued up. Unsent errors are left
|
@@ -4,15 +4,16 @@ DependencyDetection.defer do
|
|
4
4
|
depends_on do
|
5
5
|
defined?(::Unicorn) && defined?(::Unicorn::HttpServer)
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
executes do
|
9
9
|
NewRelic::Agent.logger.debug 'Installing Unicorn instrumentation'
|
10
|
+
NewRelic::Agent.logger.info 'Detected Unicorn, please see additional documentation: https://newrelic.com/docs/troubleshooting/im-using-unicorn-and-i-dont-see-any-data'
|
10
11
|
end
|
11
|
-
|
12
|
+
|
12
13
|
executes do
|
13
14
|
Unicorn::HttpServer.class_eval do
|
14
15
|
old_worker_loop = instance_method(:worker_loop)
|
15
|
-
define_method(:worker_loop) do |
|
16
|
+
define_method(:worker_loop) do |worker|
|
16
17
|
NewRelic::Agent.after_fork(:force_reconnect => true)
|
17
18
|
old_worker_loop.bind(self).call(worker)
|
18
19
|
end
|
@@ -3,8 +3,8 @@ module NewRelic
|
|
3
3
|
class NewRelicService
|
4
4
|
# Specifies the version of the agent's communication protocol with
|
5
5
|
# the NewRelic hosted site.
|
6
|
-
|
7
|
-
PROTOCOL_VERSION =
|
6
|
+
|
7
|
+
PROTOCOL_VERSION = 9
|
8
8
|
# 14105: v8 (tag 2.10.3)
|
9
9
|
# (no v7)
|
10
10
|
# 10379: v6 (not tagged)
|
@@ -12,17 +12,17 @@ module NewRelic
|
|
12
12
|
# 2292: v4 (tag 2.3.6)
|
13
13
|
# 1754: v3 (tag 2.3.0)
|
14
14
|
# 534: v2 (shows up in 2.1.0, our first tag)
|
15
|
-
|
15
|
+
|
16
16
|
attr_accessor :request_timeout
|
17
17
|
attr_reader :collector
|
18
18
|
attr_accessor :agent_id
|
19
|
-
|
19
|
+
|
20
20
|
def initialize(license_key=nil, collector=control.server)
|
21
21
|
@license_key = license_key || Agent.config[:license_key]
|
22
22
|
@collector = collector
|
23
23
|
@request_timeout = Agent.config[:timeout]
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def connect(settings={})
|
27
27
|
if host = get_redirect_host
|
28
28
|
@collector = NewRelic::Control.instance.server_from_host(host)
|
@@ -44,7 +44,7 @@ module NewRelic
|
|
44
44
|
invoke_remote(:metric_data, @agent_id, last_harvest_time, now,
|
45
45
|
unsent_timeslice_data)
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
def error_data(unsent_errors)
|
49
49
|
invoke_remote(:error_data, @agent_id, unsent_errors)
|
50
50
|
end
|
@@ -58,24 +58,24 @@ module NewRelic
|
|
58
58
|
end
|
59
59
|
|
60
60
|
private
|
61
|
-
|
61
|
+
|
62
62
|
# A shorthand for NewRelic::Control.instance
|
63
63
|
def control
|
64
64
|
NewRelic::Control.instance
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
# Shorthand to the NewRelic::Agent.logger method
|
68
68
|
def log
|
69
69
|
NewRelic::Agent.logger
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
# The path on the server that we should post our data to
|
73
73
|
def remote_method_uri(method)
|
74
74
|
uri = "/agent_listener/#{PROTOCOL_VERSION}/#{@license_key}/#{method}"
|
75
75
|
uri << "?run_id=#{@agent_id}" if @agent_id
|
76
76
|
uri
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
# send a message via post to the actual server. This attempts
|
80
80
|
# to automatically compress the data via zlib if it is large
|
81
81
|
# enough to be worth compressing, and handles any errors the
|
@@ -84,7 +84,7 @@ module NewRelic
|
|
84
84
|
now = Time.now
|
85
85
|
#determines whether to zip the data or send plain
|
86
86
|
post_data, encoding = compress_data(args)
|
87
|
-
|
87
|
+
|
88
88
|
response = send_request(:uri => remote_method_uri(method),
|
89
89
|
:encoding => encoding,
|
90
90
|
:collector => @collector,
|
@@ -140,13 +140,13 @@ module NewRelic
|
|
140
140
|
raise
|
141
141
|
end
|
142
142
|
|
143
|
-
# Raises
|
143
|
+
# Raises an UnrecoverableServerException if the post_string is longer
|
144
144
|
# than the limit configured in the control object
|
145
145
|
def check_post_size(post_string)
|
146
146
|
# TODO: define this as a config option on the server side
|
147
147
|
return if post_string.size < Agent.config[:post_size_limit]
|
148
|
-
log.
|
149
|
-
raise
|
148
|
+
log.debug "Tried to send too much data: #{post_string.size} bytes"
|
149
|
+
raise UnrecoverableServerException.new('413 Request Entity Too Large')
|
150
150
|
end
|
151
151
|
|
152
152
|
# Posts to the specified server
|
@@ -164,9 +164,9 @@ module NewRelic
|
|
164
164
|
request['user-agent'] = user_agent
|
165
165
|
request.content_type = "application/octet-stream"
|
166
166
|
request.body = opts[:data]
|
167
|
-
|
167
|
+
|
168
168
|
log.debug "Connect to #{opts[:collector]}#{opts[:uri]}"
|
169
|
-
|
169
|
+
|
170
170
|
response = nil
|
171
171
|
http = control.http_connection(@collector)
|
172
172
|
http.read_timeout = nil
|
@@ -179,14 +179,16 @@ module NewRelic
|
|
179
179
|
raise
|
180
180
|
end
|
181
181
|
if response.is_a? Net::HTTPServiceUnavailable
|
182
|
-
raise
|
182
|
+
raise ServerConnectionException, "Service unavailable (#{response.code}): #{response.message}"
|
183
183
|
elsif response.is_a? Net::HTTPGatewayTimeOut
|
184
184
|
log.debug("Timed out getting response: #{response.message}")
|
185
185
|
raise Timeout::Error, response.message
|
186
186
|
elsif response.is_a? Net::HTTPRequestEntityTooLarge
|
187
|
-
raise
|
187
|
+
raise UnrecoverableServerException, '413 Request Entity Too Large'
|
188
|
+
elsif response.is_a? Net::HTTPUnsupportedMediaType
|
189
|
+
raise UnrecoverableServerException, '415 Unsupported Media Type'
|
188
190
|
elsif !(response.is_a? Net::HTTPSuccess)
|
189
|
-
raise
|
191
|
+
raise ServerConnectionException, "Unexpected response from server (#{response.code}): #{response.message}"
|
190
192
|
end
|
191
193
|
response
|
192
194
|
end
|
@@ -17,15 +17,15 @@ module NewRelic
|
|
17
17
|
def channels
|
18
18
|
listener.pipes
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
def listener
|
22
22
|
@listener ||= Listener.new
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
class Pipe
|
26
26
|
attr_accessor :in, :out
|
27
27
|
attr_reader :last_read
|
28
|
-
|
28
|
+
|
29
29
|
def initialize
|
30
30
|
@out, @in = IO.pipe
|
31
31
|
if defined?(::Encoding::ASCII_8BIT)
|
@@ -33,7 +33,7 @@ module NewRelic
|
|
33
33
|
end
|
34
34
|
@last_read = Time.now
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
def close
|
38
38
|
@out.close unless @out.closed?
|
39
39
|
@in.close unless @in.closed?
|
@@ -46,7 +46,7 @@ module NewRelic
|
|
46
46
|
end
|
47
47
|
@in << "\n\n"
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
def read
|
51
51
|
@in.close unless @in.closed?
|
52
52
|
@last_read = Time.now
|
@@ -57,7 +57,7 @@ module NewRelic
|
|
57
57
|
@out.closed? && @in.closed?
|
58
58
|
end
|
59
59
|
end
|
60
|
-
|
60
|
+
|
61
61
|
class Listener
|
62
62
|
attr_reader :thread
|
63
63
|
attr_accessor :pipes, :timeout, :select_timeout
|
@@ -80,7 +80,7 @@ module NewRelic
|
|
80
80
|
loop do
|
81
81
|
clean_up_pipes
|
82
82
|
pipes_to_listen_to = @pipes.values.map{|pipe| pipe.out} + [wake.out]
|
83
|
-
if ready = IO.select(pipes_to_listen_to, [], [], @select_timeout)
|
83
|
+
if ready = IO.select(pipes_to_listen_to, [], [], @select_timeout)
|
84
84
|
pipe = ready[0][0]
|
85
85
|
if pipe == wake.out
|
86
86
|
pipe.read(1)
|
@@ -88,14 +88,14 @@ module NewRelic
|
|
88
88
|
merge_data_from_pipe(pipe)
|
89
89
|
end
|
90
90
|
end
|
91
|
-
|
91
|
+
|
92
92
|
break if !should_keep_listening?
|
93
93
|
end
|
94
94
|
end
|
95
95
|
@thread #.abort_on_exception = true
|
96
96
|
sleep 0.001 # give time for the thread to spawn
|
97
97
|
end
|
98
|
-
|
98
|
+
|
99
99
|
def stop
|
100
100
|
return unless @started == true
|
101
101
|
@started = false
|
@@ -112,7 +112,7 @@ module NewRelic
|
|
112
112
|
end
|
113
113
|
@pipes = {}
|
114
114
|
end
|
115
|
-
|
115
|
+
|
116
116
|
def wake
|
117
117
|
@wake ||= Pipe.new
|
118
118
|
end
|
@@ -126,7 +126,7 @@ module NewRelic
|
|
126
126
|
def merge_data_from_pipe(pipe_handle)
|
127
127
|
pipe = find_pipe_for_handle(pipe_handle)
|
128
128
|
got = pipe.read
|
129
|
-
|
129
|
+
|
130
130
|
if got && !got.empty?
|
131
131
|
payload = unmarshal(got)
|
132
132
|
if payload == 'EOF'
|
@@ -148,11 +148,11 @@ module NewRelic
|
|
148
148
|
NewRelic::Control.instance.log.debug(msg)
|
149
149
|
nil
|
150
150
|
end
|
151
|
-
|
151
|
+
|
152
152
|
def should_keep_listening?
|
153
153
|
@started || @pipes.values.find{|pipe| !pipe.in.closed?}
|
154
154
|
end
|
155
|
-
|
155
|
+
|
156
156
|
def clean_up_pipes
|
157
157
|
@pipes.values.each do |pipe|
|
158
158
|
if pipe.last_read.to_f + @timeout < Time.now.to_f
|
@@ -18,7 +18,6 @@ module NewRelic
|
|
18
18
|
attr_reader :sql_traces
|
19
19
|
|
20
20
|
def initialize
|
21
|
-
configure!
|
22
21
|
@sql_traces = {}
|
23
22
|
clear_transaction_data
|
24
23
|
|
@@ -28,38 +27,20 @@ module NewRelic
|
|
28
27
|
@samples_lock = Mutex.new
|
29
28
|
end
|
30
29
|
|
31
|
-
def configure!
|
32
|
-
@explain_threshold = Agent.config[:'slow_sql.explain_threshold']
|
33
|
-
@explain_enabled = Agent.config[:'sloq_sql.explain_enabled']
|
34
|
-
@stack_trace_threshold = Agent.config[:'slow_sql.stack_trace_threshold']
|
35
|
-
if Agent.config[:'slow_sql.enabled']
|
36
|
-
enable
|
37
|
-
else
|
38
|
-
disable
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
# Enable the sql sampler - this also registers it with
|
43
|
-
# the statistics engine.
|
44
|
-
def enable
|
45
|
-
@disabled = false
|
46
|
-
end
|
47
|
-
|
48
|
-
# Disable the sql sampler - this also deregisters it
|
49
|
-
# with the statistics engine.
|
50
|
-
def disable
|
51
|
-
@disabled = true
|
52
|
-
end
|
53
|
-
|
54
30
|
def enabled?
|
55
|
-
|
31
|
+
Agent.config[:'slow_sql.enabled'] &&
|
32
|
+
(Agent.config[:'slow_sql.record_sql'] == 'raw' ||
|
33
|
+
Agent.config[:'slow_sql.record_sql'] == 'obfuscated') &&
|
34
|
+
Agent.config[:'transaction_tracer.enabled']
|
56
35
|
end
|
57
36
|
|
58
37
|
def notice_transaction(path, uri=nil, params={})
|
59
38
|
if NewRelic::Agent.instance.transaction_sampler.builder
|
60
39
|
guid = NewRelic::Agent.instance.transaction_sampler.builder.sample.guid
|
61
40
|
end
|
62
|
-
|
41
|
+
if Agent.config[:'slow_sql.enabled'] && transaction_data
|
42
|
+
transaction_data.set_transaction_info(path, uri, params, guid)
|
43
|
+
end
|
63
44
|
end
|
64
45
|
|
65
46
|
def notice_first_scope_push(time)
|
@@ -111,7 +92,7 @@ module NewRelic
|
|
111
92
|
def notice_sql(sql, metric_name, config, duration)
|
112
93
|
return unless transaction_data
|
113
94
|
if NewRelic::Agent.is_sql_recorded?
|
114
|
-
if duration >
|
95
|
+
if duration > Agent.config[:'slow_sql.explain_threshold']
|
115
96
|
backtrace = caller.join("\n")
|
116
97
|
transaction_data.sql_data << SlowSql.new(sql, metric_name, config,
|
117
98
|
duration, backtrace)
|
@@ -127,7 +108,7 @@ module NewRelic
|
|
127
108
|
end
|
128
109
|
|
129
110
|
def harvest
|
130
|
-
return [] if
|
111
|
+
return [] if !Agent.config[:'slow_sql.enabled']
|
131
112
|
result = []
|
132
113
|
@samples_lock.synchronize do
|
133
114
|
result = @sql_traces.values
|