smoke_detector 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +5 -13
  2. data/README.md +1 -2
  3. data/lib/smoke_detector/engine.rb +4 -2
  4. data/lib/smoke_detector/middleware/javascript_monitors.rb +36 -0
  5. data/lib/smoke_detector/providers/airbrake.rb +2 -1
  6. data/lib/smoke_detector/providers/provider.rb +12 -0
  7. data/lib/smoke_detector/providers/rollbar.rb +18 -1
  8. data/lib/smoke_detector/providers.rb +2 -2
  9. data/lib/smoke_detector/version.rb +1 -1
  10. data/lib/smoke_detector.rb +1 -0
  11. data/spec/dummy/app/controllers/widgets_controller.rb +3 -0
  12. data/spec/dummy/config/initializers/smoke_detector.rb +1 -0
  13. data/spec/dummy/config/routes.rb +1 -0
  14. data/spec/dummy/db/development.sqlite3 +0 -0
  15. data/spec/dummy/db/test.sqlite3 +0 -0
  16. data/spec/dummy/log/development.log +5 -8619
  17. data/spec/dummy/log/test.log +1251 -13557
  18. data/spec/models/providers/airbrake_spec.rb +1 -1
  19. data/spec/models/providers/provider_spec.rb +2 -1
  20. data/spec/models/providers/rollbar_spec.rb +2 -2
  21. data/spec/models/providers_spec.rb +5 -4
  22. data/spec/models/smoke_detector_spec.rb +2 -2
  23. data/spec/requests/aibrake_config_spec.rb +1 -1
  24. data/spec/requests/middleware/javascript_monitors_spec.rb +38 -0
  25. data/spec/requests/multi_provider_config_spec.rb +2 -2
  26. data/spec/requests/rollbar_config_spec.rb +1 -1
  27. metadata +32 -49
  28. data/spec/dummy/tmp/cache/assets/C5F/270/sprockets%2F32a6d17723de2976b8456753922862fc +0 -0
  29. data/spec/dummy/tmp/cache/assets/CA3/870/sprockets%2F703bc6444d2a153516ad9804dc24b467 +0 -0
  30. data/spec/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
  31. data/spec/dummy/tmp/cache/assets/D2F/510/sprockets%2F42e50ab0277768533b1cad2237fb5ade +0 -0
  32. data/spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  33. data/spec/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
  34. data/spec/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
  35. data/spec/dummy/tmp/cache/assets/DAE/CC0/sprockets%2Fcf340221edaaed61b5821abd28052dbb +0 -0
  36. data/spec/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
  37. data/spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZTJjMjcwN2FjYzJkMWE0MDk2MGZkOTkzZTBiMWQ1NjFkMTZjNjJiYg==
5
- data.tar.gz: !binary |-
6
- NTM3NzQ0NDQwNmVlN2JiYmQ3ZGM0NWM3ODMxOWIwNzY2YTFmZTlhYw==
2
+ SHA1:
3
+ metadata.gz: 67ea73e289c565de0a494339d3e8c6ee817536b3
4
+ data.tar.gz: 0ba4efd5ad042ab55e4c10ea8aaa2c18c9f9581e
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- ZGIzMmU5MTg1N2JhZTgxMjdkYzBkOGNjZTRjNWYyYmVjNjY4NjlkZjBlMTQ0
10
- ZmU4YzlkNTNiMDBiMWIyZDZmNjQxNDUxM2M4ODA5YmFmMWY4Y2Q1Nzc5NmUx
11
- NmRkMjgwN2YzZjQ0ZDY2NDlhNWY2MzUyN2U4NTcyN2IzMzcwM2M=
12
- data.tar.gz: !binary |-
13
- MzczNzY3NWIzMjI2YzEzNDNhZjBlMDc4YTcxNTI2YzRmNjM4NzNiNTY2OTU3
14
- ZThlNWUyNjY2YmYzMjlmMWZjYTMyMTYwMTQ1ZTI5ZWY5MWU3MThhYTZlM2I0
15
- MDc5MDBmYWMxNGUxZWE2NWZiYWNjZDZhZDczNzk4MDYxYWM5MWY=
6
+ metadata.gz: 6ebf7ffe6004f2e455cffabe41192efda281dee5422c0a42c1ebd39f9e6334c01e542b1465ff5f4e81ee8c682c8e635a7235cc8e9d313397855486c149f4e071
7
+ data.tar.gz: 4b42088c4c9275e6eab33485224664097b244d7778aa383a72394bd3d84c95dedf8caddd9a00125e0c60906ff9f680ce3c51066faf70d851833bf33eeb821e6f
data/README.md CHANGED
@@ -45,5 +45,4 @@ TODO
45
45
  ----
