smoke_detector 0.0.4 → 0.1.0

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.
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