newrelic_rpm 3.0.0 → 3.0.1

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 CHANGED
@@ -1,3 +1,7 @@
1
+ v3.0.1
2
+ * Updated Real User Monitoring to reduce javascript size and improve
3
+ compatibility, fix a few known bugs
4
+
1
5
  v3.0.0
2
6
  * Support for Real User Monitoring
3
7
  * Back end work on internals to improve reliability
@@ -2,19 +2,23 @@ module NewRelic
2
2
  module Agent
3
3
  class BeaconConfiguration
4
4
  attr_reader :browser_timing_header
5
+ attr_reader :browser_timing_static_footer
5
6
  attr_reader :application_id
6
7
  attr_reader :browser_monitoring_key
7
8
  attr_reader :beacon
8
9
  attr_reader :rum_enabled
9
10
  attr_reader :license_bytes
10
11
 
12
+ JS_HEADER = "<script>var NREUMQ=[];NREUMQ.push([\"mark\",\"firstbyte\",new Date().getTime()]);</script>"
13
+
11
14
  def initialize(connect_data)
12
15
  @browser_monitoring_key = connect_data['browser_key']
13
16
  @application_id = connect_data['application_id']
14
17
  @beacon = connect_data['beacon']
15
18
  @rum_enabled = connect_data['rum.enabled']
16
19
  @rum_enabled = true if @rum_enabled.nil?
17
- @browser_timing_header = build_browser_timing_header(connect_data)
20
+ @browser_timing_header = build_browser_timing_header
21
+ @browser_timing_static_footer = build_load_file_js(connect_data)
18
22
  end
19
23
 
20
24
  def license_bytes
@@ -25,22 +29,22 @@ module NewRelic
25
29
  @license_bytes
26
30
  end
27
31
 
28
- def load_file_js(connect_data)
32
+ def build_load_file_js(connect_data)
29
33
  return "" unless connect_data.fetch('rum.load_episodes_file', true)
30
34
 
31
35
  episodes_url = connect_data.fetch('episodes_url', '')
32
- "(function(){var d=document;var e=d.createElement(\"script\");e.type=\"text/javascript\";e.async=true;e.src=\"#{episodes_url}\";var s=d.getElementsByTagName(\"script\")[0];s.parentNode.insertBefore(e,s);})()"
36
+ "(function(){var d=document;var e=d.createElement(\"script\");e.async=true;e.src=\"#{episodes_url}\";var s=d.getElementsByTagName(\"script\")[0];s.parentNode.insertBefore(e,s);})();"
33
37
  end
34
38
 
35
- def basic_javascript(connect_data)
36
- "<script>var NREUMQ=[];NREUMQ.push([\"mark\",\"firstbyte\",new Date().getTime()]);#{load_file_js(connect_data)}</script>"
39
+ def javascript_header
40
+ JS_HEADER.dup
37
41
  end
38
42
 
39
- def build_browser_timing_header(connect_data)
43
+ def build_browser_timing_header
40
44
  return "" if !@rum_enabled
41
45
  return "" if @browser_monitoring_key.nil?
42
46
 
43
- value = basic_javascript(connect_data)
47
+ value = javascript_header
44
48
  if value.respond_to?(:html_safe)
45
49
  value.html_safe
46
50
  else
@@ -56,7 +56,7 @@ module NewRelic
56
56
 
57
57
  def footer_js_string(beacon, license_key, application_id)
58
58
  obfuscated_transaction_name = obfuscate(browser_monitoring_transaction_name)
59
- html_safe_if_needed("<script type=\"text/javascript\" charset=\"utf-8\">NREUMQ.push([\"nrf2\",\"#{beacon}\",\"#{license_key}\",#{application_id},\"#{obfuscated_transaction_name}\",#{browser_monitoring_queue_time},#{browser_monitoring_app_time}])</script>")
59
+ html_safe_if_needed("<script>#{NewRelic::Agent.instance.beacon_configuration.browser_timing_static_footer}NREUMQ.push([\"nrf2\",\"#{beacon}\",\"#{license_key}\",#{application_id},\"#{obfuscated_transaction_name}\",#{browser_monitoring_queue_time},#{browser_monitoring_app_time},new Date().getTime()])</script>")
60
60
  end