46
46
 
47
47
  1. Add support for JS reporting snippets
48
- 2. Add support for all configuration settings
49
- 3. Add support for capistrano deploy announcements
48
+ 2. Add support for capistrano deploy announcements
@@ -3,14 +3,16 @@ module SmokeDetector
3
3
 
4
4
  config.providers = nil
5
5
 
6
- initializer 'smoke_detector.init_error_handler' do
6
+ initializer 'smoke_detector.init_error_handler' do |app|
7
7
  config.providers.each do |provider|
8
- SmokeDetector.register_provider provider[:provider], provider[:api_key], provider[:settings] || {}
8
+ SmokeDetector.register_provider(provider[:provider], provider[:api_key], provider[:client_api_key], provider[:settings] || {})
9
9
  end
10
10
 
11
11
  ActiveSupport.on_load(:action_controller) do
12
12
  include SmokeDetector::ControllerMethods
13
13
  end
14
+
15
+ app.middleware.use SmokeDetector::JavaScriptMonitors
14
16
  end
15
17
  end
16
18
  end
@@ -0,0 +1,36 @@
1
+ module SmokeDetector
2
+ class JavaScriptMonitors
3
+
4
+ TARGET_TAG = '<head>'
5
+ ACCEPTABLE_CONTENT = /text\/html|application\/xhtml\+xml/
6
+
7
+ def initialize(app)
8
+ @app = app
9
+ end
10
+
11
+ def call(env)
12
+ status, headers, response = @app.call(env)
13
+
14
+ if monitor?(headers)
15
+ body = response.body
16
+ if index = body.rindex(TARGET_TAG) + TARGET_TAG.length + 1
17
+ body.insert(index, monitoring_code)
18
+ headers["Content-Length"] = body.length.to_s
19
+ response = [body]
20
+ end
21
+ end
22
+
23
+ [status, headers, response]
24
+ end
25
+
26
+ private
27
+
28
+ def monitoring_code
29
+ @monitoring_code ||= SmokeDetector.providers.map(&:client_monitoring_code).join('')
30
+ end
31
+
32
+ def monitor?(headers)
33
+ headers["Content-Type"] =~ ACCEPTABLE_CONTENT && monitoring_code.present?
34
+ end
35
+ end
36
+ end
@@ -1,7 +1,8 @@
1
1
  module SmokeDetector::Providers
2
2
  class Airbrake < Provider
3
3
 
4
- def initialize(api_key, settings = {})
4
+ def initialize(api_key, client_api_key = nil, settings = {})
5
+ super
5
6
  ::Airbrake.configure do |c|
6
7
  c.api_key = api_key
7
8
  apply_configuration_settings(c, settings)
@@ -3,6 +3,10 @@ module SmokeDetector::Providers
3
3
  class Provider
4
4
  attr_accessor :controller_proc
5
5
 
6
+ def initialize(api_key, client_api_key = nil, settings = {})
7
+ @client_api_key = client_api_key
8
+ end
9
+
6
10
  def alert(exception, options = {})
7
11
  raise NotImplementedError
8
12
  end
@@ -11,8 +15,16 @@ module SmokeDetector::Providers
11
15
  raise NotImplementedError
12
16
  end
13
17
 
18
+ def client_monitoring_code
19
+ ''
20
+ end
21
+
14
22
  private
15
23
 
24
+ def client_api_key
25
+ @client_api_key
26
+ end
27
+
16
28
  def apply_configuration_settings(configuration, settings)
17
29
  settings.each do |setting, value|
18
30
  raise(ArgumentError, "#{setting} is not a valid #{self.class.name} configuration setting") unless configuration.respond_to?("#{setting}=")
@@ -2,7 +2,8 @@ module SmokeDetector::Providers
2
2
 
3
3
  class Rollbar < Provider
4
4
 
5
- def initialize(api_key, settings = {})
5
+ def initialize(api_key, client_api_key = nil, settings = {})
6
+ super
6
7
  ::Rollbar.configure do |c|
7
8
  c.environment = ::Rails.env # Rollbar sets this to 'unspecified' by default
8
9
 
@@ -30,6 +31,22 @@ module SmokeDetector::Providers
30
31
  ::Rollbar.report_message(message, level, options)
31
32
  end
32
33
 
