copperegg-apm 1.0.0.pre6 → 1.0.0.pre7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 25fc7205faebae36a3c3900d91b3cd4f9b546cdc
4
- data.tar.gz: 62b6fc328ed9103b6d6b2da9b1530c0e1f88a9dc
3
+ metadata.gz: b6e3a0e3531849de3332f35761ab4e58d19e0b21
4
+ data.tar.gz: 21a430c08d341f29129701aeb46366f12df4ba96
5
5
  SHA512:
6
- metadata.gz: d9aeef33236e8d6d4a0a97ad9e7e75646fffb3e256670f4ecab417fcdb7fa064dbaaf6b06f3305b9faaaa4c36df0602b4618a6b63e1f5c6a40476ac74443d47d
7
- data.tar.gz: f2fbbe012180b90691727279be8837957886d20c6f22ede1d31a52d4f9620142ab2d615dcaec15565638bde3ea7157c2577c75fd234feb53af0f3624cdf73366
6
+ metadata.gz: bf59d18d0970a2eb9b4783e6d4233c7e311de3e80260d335656d93b59172a8b278ddee6c4035773bd02927e04a5a01fd0a5c433b318bc4fcee28bf14f760b3de
7
+ data.tar.gz: abcfa2620a899fba57a03015cc376e48d3f2e9a2092174885735d0257f368f6e05300e094f788445b4f50ccfeac329c17d4ac2b7e9fa9fd8cec991eec7ad5f1b
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- copperegg-apm (1.0.0.pre6)
4
+ copperegg-apm (1.0.0.pre7)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -1,11 +1,13 @@
1
1
  # CopperEgg APM
2
2
 
3
- Monitor the performance of your application with code instrumentation and exception aggregation.
3
+ Monitor the performance of your application with code instrumentation, exception aggregation, and real user monitoring.
4
4
 
5
5
  **Code instrumentation** measures the elapsed time used to execute a SQL statement, outbound HTTP request, or method call.
6
6
 
7
7
  **Exception aggregation** monitors the number and type of exceptions occurring in your code.
8
8
 
9
+ **Real User Monitoring (RUM)** provides metrics for your we application as it runs within web browsers from the perspective of the end user.
10
+
9
11
  ## Getting Started
10
12
 
11
13
  ### Prerequisites
@@ -177,6 +179,73 @@ Outbound HTTP requests performed within your project will be benchmarked from an
177
179
 
178
180
  When exception benchmarking is enabled, any exception raised in your project will be aggregated by class, source location, and system.
179
181
 
182
+ ## Real User Monitoring
183
+
184
+ Browser monitoring is added to your HTML pages using either Rack middleware or a helper method.
185
+
186
+ ### Rails
187
+
188
+ For Rails projects, you can automatically monitor browser performance by setting the configuration directive `benchmark_browser`:
189
+
190
+ ```ruby
191
+ config.benchmark_browser = true
192
+ ```
193
+
194
+ This will add the `CopperEgg::APM::RUMBlender` to the bottom of the middleware stack.
195
+
196
+ Alternatively, in the Rails configuration, you can insert this anywhere in your middleware stack. For example:
197
+
198
+ ```ruby
199
+ config.middleware.insert_after ActionDispatch::ParamsParser, CopperEgg::APM::RUMBlender
200
+ ```
201
+
202
+ If you prefer to add RUM to your HTML pages manually, you can call the helper method `ce_rum_javascript_tag` in your HTML templates:
203
+
204
+ ```ruby
205
+ <%= ce_rum_javascript_tag %>
206
+ ```
207
+
208
+ For versions prior to 3.2, you will need to include the `CopperEgg::APM::RUM` module into your helper modules:
209
+
210
+ ```ruby
211
+ module ApplicationHelper
212
+ include CopperEgg::APM::RUM
213
+ ```
214
+
215
+ Alternatively, you can include the module in your controllers:
216
+
217
+ ```ruby
218
+ class UsersController < ActionController::Base
219
+ helper CopperEgg::APM::RUM
220
+ ```
221
+
222
+ ### Sinatra
223
+
224
+ The following is an example of adding RUM to your Sinatra app:
225
+
226
+ ```ruby
227
+ require 'sinatra'
228
+ require 'copperegg_apm_config'
229
+
230
+ use Rack::Lint
231
+ use CopperEgg::APM::RUM
232
+
233
+ get '/hello' do
234
+ 'Hello World'
235
+ end
236
+ ```
237
+
238
+ ### Other Rack-based Projects
239
+
240
+ For other Rack-based projects, you can add RUMBlender in your `config.ru` file like so:
241
+
242
+ ```ruby
243
+ require 'copperegg_apm_config'
244
+
245
+ use CopperEgg::APM::RUMBlender
246
+ run MyRackApplication
247
+ ```
248
+
180
249
  ## Disable Gem Functionality
