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.

Files changed (49) hide show
  1. data/CHANGELOG +47 -2
  2. data/lib/new_relic/agent.rb +5 -5
  3. data/lib/new_relic/agent/agent.rb +88 -177
  4. data/lib/new_relic/agent/beacon_configuration.rb +33 -47
  5. data/lib/new_relic/agent/browser_monitoring.rb +26 -33
  6. data/lib/new_relic/agent/configuration/defaults.rb +21 -13
  7. data/lib/new_relic/agent/configuration/manager.rb +28 -14
  8. data/lib/new_relic/agent/configuration/server_source.rb +8 -5
  9. data/lib/new_relic/agent/database.rb +37 -22
  10. data/lib/new_relic/agent/error_collector.rb +32 -31
  11. data/lib/new_relic/agent/instrumentation/unicorn_instrumentation.rb +4 -3
  12. data/lib/new_relic/agent/new_relic_service.rb +21 -19
  13. data/lib/new_relic/agent/pipe_channel_manager.rb +13 -13
  14. data/lib/new_relic/agent/sql_sampler.rb +9 -28
  15. data/lib/new_relic/agent/stats_engine/gc_profiler.rb +21 -24
  16. data/lib/new_relic/agent/stats_engine/transactions.rb +20 -12
  17. data/lib/new_relic/agent/transaction_sample_builder.rb +5 -3
  18. data/lib/new_relic/agent/transaction_sampler.rb +43 -47
  19. data/lib/new_relic/control/frameworks/rails.rb +9 -4
  20. data/lib/new_relic/control/frameworks/rails3.rb +10 -0
  21. data/lib/new_relic/noticed_error.rb +18 -8
  22. data/lib/new_relic/rack.rb +4 -0
  23. data/lib/new_relic/rack/browser_monitoring.rb +2 -0
  24. data/lib/new_relic/rack/error_collector.rb +56 -0
  25. data/lib/new_relic/version.rb +3 -3
  26. data/newrelic.yml +0 -12
  27. data/newrelic_rpm.gemspec +6 -3
  28. data/test/new_relic/agent/agent/connect_test.rb +78 -113
  29. data/test/new_relic/agent/agent/start_test.rb +2 -2
  30. data/test/new_relic/agent/agent/start_worker_thread_test.rb +6 -33
  31. data/test/new_relic/agent/agent_test.rb +20 -6
  32. data/test/new_relic/agent/agent_test_controller_test.rb +7 -5
  33. data/test/new_relic/agent/beacon_configuration_test.rb +54 -60
  34. data/test/new_relic/agent/browser_monitoring_test.rb +88 -74
  35. data/test/new_relic/agent/configuration/manager_test.rb +21 -21
  36. data/test/new_relic/agent/configuration/server_source_test.rb +21 -4
  37. data/test/new_relic/agent/instrumentation/task_instrumentation_test.rb +2 -2
  38. data/test/new_relic/agent/mock_scope_listener.rb +3 -0
  39. data/test/new_relic/agent/new_relic_service_test.rb +56 -17
  40. data/test/new_relic/agent/pipe_channel_manager_test.rb +4 -1
  41. data/test/new_relic/agent/rpm_agent_test.rb +1 -0
  42. data/test/new_relic/agent/stats_engine_test.rb +12 -7
  43. data/test/new_relic/agent/transaction_sampler_test.rb +106 -102
  44. data/test/new_relic/agent_test.rb +10 -9
  45. data/test/new_relic/control_test.rb +1 -17
  46. data/test/new_relic/rack/browser_monitoring_test.rb +11 -5
  47. data/test/new_relic/rack/error_collector_test.rb +74 -0
  48. data/test/test_helper.rb +1 -1
  49. metadata +9 -7
@@ -12,52 +12,38 @@ module NewRelic
12
12
  # the static portion of the RUM footer - this part does not vary
13
13
  # by which request is in progress
14
14
  attr_reader :browser_timing_static_footer
15
-
16
- # the application id we include in the javascript -
17
- # crossreferences with the application id on the collectors
18
- attr_reader :application_id
19
15
 
