newrelic_rpm 3.0.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

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