181
250
 
182
251
  To disable all functionality of this gem, call `config.disable` in the configuration block and then restart your application:
Binary file
data/lib/copperegg/apm.rb CHANGED
@@ -18,6 +18,7 @@ end
18
18
  pg/connection
19
19
  restclient/request
20
20
  rum
21
+ rum_blender
21
22
  sqlite3/database
22
23
  typhoeus/hydra
23
24
  unbound_method
@@ -54,8 +54,8 @@ module CopperEgg
54
54
  def benchmarkable_methods
55
55
  return @@benchmarkable_methods if @@benchmarkable_methods.size > 0
56
56
 
57
- if defined?(::Rails) && Rails.respond_to?(:application) && Rails.application.respond_to?(:eager_load!)
58
- Rails.application.eager_load!
57
+ if defined?(::Rails) && ::Rails.respond_to?(:application) && ::Rails.application.respond_to?(:eager_load!)
58
+ ::Rails.application.eager_load!
59
59
  end
60
60
 
61
61
  ObjectSpace.each_object(Class) do |class_or_module|
@@ -19,6 +19,7 @@ module CopperEgg
19
19
  @@benchmark_active_record = false
20
20
  @@benchmark_http = true
21
21
  @@benchmark_exceptions = true
22
+ @@benchmark_browser = false
22
23
  @@benchmark_methods_level = :disabled
23
24
  @@only_methods = []
24
25
  @@exclude_methods = []
@@ -105,6 +106,15 @@ module CopperEgg
105
106
  @@benchmark_exceptions
106
107
  end
107
108
 
109
+ def self.benchmark_browser=(boolean)
110
+ raise ConfigurationError.new("Boolean expected for benchmark_browser") if boolean != true && boolean != false
111
+ @@benchmark_browser = boolean
112
+ end
113
+
114
+ def self.benchmark_browser?
115
+ @@benchmark_browser
116
+ end
117
+
108
118
  def self.benchmark_methods(level, options={})
109
119
  raise ConfigurationError.new("Method benchmark level can only be :disabled, :basic, :moderate, :full, or :custom") if !BENCHMARK_METHOD_LEVELS.include?(level)
110
120
 
@@ -159,7 +169,7 @@ module CopperEgg
159
169
 
160
170
  if @@app_root.empty?
161
171
  @@app_root = if defined?(::Rails) && Rails.respond_to?(:root)
162
- Rails.root.to_s
172
+ ::Rails.root.to_s
163
173
  elsif defined?(RAILS_ROOT)
164
174
  RAILS_ROOT
165
175
  else
@@ -167,14 +177,20 @@ module CopperEgg
167
177
  end
168
178
  end
169
179
 
170
- if @@disabled
171
- @@benchmark_sql = @@benchmark_active_record = @@benchmark_http = @@benchmark_exceptions = false
180
+ if @@disabled || @@instrument_key.empty?
181
+ @@benchmark_sql = @@benchmark_active_record = @@benchmark_http = @@benchmark_exceptions = @@benchmark_browser = false
172
182
  @@benchmark_methods_level = :disabled
173
183
  @@only_methods = []
174
184
  @@exclude_methods = []
175
185
  @@include_methods = []