20
- # the key used for browser monitoring. This is different from
21
- # the account key
22
- attr_reader :browser_monitoring_key
23
-
24
- # which beacon we should report to - set by startup of the agent
25
- attr_reader :beacon
26
-
27
- # whether RUM is enabled or not - determined based on server and
28
- # local config
29
- attr_reader :rum_enabled
30
-
31
- # whether JSONP is used to communicate with the Beacon or not
32
- attr_reader :rum_jsonp
33
-
34
16
  # RUM footer command used for 'finish' - based on whether JSONP is
35
17
  # being used. 'nrfj' for JSONP, otherwise 'nrf2'
36
18
  attr_reader :finish_command
37
-
19
+
38
20
  # A static javascript header that is identical for every account
39
21
  # and application
40
22
  JS_HEADER = "<script type=\"text/javascript\">var NREUMQ=NREUMQ||[];NREUMQ.push([\"mark\",\"firstbyte\",new Date().getTime()]);</script>"
41
-
23
+
42
24
  # Creates a new browser configuration data. Argument is a hash
43
25
  # of configuration values from the server
44
- def initialize(connect_data)
45
- @browser_monitoring_key = connect_data['browser_key']
46
- @application_id = connect_data['application_id']
47
- @beacon = connect_data['beacon']
48
- @rum_enabled = connect_data['rum.enabled']
49
- @rum_enabled = true if @rum_enabled.nil?
50
- NewRelic::Control.instance.log.warn("Real User Monitoring is disabled for this agent. Edit your configuration to change this.") unless @rum_enabled
26
+ def initialize
51
27
  @browser_timing_header = build_browser_timing_header
52
28
  NewRelic::Control.instance.log.debug("Browser timing header: #{@browser_timing_header.inspect}")
53
- @browser_timing_static_footer = build_load_file_js(connect_data)
29
+ @browser_timing_static_footer = build_load_file_js
54
30
  NewRelic::Control.instance.log.debug("Browser timing static footer: #{@browser_timing_static_footer.inspect}")
55
- @rum_jsonp = connect_data['rum.jsonp']
56
- @rum_jsonp = true if @rum_jsonp.nil?
57
- NewRelic::Control.instance.log.debug("Real User Monitoring is using JSONP protocol") if @rum_jsonp
58
- @finish_command = @rum_jsonp ? 'nrfj' : 'nrf2'
31
+ if Agent.config[:'rum.jsonp']
32
+ NewRelic::Control.instance.log.debug("Real User Monitoring is using JSONP protocol")
33
+ @finish_command = 'nrfj'
34
+ else
35
+ @finish_command = 'nrf2'
36
+ end
37
+
38
+ if !Agent.config[:'rum.enabled']
39
+ NewRelic::Control.instance.log.warn("Real User Monitoring is disabled for this agent. Edit your configuration to change this.")
40
+ end
41
+ end
42
+
43
+ def enabled?
44
+ Agent.config[:'rum.enabled'] && !!Agent.config[:beacon]
59
45
  end
60
-
46
+
61
47
  # returns a memoized version of the bytes in the license key for
62
48
  # obscuring transaction names in the javascript
63
49
  def license_bytes
@@ -67,26 +53,28 @@ module NewRelic
67
53
  end
68
54
  @license_bytes
69
55
  end
70
-
56
+
71
57
  # returns a snippet of text that does not change
72
58
  # per-transaction. Is empty when rum is disabled, or we are not
73
59
  # including the episodes file dynamically (i.e. the user
74
60
  # includes it themselves)
75
- def build_load_file_js(connect_data)
61
+ def build_load_file_js
76
62
  js = <<-EOS