34
+ def client_monitoring_code
35
+ return '' if client_api_key.blank?
36
+ @client_monitoring_code ||= <<-JS
37
+ <script>
38
+ var _rollbarConfig = {
39
+ accessToken: "#{@client_api_key}",
40
+ captureUncaught: true,
41
+ payload: {
42
+ environment: "#{::Rails.env}"
43
+ }
44
+ };
45
+ !function(a,b){function c(b){this.shimId=++f,this.notifier=null,this.parentShim=b,this.logger=function(){},a.console&&void 0===a.console.shimId&&(this.logger=a.console.log)}function d(b){var d=c;return e(function(){if(this.notifier)return this.notifier[b].apply(this.notifier,arguments);var c=this,e="scope"===b;e&&(c=new d(this));var f=Array.prototype.slice.call(arguments,0),g={shim:c,method:b,args:f,ts:new Date};return a._rollbarShimQueue.push(g),e?c:void 0})}function e(a,b){return b=b||this.logger,function(){try{return a.apply(this,arguments)}catch(c){b("Rollbar internal error:",c)}}}var f=0;c.init=function(a,b){var d=b.globalAlias||"Rollbar";if("object"==typeof a[d])return a[d];a._rollbarShimQueue=[],b=b||{};var f=new c;return e(function(){if(f.configure(b),b.captureUncaught){var c=a.onerror;a.onerror=function(){f.uncaughtError.apply(f,arguments),c&&c.apply(a,arguments)}}return a[d]=f,f},f.logger)()},c.prototype.loadFull=function(a,b,c,d){var f=e(function(){var a=b.createElement("script"),e=b.getElementsByTagName("script")[0];a.src=d.rollbarJsUrl,a.async=!c,a.onload=g,e.parentNode.insertBefore(a,e)},this.logger),g=e(function(){if(void 0===a._rollbarPayloadQueue)for(var b,c,d,e,f=new Error("rollbar.js did not load");b=a._rollbarShimQueue.shift();)for(d=b.args,e=0;e<d.length;++e)if(c=d[e],"function"==typeof c){c(f);break}},this.logger);e(function(){c?f():a.addEventListener?a.addEventListener("load",f,!1):a.attachEvent("onload",f)},this.logger)()};for(var g="log,debug,info,warn,warning,error,critical,global,configure,scope,uncaughtError".split(","),h=0;h<g.length;++h)c.prototype[g[h]]=d(g[h]);var i="//d37gvrvc0wt4s1.cloudfront.net/js/v1.0/rollbar.min.js";_rollbarConfig.rollbarJsUrl=_rollbarConfig.rollbarJsUrl||i;var j=c.init(a,_rollbarConfig);j.loadFull(a,b,!1,_rollbarConfig)}(window,document);
46
+ </script>
47
+ JS
48
+ end
49
+
33
50
  module ControllerMethods
34
51
  def alert_smoke_detector(exception, options = {})
35
52
  super if defined?(super)
@@ -6,11 +6,11 @@ module SmokeDetector
6
6
  :rollbar
7
7
  ]
8
8
 
9
- def self.register_provider(provider_name, api_key, settings = {})
9
+ def self.register_provider(provider_name, api_key, client_api_key, settings = {})
10
10
  @providers ||= []
11
11
  raise ProviderRegistrationError, 'Unsupported Provider' unless PROVIDERS.include?(provider_name)
12
12
  raise ProviderRegistrationError, 'Provider is already registered' if registered_provider?(provider_name)
13
- @providers << classify_provider(provider_name).new(api_key, settings)
13
+ @providers << classify_provider(provider_name).new(api_key, client_api_key, settings)
14
14
  end
15
15
 
16
16
  def self.providers
@@ -1,3 +1,3 @@
1
1
  module SmokeDetector
2
- VERSION = "0.0.4"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -1,6 +1,7 @@
1
1
  require 'smoke_detector/exceptions'
2
2
  require 'smoke_detector/providers'
3
3
  require 'smoke_detector/controller_methods'
4
+ require 'smoke_detector/middleware/javascript_monitors'
4
5
  require 'smoke_detector/engine'
5
6
 
6
7
  module SmokeDetector
@@ -1,5 +1,8 @@
1
1
  class WidgetsController < ApplicationController
2
2
 
3
+ def index
4
+ end
5
+
3
6
  def bubble_up
4
7
  raise 'bubble_up'
5
8
  render :index
@@ -7,6 +7,7 @@ module SmokeDetector
7
7
  {
8
8
  provider: :rollbar,
9
9
  api_key: 'fake_rollbar',
10
+ client_api_key: 'fake_rollbar_client',
10
11
  settings: {
11
12
  use_async: true
12
13
  }
@@ -1,4 +1,5 @@
1
1
  Dummy::Application.routes.draw do
2
+ resources :widgets, only: :index
2
3
  match '/widgets/bubble_up' => 'widgets#bubble_up'
3
4
  match '/widgets/deep_bubble_up' => 'widgets#deep_bubble_up'
4
5
  match '/widgets/catch' => 'widgets#catch'
Binary file
Binary file