176
- elsif @@benchmark_methods_level != :disabled
177
- CopperEgg::APM.add_method_benchmarking
186
+ else
187
+ if @@benchmark_methods_level != :disabled
188
+ CopperEgg::APM.add_method_benchmarking
189
+ end
190
+
191
+ if @@benchmark_browser && defined?(::Rails) && ::Rails.respond_to?(:configuration) && ::Rails.configuration.respond_to?(:middleware) && ::Rails.configuration.middleware.respond_to?(:use)
192
+ ::Rails.configuration.middleware.use CopperEgg::APM::RUMBlender
193
+ end
178
194
  end
179
195
  end
180
196
 
@@ -6,7 +6,7 @@ module CopperEgg
6
6
  class Railtie < ::Rails::Railtie
7
7
  initializer "copperegg_apm.helpers" do
8
8
  ActiveSupport.on_load_all do
9
- helper CopperEgg::APM::Rum
9
+ helper CopperEgg::APM::RUM
10
10
  end
11
11
  end
12
12
 
@@ -1,23 +1,22 @@
1
1
  module CopperEgg
2
2
  module APM
3
- module Rum
4
- def real_user_monitoring_javascript_tag
5
- script = %Q(
6
- <script type="text/javascript">
7
- var BACON = BACON || {};
3
+ module RUM
4
+ def ce_rum_javascript_tag
5
+ tag = %Q(
6
+ <script type="text/javascript">
7
+ var BACON = BACON || {};
8
8
 
9
- BACON.id = '#{CopperEgg::APM::Configuration.instrument_key}';
10
- BACON.short_url = #{CopperEgg::APM::Configuration.rum_short_url};
11
- BACON.beaconUrl = '#{CopperEgg::APM::Configuration.rum_beacon_url}';
9
+ BACON.id = '#{Configuration.instrument_key}';
10
+ BACON.short_url = #{Configuration.rum_short_url};
11
+ BACON.beaconUrl = '#{Configuration.rum_beacon_url}';
12
12
 
13
- BACON.starttime = new Date().getTime();
14
- (function(d, s) { var js = d.createElement(s);
15
- js.async = true; js.src = "http://cdn.copperegg.com/rum/bacon.min.js";
16
- var s = d.getElementsByTagName(s)[0]; s.parentNode.insertBefore(js, s);
17
- })(document, "script");
18
- </script>
19
- )
20
- script.respond_to?(:html_safe) ? script.html_safe : script
13
+ BACON.starttime = new Date().getTime();
14
+ (function(d, s) { var js = d.createElement(s);
15
+ js.async = true; js.src = "http://cdn.copperegg.com/rum/bacon.min.js";
16
+ var s = d.getElementsByTagName(s)[0]; s.parentNode.insertBefore(js, s);
17
+ })(document, "script");
18
+ </script>)
19
+ tag.respond_to?(:html_safe) ? tag.html_safe : tag
21
20
  end
22
21
  end
23
22
  end
@@ -0,0 +1,51 @@
1
+ require 'rack'
2
+
3
+ module CopperEgg
4
+ module APM
5
+ class RUMBlender
6
+ include RUM
7
+ RUM_BLENDED_KEY = 'THIS_RUM_BLENDED_FOR_YOU_BY_COPPEREGG'
8
+
9
+ def initialize(app)
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+ status, headers, response = @app.call(env)
15
+
16
+ if status != 200 || env[RUM_BLENDED_KEY] || !CopperEgg::APM::Configuration.benchmark_browser? || !html_request?(headers)
17
+ return [status, headers, response]
18
+ else
19
+ html = ''
20
+ response.each {|part| html << part}
21
+ open_head_tag_index = html.index /<head[^>]*>/
22
+ close_head_tag_index = html.index '</head>'
23
+ open_body_tag_index = html.index /<body[^>]*>/
24
+ close_body_tag_index = html.index '</body>'
25
+
26
+ if open_head_tag_index && open_head_tag_index < close_head_tag_index.to_i && open_head_tag_index < open_body_tag_index.to_i
27
+ html.sub!(/<head[^>]*>/) do |match|
28
+ match.to_s.insert(-1, ce_rum_javascript_tag)
29
+ end
30
+ elsif open_body_tag_index && open_body_tag_index < close_body_tag_index.to_i
31
+ html.sub!(/<body[^>]*>/) do |match|
32
+ match.to_s.insert(-1, ce_rum_javascript_tag)
33
+ end
34
+ else
35
+ return [status, headers, response]
36
+ end
37
+
38
+ headers['Content-Length'] = html.length if headers['Content-Length']
39
+ response = Rack::Response.new(html, status, headers)
40
+ response.finish
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def html_request?(headers)
47
+ headers["Content-Type"].to_s =~ /text\/html/ && !(headers['Content-Disposition'].to_s =~ /attachment/)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -1,5 +1,5 @@
1
1
  module CopperEgg