77
63
  if (!NREUMQ.f) { NREUMQ.f=function() {
78
64
  NREUMQ.push(["load",new Date().getTime()]);
79
65
  EOS
80
-
81
- if connect_data.fetch('rum.load_episodes_file', true)
82
- episodes_url = connect_data.fetch('episodes_url', '')
66
+
67
+ if Agent.config[:'rum.load_episodes_file'] &&
68
+ Agent.config[:'rum.load_episodes_file'] != ''
83
69
  js << <<-EOS
84
- var e=document.createElement(\"script\");
85
- e.type=\"text/javascript\";e.async=true;e.src=\"#{episodes_url}\";
70
+ var e=document.createElement("script");
71
+ e.type="text/javascript";
72
+ e.src=(("http:"===document.location.protocol)?"http:":"https:") + "//" +
73
+ "#{Agent.config[:episodes_file]}";
86
74
  document.body.appendChild(e);
87
75
  EOS
88
76
  end
89
-
77
+
90
78
  js << <<-EOS
91
79
  if(NREUMQ.a)NREUMQ.a();
92
80
  };
@@ -101,12 +89,12 @@ EOS
101
89
  def javascript_header
102
90
  JS_HEADER.dup
103
91
  end
104
-
92
+
105
93
  # Returns the header string, properly html-safed if needed
106
94
  def build_browser_timing_header
107
- return "" if !@rum_enabled
108
- return "" if @browser_monitoring_key.nil?
109
-
95
+ return "" if !enabled?
96
+ return "" if Agent.config[:browser_key].nil?
97
+
110
98
  value = javascript_header
111
99
  if value.respond_to?(:html_safe)
112
100
  value.html_safe
@@ -117,5 +105,3 @@ EOS
117
105
  end
118
106
  end
119
107
  end
120
-
121
-
@@ -5,25 +5,22 @@ module NewRelic
5
5
  # This module contains support for Real User Monitoring - the
6
6
  # javascript generation and configuration
7
7
  module BrowserMonitoring
8
-
9
-
10
8
  class DummyMetricFrame
11
9
  def initialize
12
10
  @attributes = {}
13
11
  end
14
-
12
+
15
13
  def user_attributes
16
14
  @attributes
17
15
  end
18
-
16
+
19
17
  def queue_time
20
18
  0.0
21
19
  end
22
20
  end
23
-
21
+
24
22
  @@dummy_metric_frame = DummyMetricFrame.new
25
-
26
-
23
+
27
24
  # This method returns a string suitable for inclusion in a page
28
25
  # - known as 'manual instrumentation' for Real User
29
26
  # Monitoring. Can return either a script tag with associated
@@ -34,8 +31,8 @@ module NewRelic
34
31
  # page as is reasonably possible - that is, before any style or
35
32
  # javascript inclusions, but after any header-related meta tags
36
33
  def browser_timing_header
37
- if NewRelic::Agent.instance.beacon_configuration.nil? ||
38
- !NewRelic::Agent.is_transaction_traced? ||
34
+ if NewRelic::Agent.instance.beacon_configuration.nil? ||
35
+ !NewRelic::Agent.is_transaction_traced? ||
39
36
  !NewRelic::Agent.is_execution_traced? ||
40
37
  NewRelic::Agent::TransactionInfo.get.ignore_end_user?
41
38
  return ""
@@ -54,16 +51,17 @@ module NewRelic
54
51
  # page as is reasonably possible.
55
52
  def browser_timing_footer
56
53
  config = NewRelic::Agent.instance.beacon_configuration
57
-
58
- if config.nil? ||
59
- !config.rum_enabled ||
60
- config.browser_monitoring_key.nil? ||
61
- !NewRelic::Agent.is_transaction_traced? ||
62
- !NewRelic::Agent.is_execution_traced? ||
63
- NewRelic::Agent::TransactionInfo.get.ignore_end_user?
64
- return ""
54
+
55
+ if config.nil? ||
56
+ !config.enabled? ||
57
+ Agent.config[:browser_key].nil? ||
58
+ Agent.config[:browser_key].empty? ||
59
+ !NewRelic::Agent.is_transaction_traced? ||
60
+ !NewRelic::Agent.is_execution_traced? ||
61
+ NewRelic::Agent::TransactionInfo.get.ignore_end_user?
62
+ return ""
65
63
  end
66
-
64
+
67
65
  generate_footer_js(config)
68
66
  end
69
67
 
@@ -114,7 +112,7 @@ module NewRelic
114
112
 
115
113
  response['X-NewRelic-Beacon-Url'] = beacon_url(request)
116
114
 
117
- payload = %[ ["#{config.application_id}","#{obfuscate(config, browser_monitoring_transaction_name)}",#{browser_monitoring_queue_time},#{browser_monitoring_app_time}] ]
115
+ payload = %[ ["#{Agent.config[:application_id]}","#{obfuscate(config, browser_monitoring_transaction_name)}",#{browser_monitoring_queue_time},#{browser_monitoring_app_time}] ]
118
116
  response['X-NewRelic-App-Server-Metrics'] = payload
119
117
  end
120
118
  end
@@ -126,24 +124,19 @@ module NewRelic
126
124
  end
127
125
 
128
126
  def beacon_url(request)
129
- config = NewRelic::Agent.instance.beacon_configuration
130
- "#{request.scheme || 'http'}://#{config.beacon}/mobile/1/#{config.browser_monitoring_key}"
127
+ "#{request.scheme || 'http'}://#{Agent.config[:beacon]}/mobile/1/#{Agent.config[:browser_key]}"
131
128
  end
132
129
 
133
130
  private
134
131
 
135
132
  def generate_footer_js(config)
136
133
  if browser_monitoring_start_time
137
- application_id = config.application_id
138
- beacon = config.beacon
139
- license_key = config.browser_monitoring_key
140
-
141
- footer_js_string(config, beacon, license_key, application_id)
134
+ footer_js_string(config)
142
135
  else
143
136
  ''
144
137
  end
145
138
  end
146
-
139
+
147
140
  def metric_frame_attribute(key)
148
141
  current_metric_frame.user_attributes[key] || ""
149
142
  end
@@ -153,19 +146,19 @@ module NewRelic
153
146
  return txn.guid if txn.include_guid?
154
147
  ""
155
148
  end
156
-
149
+
157
150
  def tt_token
158
151
  return NewRelic::Agent::TransactionInfo.get.token
159
152
  end
160
-
161
- def footer_js_string(config, beacon, license_key, application_id)
153
+
154
+ def footer_js_string(config)
162
155
  obfuscated_transaction_name = obfuscate(config, browser_monitoring_transaction_name)
163
-
156
+
164
157
  user = obfuscate(config, metric_frame_attribute(:user))
165
158
  account = obfuscate(config, metric_frame_attribute(:account))
166
159
  product = obfuscate(config, metric_frame_attribute(:product))
167
-
168
- html_safe_if_needed("<script type=\"text/javascript\">#{config.browser_timing_static_footer}NREUMQ.push([\"#{config.finish_command}\",\"#{beacon}\",\"#{license_key}\",#{application_id},\"#{obfuscated_transaction_name}\",#{browser_monitoring_queue_time},#{browser_monitoring_app_time},new Date().getTime(),\"#{tt_guid}\",\"#{tt_token}\",\"#{user}\",\"#{account}\",\"#{product}\"])</script>")
160
+
161
+ html_safe_if_needed("<script type=\"text/javascript\">#{config.browser_timing_static_footer}NREUMQ.push([\"#{config.finish_command}\",\"#{Agent.config[:beacon]}\",\"#{Agent.config[:browser_key]}\",#{Agent.config[:application_id]},\"#{obfuscated_transaction_name}\",#{browser_monitoring_queue_time},#{browser_monitoring_app_time},new Date().getTime(),\"#{tt_guid}\",\"#{tt_token}\",\"#{user}\",\"#{account}\",\"#{product}\"]);</script>")
169
162
  end
170
163
 
171
164
  def html_safe_if_needed(string)
@@ -21,18 +21,20 @@ module NewRelic
21
21
  :multi_homed => false,
22
22
  :high_security => false,
23
23
 
24
- :host => 'collector.newrelic.com',
25
- :api_host => 'rpm.newrelic.com',
26
- :port => Proc.new { self[:ssl] ? 443 : 80 },
27
- :api_port => Proc.new { self[:port] },
28
- :ssl => false,
29
- :verify_certificate => false,
30
- :sync_startup => false,
31
- :send_data_on_exit => true,
32
- :post_size_limit => 2 * 1024 * 1024, # 2 megs
33
- :timeout => 2 * 60, # 2 minutes
34
- :force_send => false,
35
- :send_environment_info => true,
24
+ :host => 'collector.newrelic.com',
25
+ :api_host => 'rpm.newrelic.com',
26
+ :port => Proc.new { self[:ssl] ? 443 : 80 },
27
+ :api_port => Proc.new { self[:port] },
28
+ :ssl => false,
29
+ :verify_certificate => false,
30
+ :sync_startup => false,
31
+ :send_data_on_exit => true,
32
+ :post_size_limit => 2 * 1024 * 1024, # 2 megs
33
+ :timeout => 2 * 60, # 2 minutes
34
+ :force_send => false,
35
+ :send_environment_info => true,
36
+ :start_channel_listener => false,
37
+ :data_report_period => 60,
36
38
 
37
39
  :log_file_name => 'newrelic_agent.log',
38
40
  :log_file_path => 'log/',
@@ -59,6 +61,7 @@ module NewRelic
59
61
  :'transaction_tracer.record_sql' => 'obfuscated',
60
62
  :'transaction_tracer.limit_segments' => 4000,
61
63
  :'transaction_tracer.random_sample' => false,
64
+ :sample_rate => 10,
62
65
 
63
66
  :'slow_sql.enabled' => Proc.new { self[:'transaction_tracer.enabled'] },
64
67
  :'slow_sql.stack_trace_threshold' => Proc.new { self[:'transaction_tracer.stack_trace_threshold'] },
@@ -68,7 +71,12 @@ module NewRelic
68
71
 
69
72
  :'error_collector.enabled' => true,
70
73
  :'error_collector.capture_source' => true,
71
- :'error_collector.ignore_errors' => 'ActionController::RoutingError'
74
+ :'error_collector.ignore_errors' => 'ActionController::RoutingError',
75
+
76
+ :'rum.enabled' => true,
77
+ :'rum.jsonp' => true,
78
+ :'rum.load_episodes_file' => true,
79
+ :'browser_monitoring.auto_instrument' => Proc.new { self[:'rum.enabled'] }
72
80
  }.freeze
73
81
  end
74
82
  end
@@ -15,11 +15,13 @@ module NewRelic
15
15
  def initialize
16
16
  @config_stack = [ EnvironmentSource.new, DEFAULTS ]
17
17
  @cache = Hash.new {|hash,key| hash[key] = self.fetch(key) }
18
+ @callbacks = Hash.new {|hash,key| hash[key] = [] }
18
19
  end
19
20
 
20
21
  def apply_config(source, level=0)
22
+ invoke_callbacks(:add, source)
21
23
  @config_stack.insert(level, source.freeze)
22
- expire_cache
24
+ reset_cache
23
25
  end
24
26
 
25
27
  def remove_config(source=nil)
@@ -28,7 +30,8 @@ module NewRelic
28
30
  else
29
31
  @config_stack.delete(source)
30
32
  end
31
- expire_cache
33
+ reset_cache
34
+ invoke_callbacks(:remove, source)
32
35
  end
33
36
 
34
37
  def replace_or_add_config(source, level=0)
@@ -49,9 +52,7 @@ module NewRelic
49
52
  @config_stack.each do |config|
50
53
  next unless config
51
54
  accessor = key.to_sym
52
- if config.respond_to?(accessor)
53
- return config.send(accessor)
54
- elsif config.has_key?(accessor)
55
+ if config.has_key?(accessor)
55
56
  if config[accessor].respond_to?(:call)
56
57
  return instance_eval(&config[accessor])
57
58
  else
@@ -62,6 +63,26 @@ module NewRelic
62
63
  nil
63
64
  end
64
65
 
66
+ def register_callback(key, &proc)
67
+ @callbacks[key] << proc
68
+ proc.call(@cache[key])
69
+ end
70
+
71
+ def invoke_callbacks(direction, source)
72
+ return unless source
73
+ source.keys.each do |key|
74
+ if @cache[key] != source[key]
75
+ @callbacks[key].each do |proc|
76
+ if direction == :add
77
+ proc.call(source[key])
78
+ else
79
+ proc.call(@cache[key])
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+
65
86
  def flattened_config
66
87
  @config_stack.reverse.inject({}) do |flat,layer|
67
88
  thawed_layer = layer.dup
@@ -69,7 +90,7 @@ module NewRelic
69
90
  begin
70
91
  thawed_layer[k] = instance_eval(&v) if v.respond_to?(:call)
71
92
  rescue => e
72
- NewRelic::Control.instance.log.debug("#{e.class.name} : #{e.message} - when calling Proc for config key #{k}")
93
+ NewRelic::Control.instance.log.debug("#{e.class.name} : #{e.message} - when accessing config key #{k}")
73
94
  thawed_layer[k] = nil
74
95
  end
75
96
  thawed_layer.delete(:config)
@@ -78,13 +99,6 @@ module NewRelic
78
99
  end
79
100
  end
80
101
 
81
- def exclude_rails_config(hash, key)
82
- if defined?(::Rails::Configuration) &&
83
- hash[key].kind_of?(::Rails::Configuration)
84
- hash.delete(key)
85
- end
86
- end
87
-
88
102
  def app_names
89
103
  case self[:app_name]
90
104
  when Array then self[:app_name]
@@ -93,7 +107,7 @@ module NewRelic
93
107
  end
94
108
  end
95
109
 
96
- def expire_cache
110
+ def reset_cache
97
111
  @cache = Hash.new {|hash,key| hash[key] = self.fetch(key) }
98
112
  end
99
113
  end
@@ -3,6 +3,14 @@ module NewRelic
3
3
  module Configuration
4
4
  class ServerSource < DottedHash
5
5
  def initialize(hash)
6
+ if hash['agent_config']
7
+ if hash['agent_config']['transaction_tracer.transaction_threshold'] =~ /apdex_f/i
8
+ # when value is "apdex_f" remove the config and defer to default
9
+ hash['agent_config'].delete('transaction_tracer.transaction_threshold')
10
+ end
11
+ super(hash.delete('agent_config'))
12
+ end
13
+
6
14
  string_map = [
7
15
  ['collect_traces', 'transaction_tracer.enabled'],
8
16
  ['collect_traces', 'slow_sql.enabled'],
@@ -11,11 +19,6 @@ module NewRelic
11
19
  hash[pair[1]] = hash[pair[0]] if hash[pair[0]] != nil
12
20
  end
13
21
 
14
- if hash['transaction_tracer.transaction_threshold'] =~ /apdex_f/i
15
- # when value is "apdex_f" remove the config and defer to default
16
- hash.delete('transaction_tracer.transaction_threshold')
17
- end
18
-
19
22
  super
20
23
  end
21
24
  end
@@ -14,27 +14,42 @@ module NewRelic
14
14
  "Rows",
15
15
  "Extra"
16
16
  ].freeze
17
-
17
+
18
18
  module Agent
19
19
  module Database
20
20
  extend self
21
-
21
+
22
22
  def obfuscate_sql(sql)
23
23
  Obfuscator.instance.obfuscator.call(sql)
24
24
  end
25
-
25
+
26
26
  def set_sql_obfuscator(type, &block)
27
27
  Obfuscator.instance.set_sql_obfuscator(type, &block)
28
28
  end
29
-
29
+
30
+ def record_sql_method
31
+ case Agent.config[:'transaction_tracer.record_sql'].to_s
32
+ when 'off'
33
+ :off
34
+ when 'none'
35
+ :off
36
+ when 'false'
37
+ :off
38
+ when 'raw'
39
+ :raw
40
+ else
41
+ :obfuscated
42
+ end
43
+ end
44
+
30
45
  def get_connection(config)
31
46
  ConnectionManager.instance.get_connection(config)
32
47
  end
33
-
48
+
34
49
  def close_connections
35
50
  ConnectionManager.instance.close_connections
36
51
  end
37
-
52
+
38
53
  # Perform this in the runtime environment of a managed
39
54
  # application, to explain the sql statement executed within a
40
55
  # segment of a transaction sample. Returns an array of
@@ -50,7 +65,7 @@ module NewRelic
50
65
  explain_sql = explain_statement(statement, connection_config)
51
66
  return explain_sql || []
52
67
  end
53
-
68
+
54
69
  def explain_statement(statement, config)
55
70
  if is_select?(statement)
56
71
  handle_exception_in_explain do
@@ -63,12 +78,12 @@ module NewRelic
63
78
  end
64
79
  end
65
80
  end
66
-
81
+
67
82
  def process_resultset(items)
68
83
  # The resultset type varies for different drivers. Only thing you can count on is
69
84
  # that it implements each. Also: can't use select_rows because the native postgres
70
85
  # driver doesn't know that method.
71
-
86
+
72
87
  headers = []
73
88
  values = []
74
89
  if items.respond_to?(:each_hash)
@@ -88,7 +103,7 @@ module NewRelic
88
103
  else
89
104
  values = [items]
90
105
  end
91
-
106
+
92
107
  headers = nil if headers.empty?
93
108
  [headers, values]
94
109
  end
@@ -104,14 +119,14 @@ module NewRelic
104
119
  # double exception. throw up your hands
105
120
  end
106
121
  end
107
-
122
+
108
123
  def is_select?(statement)
109
124
  # split the string into at most two segments on the
110
125
  # system-defined field separator character
111
126
  first_word, rest_of_statement = statement.split($;, 2)
112
127
  (first_word.upcase == 'SELECT')
113
128
  end
114
-
129
+
115
130
  class ConnectionManager
116
131
  include Singleton
117
132
 
@@ -121,11 +136,11 @@ module NewRelic
121
136
  # the sql
122
137
  def get_connection(config)
123
138
  @connections ||= {}
124
-
139
+
125
140
  connection = @connections[config]
126
-
141
+
127
142
  return connection if connection
128
-
143
+
129
144
  begin
130
145
  connection = ActiveRecord::Base.send("#{config[:adapter]}_connection", config)
131
146
  @connections[config] = connection
@@ -135,7 +150,7 @@ module NewRelic
135
150
  nil
136
151
  end
137
152
  end
138
-
153
+
139
154
  # Closes all the connections in the internal connection cache
140
155
  def close_connections
141
156
  @connections ||= {}
@@ -145,16 +160,16 @@ module NewRelic
145
160
  rescue
146
161
  end
147
162
  end
148
-
163
+
149
164
  @connections = {}
150
165
  end
151
166
  end
152
167
 
153
168
  class Obfuscator
154
169
  include Singleton
155
-
170
+
156
171
  attr_reader :obfuscator
157
-
172
+
158
173
  def initialize
159
174
  reset
160
175
  end
@@ -162,7 +177,7 @@ module NewRelic
162
177
  def reset
163
178
  @obfuscator = method(:default_sql_obfuscator)
164
179
  end
165
-
180
+
166
181
  # Sets the sql obfuscator used to clean up sql when sending it
167
182
  # to the server. Possible types are:
168
183
  #
@@ -185,7 +200,7 @@ module NewRelic
185
200
  fail "unknown sql_obfuscator type #{type}"
186
201
  end
187
202
  end
188
-
203
+
189
204
  def default_sql_obfuscator(sql)
190
205
  stmt = sql.kind_of?(Statement) ? sql : Statement.new(sql)
191
206
  adapter = stmt.adapter
@@ -215,7 +230,7 @@ module NewRelic
215
230
  end
216
231
  end
217
232
 
218
- class Statement < String
233
+ class Statement < String
219
234
  attr_accessor :adapter
220
235
  end
221
236
  end