61
61
 
62
62
  def html_safe_if_needed(string)
@@ -76,7 +76,7 @@ module NewRelic
76
76
  index+=1
77
77
  }
78
78
 
79
- [obfuscated].pack("m0").chomp
79
+ [obfuscated].pack("m0").gsub("\n", '')
80
80
  end
81
81
  end
82
82
  end
@@ -9,6 +9,12 @@ module NewRelic::Rack
9
9
 
10
10
  # method required by Rack interface
11
11
  def call(env)
12
+
13
+ # clear out the thread locals we use in case this is a static request
14
+ Thread.current[:newrelic_most_recent_transaction] = nil
15
+ Thread.current[:newrelic_start_time] = Time.now
16
+ Thread.current[:newrelic_queue_time] = 0
17
+
12
18
  result = @app.call(env) # [status, headers, response]
13
19
 
14
20
  if (NewRelic::Agent.browser_timing_header != "") && should_instrument?(result[0], result[1])
@@ -30,7 +36,7 @@ module NewRelic::Rack
30
36
 
31
37
  def autoinstrument_source(response, headers)
32
38
  source = nil
33
- response.each {|fragment| (source) ? (source << f) : (source = fragment)}
39
+ response.each {|fragment| (source) ? (source << fragment) : (source = fragment)}
34
40
 
35
41
  body_start = source.index("<body")
36
42
  body_close = source.rindex("</body>")
@@ -3,7 +3,7 @@ module NewRelic
3
3
  module VERSION #:nodoc:
4
4
  MAJOR = 3
5
5
  MINOR = 0
6
- TINY = 0
6
+ TINY = 1
7
7
  BUILD = nil #'0' # Set to nil for a release, 'beta1', 'alpha', etc for prerelease builds
8
8
  STRING = [MAJOR, MINOR, TINY, BUILD].compact.join('.')
9
9
  end
@@ -138,8 +138,8 @@ common: &default_settings
138
138
  transaction_tracer:
139
139
 
140
140
  # Transaction tracer is enabled by default. Set this to false to
141
- # turn it off. This feature is only available at the Silver and
142
- # above product levels.
141
+ # turn it off. This feature is only available at the Professional
142
+ # and above product levels.
143
143
  enabled: true
144
144
 
145
145
  # Threshold in seconds for when to collect a transaction
@@ -176,7 +176,7 @@ common: &default_settings
176
176
  error_collector:
177
177
 
178
178
  # Error collector is enabled by default. Set this to false to turn
179
- # it off. This feature is only available at the Silver and above
179
+ # it off. This feature is only available at the Professional and above
180
180
  # product levels
181
181
  enabled: true