2
2
  module APM
3
- GEM_VERSION = '1.0.0.pre6' unless defined? GEM_VERSION
3
+ GEM_VERSION = '1.0.0.pre7' unless defined? GEM_VERSION
4
4
  end
5
5
  end
data/spec/rum_spec.rb CHANGED
@@ -2,17 +2,17 @@
2
2
  require 'spec_helper'
3
3
 
4
4
  class String
5
- include CopperEgg::APM::Rum
5
+ include CopperEgg::APM::RUM
6
6
  end
7
7
 
8
- describe CopperEgg::APM::Rum do
9
- describe "#copperegg_real_user_monitoring" do
8
+ describe CopperEgg::APM::RUM do
9
+ describe "#ce_rum_javascript_tag" do
10
10
  before do
11
11
  CopperEgg::APM::Configuration.rum_short_url = true
12
12
  end
13
13
 
14
14
  it "should return javascript" do
15
- javascript = "".real_user_monitoring_javascript_tag
15
+ javascript = "".ce_rum_javascript_tag
16
16
 
17
17
  expect(javascript).to match(/^[\s\n]*<script type="text\/javascript">.*<\/script>[\s\n]*$/m)
18
18
  expect(javascript.include?("BACON.id = '#{CopperEgg::APM::Configuration.instrument_key}';")).to be_true
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: copperegg-apm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre6
4
+ version: 1.0.0.pre7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Bradford
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-06-05 00:00:00.000000000 Z
11
+ date: 2013-06-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -209,7 +209,7 @@ files:
209
209
  - ./lib/copperegg/apm/railtie.rb
210
210
  - ./lib/copperegg/apm/restclient/request.rb
211
211
  - ./lib/copperegg/apm/rum.rb
212
- - ./lib/copperegg/apm/rum_middleware.rb
212
+ - ./lib/copperegg/apm/rum_blender.rb
213
213
  - ./lib/copperegg/apm/sqlite3/database.rb
214
214
  - ./lib/copperegg/apm/tasks.rb
215
215
  - ./lib/copperegg/apm/typhoeus/hydra.rb
@@ -293,7 +293,7 @@ rubyforge_project:
293
293
  rubygems_version: 2.0.3
294
294
  signing_key:
295
295
  specification_version: 4
296
- summary: copperegg-apm-1.0.0.pre6
296
+ summary: copperegg-apm-1.0.0.pre7
297
297
  test_files:
298
298
  - spec/action_controller_spec.rb
299
299
  - spec/apm_spec.rb
@@ -1,45 +0,0 @@
1
- require 'rack'
2
-
3
- module CopperEgg
4
- module APM
5
- class RumMiddleware
6
- RUM_INJECTED_KEY = "COPPEREGG_APM_RUM_INJECTED"
7
-
8
- def initialize(app)
9
- @app = app
10
- end
11
-
12
- def call(evn)
13
- status, headers, response = @app.call(env)
14
-
15
- if status != 200 || rum_injected?(env) || !html_request?(env)
16
- return [status, headers, response]
17
- elsif has_head_tag?(response)
18
- # if html request, extract <head>...</head> from request
19
-
20
- # if <head> is extracted, insert rum <script> tag at the bottom
21
- else
22
- return [status, headers, response]
23
- end
24
- end
25
-
26
- private
27
-
28
- def rum_injected?(env)
29
- env[RUM_INJECTED_KEY]
30
- end
31
-
32
- def html_request?(env)
33
- env["Content-Type"] && env["Content-Type"] =~ /text\/html/
34
- end
35
-
36
- def has_head_tag?(response)
37
-
38
- end
39
-
40
- def inject_rum(response, headers)
41
-
42
- end
43
- end
44
- end
45
- end