airbadger 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c5f8337fbc0d35047075ac0ca52de375b9e8d3f7
4
+ data.tar.gz: 1e8bb7c714e5e74837e8b38243d8789762c503ea
5
+ SHA512:
6
+ metadata.gz: 9c76835f923d0f1851571c7064c42e688f962c0ccd2c12b774007edb87c972b500a8c35f813ccc8f8b3420ad6989b961ec7ca0737328e93cc8289a9c42f1ec8d
7
+ data.tar.gz: 86c7370648a93fe141c9ebc0095b704b42a1447722664d79d3f9c1d0174d6c0254ff31135c9f052678071783832ebbb028e95a43cf5fc13b93e4dd8459e8867a
Binary file
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Josh Jordan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,41 @@
1
+ airbadger
2
+ =========
3
+
4
+ Report errors to multiple Airbrake-compatible APIs simultaneously. Useful for comparing services such as Airbrake, Honeybadger, Errbit, etc. side by side with the same data.
5
+
6
+ Installation
7
+ ============
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'airbadger'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install airbadger
20
+
21
+ Usage
22
+ =====
23
+
24
+ TODO: Write usage instructions here
25
+
26
+ Contributing to airbadger
27
+ =========================
28
+
29
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
30
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
31
+ * Fork the project.
32
+ * Start a feature/bugfix branch.
33
+ * Commit and push until you are happy with your contribution.
34
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
35
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
36
+
37
+ Copyright
38
+ =========
39
+
40
+ Copyright (c) 2013 Josh Jordan. See LICENSE for further details.
41
+
@@ -0,0 +1,10 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ desc 'Open an irb session preloaded with Airbadger'
4
+ task :console do
5
+ sh 'irb -rubygems -I lib -r airbadger.rb -I spec -r spec_helper.rb'
6
+ end
7
+
8
+ require 'rspec/core/rake_task'
9
+ RSpec::Core::RakeTask.new(:spec)
10
+ task :default => :spec
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'airbadger/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "airbadger"
8
+ spec.version = Airbadger::VERSION
9
+ spec.authors = ["Josh Jordan"]
10
+ spec.email = ["josh.jordan@gmail.com"]
11
+ spec.description = %q{To ease the transition when trying out a new error monitoring service, Airbadger can report errors to multiple Airbrake API-compatible endpoints, such as Errbit and Raygun. Honeybadger is also supported.}
12
+ spec.summary = %q{Reports errors to multiple Airbrake-compatible endpoints}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency 'airbrake', '< 3.2'
22
+ spec.add_dependency 'honeybadger', '< 1.9'
23
+
24
+ spec.add_development_dependency 'bundler', '~> 1.3'
25
+ spec.add_development_dependency 'rake', '~> 10.1'
26
+ spec.add_development_dependency 'pry', '~> 0.9'
27
+ spec.add_development_dependency 'rspec', '~> 2.14'
28
+ end
@@ -0,0 +1,30 @@
1
+ require 'airbadger/warning_suppression'
2
+ require 'airbadger/airbrake_loader'
3
+ require 'airbadger/configuration'
4
+
5
+ require 'airbadger/version'
6
+
7
+ module Airbadger
8
+ def self.configure(&block)
9
+ configuration.instance_eval(&block)
10
+ configuration.setup_proxy!
11
+ end
12
+
13
+ def self.method_missing(method_name, *args, &block)
14
+ if PROXIED_METHODS.include? method_name
15
+ configuration.loaded_endpoints.each do |endpoint|
16
+ endpoint.send(method_name, *args, &block)
17
+ end
18
+ return nil
19
+ end
20
+ super
21
+ end
22
+
23
+ private
24
+
25
+ PROXIED_METHODS = [:notify, :notify_or_ignore]
26
+
27
+ def self.configuration
28
+ @configuration ||= Configuration.new
29
+ end
30
+ end
@@ -0,0 +1,40 @@
1
+ class Airbadger::AirbrakeLoader
2
+ def self.load_as(airbrake_alias)
3
+ new(airbrake_alias).load_aliased
4
+ end
5
+
6
+ def load_aliased
7
+ without_recording_loaded_features { require 'airbrake' }
8
+ aliased_module.tap do |loaded_module|
9
+ preserve_namespaced_calls!
10
+ remove_airbrake_from_global_namespace!
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ attr_reader :endpoint_alias
17
+
18
+ def initialize(endpoint_alias)
19
+ @endpoint_alias = endpoint_alias.sub(/^Airbrake$/, 'AirbrakeProxied')
20
+ end
21
+
22
+ def aliased_module
23
+ @aliased_module ||= Object.const_set(endpoint_alias, Airbrake)
24
+ end
25
+
26
+ def preserve_namespaced_calls!
27
+ aliased_module.const_set('Airbrake', aliased_module)
28
+ end
29
+
30
+ def remove_airbrake_from_global_namespace!
31
+ Object.send(:remove_const, 'Airbrake')
32
+ end
33
+
34
+ def without_recording_loaded_features
35
+ feature_count = $LOADED_FEATURES.count
36
+ yield
37
+ ensure
38
+ $LOADED_FEATURES.pop while feature_count < $LOADED_FEATURES.count
39
+ end
40
+ end
@@ -0,0 +1,35 @@
1
+ class Airbadger::Configuration
2
+ include Airbadger::WarningSuppression
3
+
4
+ def endpoint(service_name, &block)
5
+ load_endpoint(service_name).configure(&block)
6
+ end
7
+
8
+ def setup_proxy!
9
+ Object.const_set('Airbrake', Airbadger)
10
+ end
11
+
12
+ def loaded_endpoints
13
+ @loaded_modules ||= []
14
+ end
15
+
16
+ private
17
+
18
+ ENDPOINT_LOADERS = Hash.new(::Airbadger::AirbrakeLoader.method(:load_as)).merge({
19
+ 'Honeybadger' => Proc.new do
20
+ require 'honeybadger'
21
+ Honeybadger
22
+ end
23
+ })
24
+
25
+ def load_endpoint(service_name)
26
+ service_name = ghetto_classify(service_name)
27
+ without_warnings do
28
+ ENDPOINT_LOADERS[service_name].call(service_name)
29
+ end.tap(&loaded_endpoints.method(:push))
30
+ end
31
+
32
+ def ghetto_classify(snake_cased)
33
+ snake_cased.to_s.split('_').collect{ |str| str[0] = str[0].upcase; str }.join
34
+ end
35
+ end
@@ -0,0 +1,3 @@
1
+ module Airbadger
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,9 @@
1
+ module Airbadger::WarningSuppression
2
+ def without_warnings
3
+ #TODO: a better approach would be to log this to an Airbadger logger
4
+ old_verbose, $VERBOSE = $VERBOSE, nil
5
+ yield
6
+ ensure
7
+ $VERBOSE = old_verbose
8
+ end
9
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe Airbadger do
4
+ ['#notify', '#notify_or_ignore'].each do |proxied_method|
5
+ describe proxied_method do
6
+ it 'proxies calls to all configured modules' do
7
+ proxied_method.sub!('#', '')
8
+
9
+ Airbadger.configure do
10
+ endpoint :raygun do |config|
11
+ config.test_mode = true
12
+ end
13
+ endpoint :errbit do |config|
14
+ config.test_mode = true
15
+ end
16
+ end
17
+
18
+ error = Exception.new('Some serious shit went down')
19
+
20
+ Raygun.should_receive(proxied_method).with(error)
21
+ Errbit.should_receive(proxied_method).with(error)
22
+
23
+ Airbadger.send(proxied_method, error)
24
+ end
25
+ end
26
+ end
27
+
28
+ it 'proxies calls to Airbrake to all loaded modules' do
29
+ Airbadger.configure do
30
+ endpoint :raygun do |config|
31
+ config.test_mode = true
32
+ end
33
+ endpoint :airbrake do |config|
34
+ config.test_mode = true
35
+ end
36
+ end
37
+
38
+ error = Exception.new('Some serious shit went down')
39
+
40
+ Raygun.should_receive(:notify).with(error)
41
+ AirbrakeProxied.should_receive(:notify).with(error)
42
+
43
+ Airbrake.notify(error)
44
+ end
45
+
46
+ it 'proxies calls to Honeybadger' do
47
+ Airbadger.configure do
48
+ endpoint :raygun do |config|
49
+ config.test_mode = true
50
+ end
51
+ endpoint :honeybadger do |config|
52
+ config.ignore_only = []
53
+ end
54
+ end
55
+
56
+ error = Exception.new('Some serious shit went down')
57
+
58
+ Raygun.should_receive(:notify).with(error)
59
+ Honeybadger.should_receive(:notify).with(error)
60
+
61
+ Airbadger.notify(error)
62
+ end
63
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe Airbadger::AirbrakeLoader do
4
+ include Airbadger::WarningSuppression
5
+
6
+ describe '.load_as' do
7
+ it 'loads a new Airbrake singleton with the given name' do
8
+ without_warnings do
9
+ described_class.load_as('Errbit')
10
+ described_class.load_as('Raygun')
11
+ end
12
+
13
+ Errbit.should respond_to :notify
14
+ Raygun.should respond_to :notify
15
+ Errbit.should_not eq Raygun
16
+ end
17
+
18
+ it 'produces endpoints singletons capable of receiving error data' do
19
+ without_warnings do
20
+ described_class.load_as('Errbit')
21
+ end
22
+ Errbit.configure do |config|
23
+ config.test_mode = true
24
+ end
25
+
26
+ now = DateTime.now.to_s
27
+ Errbit.notify(Exception.new(now))
28
+
29
+ Errbit.sender.last_notice.should include(now)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe Airbadger::Configuration do
4
+ describe '#endpoint' do
5
+ it 'proxies the configuration block to a named Airbrake singleton' do
6
+ subject.endpoint :BasicAirbrake do |config|
7
+ config.test_mode = true
8
+ end
9
+
10
+ subject.endpoint :Errbit do |config|
11
+ config.test_mode = true
12
+ config.host = 'errbit.example.com'
13
+ end
14
+
15
+ BasicAirbrake.configuration.host.should eq 'api.airbrake.io'
16
+ Errbit.configuration.host.should eq 'errbit.example.com'
17
+ end
18
+
19
+ it 'accepts snake-cased service names and produces constants with proper class names' do
20
+ subject.endpoint :basic_airbrake do |config|
21
+ config.test_mode = true
22
+ end
23
+
24
+ defined?(BasicAirbrake).should be_true
25
+ end
26
+
27
+ it 'rewrites the name "Airbrake" to "AirbrakeProxied" to avoid collisions' do
28
+ subject.endpoint :airbrake do |config|
29
+ config.test_mode = true
30
+ end
31
+
32
+ defined?(Airbrake).should be_false
33
+ defined?(AirbrakeProxied).should be_true
34
+ end
35
+
36
+ it 'supports Honeybadger configuration from the Honeybadger gem rather than the Airbrake gem' do
37
+ Airbadger::AirbrakeLoader.should_receive(:load_as).never
38
+
39
+ subject.endpoint :honeybadger do |config|
40
+ config.ignore_only = []
41
+ end
42
+
43
+ defined?(Honeybadger).should be_true
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,40 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.require(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'rspec'
11
+
12
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
13
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
14
+ require 'airbadger'
15
+
16
+ EXAMPLE_SERVICE_NAMES = [
17
+ 'Airbrake',
18
+ 'AirbrakeProxied',
19
+ 'BasicAirbrake',
20
+ 'Errbit',
21
+ 'Raygun'
22
+ ]
23
+
24
+ RSpec.configure do |config|
25
+ # Run specs in random order to surface order dependencies. If you find an
26
+ # order dependency and want to debug it, you can fix the order by providing
27
+ # the seed, which is printed after each run.
28
+ # --seed 1234
29
+ config.order = 'random'
30
+
31
+ config.before :each do
32
+ EXAMPLE_SERVICE_NAMES.each do |service_name|
33
+ Object.send(:remove_const, service_name) if Object.const_defined?(service_name)
34
+ end
35
+ end
36
+
37
+ config.before :each do
38
+ Airbadger.instance_variable_set('@configuration', nil)
39
+ end
40
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe Airbadger::WarningSuppression do
4
+ include Airbadger::WarningSuppression
5
+
6
+ describe '#without_warnings' do
7
+ before :each do
8
+ @old_version = Airbadger::VERSION
9
+ end
10
+
11
+ let! :error_stream do
12
+ $stderr = StringIO.new
13
+ end
14
+
15
+ it 'executes the block and does not emit warnings into the stderr stream' do
16
+ without_warnings do
17
+ Airbadger::VERSION = 42
18
+ end
19
+
20
+ Airbadger::VERSION.should eq 42
21
+ error_stream.string.should be_empty
22
+ end
23
+
24
+ it 'resumes emitting warnings into the stderr stream after the block' do
25
+ without_warnings do
26
+ Airbadger::VERSION = 42
27
+ end
28
+
29
+ Airbadger::VERSION = 43
30
+
31
+ error_stream.string.should_not be_empty
32
+ end
33
+
34
+ after :each do
35
+ Airbadger::VERSION = @old_version
36
+ $stderr = STDERR
37
+ end
38
+ end
39
+ end
metadata ADDED
@@ -0,0 +1,153 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: airbadger
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Josh Jordan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-10-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: airbrake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - <
18
+ - !ruby/object:Gem::Version
19
+ version: '3.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - <
25
+ - !ruby/object:Gem::Version
26
+ version: '3.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: honeybadger
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - <
32
+ - !ruby/object:Gem::Version
33
+ version: '1.9'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - <
39
+ - !ruby/object:Gem::Version
40
+ version: '1.9'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '10.1'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '10.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '0.9'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '0.9'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '2.14'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '2.14'
97
+ description: To ease the transition when trying out a new error monitoring service,
98
+ Airbadger can report errors to multiple Airbrake API-compatible endpoints, such
99
+ as Errbit and Raygun. Honeybadger is also supported.
100
+ email:
101
+ - josh.jordan@gmail.com
102
+ executables: []
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - .DS_Store
107
+ - .gitignore
108
+ - .rspec
109
+ - Gemfile
110
+ - LICENSE
111
+ - README.md
112
+ - Rakefile
113
+ - airbadger.gemspec
114
+ - lib/airbadger.rb
115
+ - lib/airbadger/airbrake_loader.rb
116
+ - lib/airbadger/configuration.rb
117
+ - lib/airbadger/version.rb
118
+ - lib/airbadger/warning_suppression.rb
119
+ - spec/airbadger_spec.rb
120
+ - spec/airbrake_loader_spec.rb
121
+ - spec/configuration_spec.rb
122
+ - spec/spec_helper.rb
123
+ - spec/warning_suppression_spec.rb
124
+ homepage: ''
125
+ licenses:
126
+ - MIT
127
+ metadata: {}
128
+ post_install_message:
129
+ rdoc_options: []
130
+ require_paths:
131
+ - lib
132
+ required_ruby_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - '>='
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ required_rubygems_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ requirements: []
143
+ rubyforge_project:
144
+ rubygems_version: 2.0.3
145
+ signing_key:
146
+ specification_version: 4
147
+ summary: Reports errors to multiple Airbrake-compatible endpoints
148
+ test_files:
149
+ - spec/airbadger_spec.rb
150
+ - spec/airbrake_loader_spec.rb
151
+ - spec/configuration_spec.rb
152
+ - spec/spec_helper.rb
153
+ - spec/warning_suppression_spec.rb