182
182
 
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{newrelic_rpm}
8
- s.version = "3.0.0"
8
+ s.version = "3.0.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Bill Kayser", "Justin George"]
12
- s.date = %q{2011-05-11}
12
+ s.date = %q{2011-05-20}
13
13
  s.description = %q{New Relic RPM is a Ruby performance management system, developed by
14
14
  New Relic, Inc (http://www.newrelic.com). RPM provides you with deep
15
15
  information about the performance of your Ruby on Rails or Merb
@@ -19,7 +19,7 @@ class NewRelic::Agent::BeaconConfigurationTest < Test::Unit::TestCase
19
19
  assert_equal 'a browser monitoring key', bc.browser_monitoring_key
20
20
  assert_equal 'an application id', bc.application_id
21
21
  assert_equal 'a beacon', bc.beacon
22
- assert_equal 269, bc.browser_timing_header.size
22
+ assert_equal 86, bc.browser_timing_header.size
23
23
  end
24
24
 
25
25
  def test_license_bytes_nil
@@ -50,72 +50,55 @@ class NewRelic::Agent::BeaconConfigurationTest < Test::Unit::TestCase
50
50
  connect_data = {}
51
51
  bc = NewRelic::Agent::BeaconConfiguration.new(connect_data)
52
52
  bc.instance_eval { @rum_enabled = false }
53
- assert_equal '', bc.build_browser_timing_header(connect_data), "should not return a header when rum enabled is false"
53
+ assert_equal '', bc.build_browser_timing_header, "should not return a header when rum enabled is false"
54
54
  end
55
55
 
56
56
  def test_build_browser_timing_header_enabled_but_no_key
57
57
  connect_data = {}
58
58
  bc = NewRelic::Agent::BeaconConfiguration.new(connect_data)
59
59
  bc.instance_eval { @rum_enabled = true; @browser_monitoring_key = nil }
60
- assert_equal '', bc.build_browser_timing_header(connect_data), "should not return a header when browser_monitoring_key is nil"
60
+ assert_equal '', bc.build_browser_timing_header, "should not return a header when browser_monitoring_key is nil"
61
61
  end
62
62
 
63
- def test_build_browser_timing_header_enabled_checking_for_episodes_url
64
- connect_data = {'episodes_url' => 'an episodes url'}
65
- bc = NewRelic::Agent::BeaconConfiguration.new(connect_data)
66
- bc.instance_eval { @rum_enabled = true; @browser_monitoring_key = 'a' * 40 }
67
- assert(bc.build_browser_timing_header(connect_data).include?('an episodes url'), "should include the episodes url in the javascript")
68
- end
69
-
70
63
  def test_build_browser_timing_header_enabled_with_key
71
64
  connect_data = {}
72
65
  bc = NewRelic::Agent::BeaconConfiguration.new(connect_data)
73
66
  bc.instance_eval { @browser_monitoring_key = 'a browser monitoring key' }
74
- bc.expects(:load_file_js).with({}).returns('load file js')
75
- assert(bc.build_browser_timing_header(connect_data).include?('load file js'), "header should be generated when rum is enabled and browser monitoring key is set")
67
+ assert(bc.build_browser_timing_header.include?('NREUMQ'), "header should be generated when rum is enabled and browser monitoring key is set")
76
68
  end
77
69
 
78
- def test_basic_javascript
79
- connect_data = {}
80
- bc = NewRelic::Agent::BeaconConfiguration.new(connect_data)
81
- mock_data = mock('connect data')
82
- bc.expects(:load_file_js).with(mock_data)
83
- # should just pass through the data
84
- bc.basic_javascript(mock_data)
85
- end
86
-
87
70
  def test_build_browser_timing_header_should_html_safe_header
88
71
  mock_javascript = mock('javascript')
89
72
  connect_data = {'browser_key' => 'a' * 40}
90
73
  bc = NewRelic::Agent::BeaconConfiguration.new(connect_data)
91
74
  assert_equal('a' * 40, bc.instance_variable_get('@browser_monitoring_key'), "should save the key from the config")
92
- bc.expects(:basic_javascript).with(connect_data).returns(mock_javascript)
75
+ bc.expects(:javascript_header).returns(mock_javascript)
93
76
  mock_javascript.expects(:respond_to?).with(:html_safe).returns(true)
94
77
  mock_javascript.expects(:html_safe)
95
- bc.build_browser_timing_header(connect_data)
78
+ bc.build_browser_timing_header
96
79
  end
97
80
 
98
- def test_load_file_js_load_episodes_file_false
81
+ def test_build_load_file_js_load_episodes_file_false
99
82
  connect_data = {'rum.load_episodes_file' => false}
100
83
  bc = NewRelic::Agent::BeaconConfiguration.new(connect_data)
101
- assert_equal '', bc.load_file_js(connect_data), "should be empty when load episodes file is false"
84
+ assert_equal '', bc.build_load_file_js(connect_data), "should be empty when load episodes file is false"
102
85
  end
103
86
 
104
- def test_load_file_js_load_episodes_file_missing
87
+ def test_build_load_file_js_load_episodes_file_missing
105
88
  connect_data = {}
106
89
  bc = NewRelic::Agent::BeaconConfiguration.new(connect_data)
107
- assert_equal(183, bc.load_file_js(connect_data).size, "should output the javascript when there is no configuration")
90
+ assert_equal(159, bc.build_load_file_js(connect_data).size, "should output the javascript when there is no configuration")
108
91
  end
109
92
 
110
- def test_load_file_js_load_episodes_file_present
93
+ def test_build_load_file_js_load_episodes_file_present
111
94
  connect_data = {'rum.load_episodes_file' => true}
112
95
  bc = NewRelic::Agent::BeaconConfiguration.new(connect_data)
113
- assert_equal(183, bc.load_file_js(connect_data).size, "should output the javascript when rum.load_episodes_file is true")
96
+ assert_equal(159, bc.build_load_file_js(connect_data).size, "should output the javascript when rum.load_episodes_file is true")
114
97
  end
115
98
 
116
- def test_load_file_js_load_episodes_file_with_episodes_url
99
+ def test_build_load_file_js_load_episodes_file_with_episodes_url
117
100
  connect_data = {'episodes_url' => 'an episodes url'}
118
101
  bc = NewRelic::Agent::BeaconConfiguration.new(connect_data)
119
- assert(bc.load_file_js(connect_data).include?('an episodes url'), "should include the episodes url by default")
102
+ assert(bc.build_load_file_js(connect_data).include?('an episodes url'), "should include the episodes url by default")
120
103
  end
121
104
  end
@@ -30,13 +30,13 @@ class NewRelic::Agent::BrowserMonitoringTest < Test::Unit::TestCase
30
30
 
31
31
  def test_browser_timing_header
32
32
  header = browser_timing_header
33
- assert_equal "<script>var NREUMQ=[];NREUMQ.push([\"mark\",\"firstbyte\",new Date().getTime()]);(function(){var d=document;var e=d.createElement(\"script\");e.type=\"text/javascript\";e.async=true;e.src=\"this_is_my_file\";var s=d.getElementsByTagName(\"script\")[0];s.parentNode.insertBefore(e,s);})()</script>", header
33
+ assert_equal "<script>var NREUMQ=[];NREUMQ.push([\"mark\",\"firstbyte\",new Date().getTime()]);</script>", header
34
34
  end
35
35
 
36
36
  def test_browser_timing_header_with_rum_enabled_not_specified
37
37
  NewRelic::Agent.instance.expects(:beacon_configuration).at_least_once.returns( NewRelic::Agent::BeaconConfiguration.new({"browser_key" => "browserKey", "application_id" => "apId", "beacon"=>"beacon", "episodes_url"=>"this_is_my_file"}))
38
38
  header = browser_timing_header
39
- assert_equal "<script>var NREUMQ=[];NREUMQ.push([\"mark\",\"firstbyte\",new Date().getTime()]);(function(){var d=document;var e=d.createElement(\"script\");e.type=\"text/javascript\";e.async=true;e.src=\"this_is_my_file\";var s=d.getElementsByTagName(\"script\")[0];s.parentNode.insertBefore(e,s);})()</script>", header
39
+ assert_equal "<script>var NREUMQ=[];NREUMQ.push([\"mark\",\"firstbyte\",new Date().getTime()]);</script>", header
40
40
  end
41
41
 
42
42
  def test_browser_timing_header_with_rum_enabled_false
@@ -68,7 +68,8 @@ class NewRelic::Agent::BrowserMonitoringTest < Test::Unit::TestCase
68
68
  Thread.current[:newrelic_start_time] = Time.now
69
69
 
70
70
  footer = browser_timing_footer
71
- assert footer.include?("<script type=\"text/javascript\" charset=\"utf-8\">NREUMQ.push([\"nrf2\",")
71
+ snippet = "<script>(function(){var d=document;var e=d.createElement(\"script\");e.async=true;e.src=\"this_is_my_file\";var s=d.getElementsByTagName(\"script\")[0];s.parentNode.insertBefore(e,s);})();NREUMQ.push([\"nrf2\","
72
+ assert footer.include?(snippet), "Expected footer to include snippet: #{snippet}, but instead was #{footer}"
72
73
  end
73
74
 
74
75
  def test_browser_timing_footer_without_calling_header
@@ -100,8 +101,10 @@ class NewRelic::Agent::BrowserMonitoringTest < Test::Unit::TestCase
100
101
  config.expects(:license_bytes).returns(license_bytes)
101
102
  NewRelic::Agent.instance.expects(:beacon_configuration).returns(config).at_least_once
102
103
  footer = browser_timing_footer
103
- assert footer.include?("<script type=\"text/javascript\" charset=\"utf-8\">NREUMQ.push([\"nrf2\",")
104
- assert footer.include?("])</script>")
104
+ beginning_snippet = "(function(){var d=document;var e=d.createElement(\"script\");e.async=true;e.src=\"this_is_my_file\";var s=d.getElementsByTagName(\"script\")[0];s.parentNode.insertBefore(e,s);})();NREUMQ.push([\"nrf2\","
105
+ ending_snippet = "])</script>"
106
+ assert(footer.include?(beginning_snippet), "expected footer to include beginning snippet: #{beginning_snippet}, but was #{footer}")
107
+ assert(footer.include?(ending_snippet), "expected footer to include ending snippet: #{ending_snippet}, but was #{footer}")
105
108
  end
106
109
 
107
110
  def test_browser_timing_footer_with_no_beacon_configuration
@@ -231,7 +234,7 @@ class NewRelic::Agent::BrowserMonitoringTest < Test::Unit::TestCase
231
234
  self.expects(:obfuscate).with('most recent transaction').returns('most recent transaction')
232
235
 
233
236
  value = footer_js_string(beacon, license_key, application_id)
234
- assert_equal('<script type="text/javascript" charset="utf-8">NREUMQ.push(["nrf2","","",1,"most recent transaction",0,0])</script>', value, "should return the javascript given some default values")
237
+ assert_equal('<script>(function(){var d=document;var e=d.createElement("script");e.async=true;e.src="this_is_my_file";var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(e,s);})();NREUMQ.push(["nrf2","","",1,"most recent transaction",0,0,new Date().getTime()])</script>', value, "should return the javascript given some default values")
235
238
  end
236
239
 
237
240
  def test_html_safe_if_needed_unsafed
@@ -260,4 +263,12 @@ class NewRelic::Agent::BrowserMonitoringTest < Test::Unit::TestCase
260
263
  output = obfuscate(text)
261
264
  assert_equal('YCJrZXV2fih5Y25vaCFtZSR2a2ZkZSp/aXV1', output, "should output obfuscated text")
262
265
  end
266
+
267
+ def test_obfuscate_long_string
268
+ text = 'a happy piece of small text' * 5
269
+ key = (1..40).to_a
270
+ NewRelic::Agent.instance.beacon_configuration.expects(:license_bytes).returns(key)
271
+ output = obfuscate(text)
272
+ assert_equal('YCJrZXV2fih5Y25vaCFtZSR2a2ZkZSp/aXV1YyNsZHZ3cSl6YmluZCJsYiV1amllZit4aHl2YiRtZ3d4cCp7ZWhiZyNrYyZ0ZWhmZyx5ZHp3ZSVuZnh5cyt8ZGRhZiRqYCd7ZGtnYC11Z3twZCZvaXl6cix9aGdgYSVpYSh6Z2pgYSF2Znxx', output, "should output obfuscated text")
273
+ end
263
274
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: newrelic_rpm
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
5
- prerelease:
4
+ hash: 5
5
+ prerelease: false
6
6
  segments:
7
7
  - 3
8
8
  - 0
9
- - 0
10
- version: 3.0.0
9
+ - 1
10
+ version: 3.0.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Bill Kayser
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-05-11 00:00:00 -07:00
19
+ date: 2011-05-20 00:00:00 -07:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -369,7 +369,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
369
369
  requirements: []
370
370
 
371
371
  rubyforge_project:
372
- rubygems_version: 1.5.2
372
+ rubygems_version: 1.3.7
373
373
  signing_key:
374
374
  specification_version: 3
375
375
  summary: New Relic Ruby Performance Monitoring Agent