bugsnag 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+ gem "multi_json"
6
+ gem "httparty"
7
+
8
+ # Add dependencies to develop your gem here.
9
+ # Include everything needed to run rake, tests, features, etc.
10
+ group :development do
11
+ gem "shoulda", ">= 0"
12
+ gem "bundler", "~> 1.0.0"
13
+ gem "jeweler", "~> 1.6.4"
14
+ gem "rcov", ">= 0"
15
+ end
@@ -0,0 +1,26 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ crack (0.1.8)
5
+ git (1.2.5)
6
+ httparty (0.7.8)
7
+ crack (= 0.1.8)
8
+ jeweler (1.6.4)
9
+ bundler (~> 1.0)
10
+ git (>= 1.2.5)
11
+ rake
12
+ multi_json (1.0.3)
13
+ rake (0.9.2)
14
+ rcov (0.9.11)
15
+ shoulda (2.11.3)
16
+
17
+ PLATFORMS
18
+ ruby
19
+
20
+ DEPENDENCIES
21
+ bundler (~> 1.0.0)
22
+ httparty
23
+ jeweler (~> 1.6.4)
24
+ multi_json
25
+ rcov
26
+ shoulda
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 James Smith
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ = bugsnag
2
+
3
+ Description goes here.
4
+
5
+ == Contributing to bugsnag
6
+
7
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
8
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
9
+ * Fork the project
10
+ * Start a feature/bugfix branch
11
+ * Commit and push until you are happy with your contribution
12
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
+ * 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.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2011 James Smith. See LICENSE.txt for
18
+ further details.
19
+
@@ -0,0 +1,56 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "bugsnag"
18
+ gem.homepage = "http://github.com/bugsnag/bugsnag-ruby"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Ruby notifier for bugsnag.com}
21
+ gem.description = %Q{Ruby notifier for bugsnag.com}
22
+ gem.email = "james@bugsnag.com"
23
+ gem.authors = ["James Smith"]
24
+
25
+ # dependencies defined in Gemfile
26
+ gem.add_dependency "multi_json"
27
+ gem.add_dependency "httparty"
28
+ end
29
+ Jeweler::RubygemsDotOrgTasks.new
30
+
31
+ require 'rake/testtask'
32
+ Rake::TestTask.new(:test) do |test|
33
+ test.libs << 'lib' << 'test'
34
+ test.pattern = 'test/**/test_*.rb'
35
+ test.verbose = true
36
+ end
37
+
38
+ require 'rcov/rcovtask'
39
+ Rcov::RcovTask.new do |test|
40
+ test.libs << 'test'
41
+ test.pattern = 'test/**/test_*.rb'
42
+ test.verbose = true
43
+ test.rcov_opts << '--exclude "gems/*"'
44
+ end
45
+
46
+ task :default => :test
47
+
48
+ require 'rake/rdoctask'
49
+ Rake::RDocTask.new do |rdoc|
50
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
51
+
52
+ rdoc.rdoc_dir = 'rdoc'
53
+ rdoc.title = "bugsnag #{version}"
54
+ rdoc.rdoc_files.include('README*')
55
+ rdoc.rdoc_files.include('lib/**/*.rb')
56
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,49 @@
1
+ require "rubygems"
2
+
3
+ # begin
4
+ # require "active_support"
5
+ # require "active_support/core_ext"
6
+ # rescue LoadError
7
+ # require "activesupport"
8
+ # require "activesupport/core_ext"
9
+ # end
10
+
11
+ require "bugsnag/configuration"
12
+ require "bugsnag/event"
13
+ require "bugsnag/notifier"
14
+ require "bugsnag/version"
15
+
16
+ require "bugsnag/rack"
17
+ require "bugsnag/railtie" if defined?(Rails::Railtie)
18
+
19
+ module Bugsnag
20
+ LOG_PREFIX = "** [Bugsnag] "
21
+
22
+ class << self
23
+ attr_accessor :notifier
24
+
25
+ def configure
26
+ yield(configuration)
27
+ self.notifier = Notifier.new(configuration)
28
+
29
+ log "Bugsnag exception handler #{VERSION} ready, #{configuration.to_hash.inspect}"
30
+ end
31
+
32
+ def notify(exception)
33
+ notifier.notify(exception)
34
+ end
35
+
36
+ def log(message)
37
+ logger.info(LOG_PREFIX + message) if logger
38
+ end
39
+
40
+ private
41
+ def configuration
42
+ @configuration ||= Bugsnag::Configuration.new
43
+ end
44
+
45
+ def logger
46
+ configuration.logger
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,18 @@
1
+ module Bugsnag
2
+ class Configuration
3
+ @@options = :api_key, :release_stage, :endpoint, :project_root, :logger
4
+ @@options.each do |attribute|
5
+ attr_accessor attribute
6
+ end
7
+
8
+ def initialize
9
+ @endpoint = "http://api.bugsnag.com/notify"
10
+ end
11
+
12
+ def to_hash
13
+ @@options.inject({}) do |hash, option|
14
+ hash.merge(option.to_sym => send(option))
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,71 @@
1
+ require "multi_json"
2
+
3
+ module Bugsnag
4
+ class Event
5
+ attr_accessor :exception, :user_id, :app_environment, :web_environment, :meta_data
6
+
7
+ def initialize(exception, user_id, env={})
8
+ self.exception = exception
9
+ self.user_id = user_id
10
+ self.app_environment = env[:app_environment]
11
+ self.web_environment = env[:web_environment]
12
+ self.meta_data = env[:meta_data]
13
+ end
14
+
15
+ def error_class
16
+ exception.class.to_s
17
+ end
18
+
19
+ def message
20
+ exception.message
21
+ end
22
+
23
+ def stacktrace(project_path=nil)
24
+ return @stacktrace if @stacktrace
25
+
26
+ if exception.backtrace
27
+ @stacktrace = exception.backtrace.map do |trace|
28
+ method = nil
29
+ file, line, method_str = trace.split(":")
30
+
31
+ trace_hash = {
32
+ :file => file,
33
+ :lineNumber => line
34
+ }
35
+
36
+ if method_str
37
+ method_match = /in `([^']+)'/.match(method_str)
38
+ method = method_match.captures.first if method_match
39
+ end
40
+
41
+ trace_hash[:method] = method if method
42
+ trace_hash[:inProject] = true if project_path && file.match(/^#{project_path}/)
43
+
44
+ trace_hash
45
+ end
46
+ else
47
+ @stacktrace = []
48
+ end
49
+
50
+ @stacktrace
51
+ end
52
+
53
+ def as_hash
54
+ {
55
+ :userId => user_id,
56
+ :causes => [{
57
+ :errorClass => error_class,
58
+ :message => message,
59
+ :stacktrace => stacktrace
60
+ }],
61
+ :appEnvironment => app_environment,
62
+ :webEnvironment => web_environment,
63
+ :metaData => meta_data
64
+ }
65
+ end
66
+
67
+ def as_json
68
+ MultiJson.encode(as_hash)
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,55 @@
1
+ require "httparty"
2
+ require "multi_json"
3
+
4
+ module Bugsnag
5
+ class Notifier
6
+ include HTTParty
7
+
8
+ headers "Content-Type" => "application/json"
9
+
10
+ NOTIFIER_NAME = "Ruby Bugsnag Notifier"
11
+ NOTIFIER_VERSION = "1.0.0"
12
+ NOTIFIER_URL = "http://www.bugsnag.com"
13
+
14
+ def initialize(configuration)
15
+ @configuration = configuration
16
+ end
17
+
18
+ def notify(exception, meta_data={})
19
+ event = Bugsnag::Event.new(exception, "TODO USER ID", {
20
+ :app_environment => build_app_environment,
21
+ :web_environment => build_web_environment,
22
+ :meta_data => meta_data
23
+ })
24
+
25
+ payload = {
26
+ :apiKey => @configuration.api_key,
27
+ :notifier => {
28
+ :name => NOTIFIER_NAME,
29
+ :version => NOTIFIER_VERSION,
30
+ :url => NOTIFIER_URL
31
+ },
32
+ :errors => [event.as_hash]
33
+ }
34
+
35
+ self.class.post(@configuration.endpoint, {:body => MultiJson.encode(payload)})
36
+
37
+ Bugsnag.log("Notified bugsnag.com of exception")
38
+ end
39
+
40
+ private
41
+ def build_app_environment
42
+ {
43
+ :releaseStage => @configuration.release_stage,
44
+ :projectRoot => @configuration.project_root.to_s
45
+ # TODO: Add in environmental variables
46
+ }
47
+ end
48
+
49
+ def build_web_environment
50
+ {
51
+
52
+ }
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,22 @@
1
+ module Bugsnag
2
+ class Rack
3
+ def initialize(app)
4
+ @app = app
5
+ end
6
+
7
+ def call(env)
8
+ begin
9
+ response = @app.call(env)
10
+ rescue Exception => raised
11
+ Bugsnag.notify(raised)
12
+ raise
13
+ end
14
+
15
+ if env["rack.exception"]
16
+ Bugsnag.notify(env["rack.exception"])
17
+ end
18
+
19
+ response
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ require "bugsnag"
2
+ require "bugsnag/rails/action_controller_rescue"
3
+
4
+ module Bugsnag
5
+ module Rails
6
+ def self.initialize
7
+ if defined?(ActionController::Base)
8
+ ActionController::Base.send(:include, Bugsnag::Rails::ActionControllerRescue)
9
+ end
10
+
11
+ Bugsnag.configure(true) do |config|
12
+ config.logger = rails_logger
13
+ config.environment_name = RAILS_ENV if defined?(RAILS_ENV)
14
+ config.project_root = RAILS_ROOT if defined?(RAILS_ROOT)
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ Bugsnag::Rails.initialize
@@ -0,0 +1,16 @@
1
+ module Bugsnag
2
+ module Rails
3
+ module ActionControllerRescue
4
+ def self.included(base)
5
+ base.send(:alias_method, :rescue_action_in_public_without_bugsnag, :rescue_action_in_public)
6
+ base.send(:alias_method, :rescue_action_in_public, :rescue_action_in_public_with_bugsnag)
7
+ end
8
+
9
+ private
10
+ def rescue_action_in_public_with_bugsnag(exception)
11
+ Bugsnag.notify(exception)
12
+ rescue_action_in_public_without_scepter(exception)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,7 @@
1
+ module Bugsnag
2
+ module Rails
3
+ module ControllerMethods
4
+ # TODO
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,27 @@
1
+ require "bugsnag"
2
+ require "rails"
3
+
4
+ module Bugsnag
5
+ class Railtie < Rails::Railtie
6
+ rake_tasks do
7
+ # TODO: Add in rake tasks
8
+ end
9
+
10
+ initializer "bugsnag.use_rack_middleware" do |app|
11
+ app.config.middleware.use "Bugsnag::Rack"
12
+ end
13
+
14
+ config.after_initialize do
15
+ Bugsnag.configure do |config|
16
+ config.logger ||= Rails.logger
17
+ config.release_stage ||= Rails.env
18
+ config.project_root ||= Rails.root
19
+ end
20
+
21
+ if defined?(::ActionController::Base)
22
+ require "bugsnag/rails/controller_methods"
23
+ ::ActionController::Base.send(:include, Bugsnag::Rails::ControllerMethods)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ module Bugsnag
2
+ VERSION = File.read(File.join(File.dirname(__FILE__), "../../VERSION"))
3
+ end
@@ -0,0 +1 @@
1
+ require "bugsnag/rails"
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(: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 'test/unit'
11
+ require 'shoulda'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ require 'bugsnag'
16
+
17
+ class Test::Unit::TestCase
18
+ end
@@ -0,0 +1,29 @@
1
+ require 'helper'
2
+
3
+ class TestBugsnag < Test::Unit::TestCase
4
+ should "get a 200 response from bugsnag.com for basic exceptions" do
5
+ flunk "oh my" if lets.code != 200
6
+ end
7
+
8
+ private
9
+ def lets
10
+ begin
11
+ go
12
+ rescue Exception => e
13
+ event = Bugsnag::Event.new(e, "12345", {:app_environment => {:releaseStage => "production"}})
14
+
15
+ # Bugsnag::Notifier.set_endpoint("http://localhost:8000")
16
+ # Bugsnag::Notifier.notify("145260904aa22d52bf2a82076d157c38", event)
17
+
18
+ return Bugsnag::Notifier.notify("d6db01214d22ac808ce6afdfa4c3f148", event)
19
+ end
20
+ end
21
+
22
+ def go
23
+ deep
24
+ end
25
+
26
+ def deep
27
+ raise RuntimeError.new("Stuff happens")
28
+ end
29
+ end
metadata ADDED
@@ -0,0 +1,200 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bugsnag
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - James Smith
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-10-10 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ prerelease: false
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ hash: 3
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ version_requirements: *id001
32
+ name: multi_json
33
+ type: :runtime
34
+ - !ruby/object:Gem::Dependency
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ hash: 3
42
+ segments:
43
+ - 0
44
+ version: "0"
45
+ version_requirements: *id002
46
+ name: httparty
47
+ type: :runtime
48
+ - !ruby/object:Gem::Dependency
49
+ prerelease: false
50
+ requirement: &id003 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ hash: 3
56
+ segments:
57
+ - 0
58
+ version: "0"
59
+ version_requirements: *id003
60
+ name: shoulda
61
+ type: :development
62
+ - !ruby/object:Gem::Dependency
63
+ prerelease: false
64
+ requirement: &id004 !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ hash: 23
70
+ segments:
71
+ - 1
72
+ - 0
73
+ - 0
74
+ version: 1.0.0
75
+ version_requirements: *id004
76
+ name: bundler
77
+ type: :development
78
+ - !ruby/object:Gem::Dependency
79
+ prerelease: false
80
+ requirement: &id005 !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ hash: 7
86
+ segments:
87
+ - 1
88
+ - 6
89
+ - 4
90
+ version: 1.6.4
91
+ version_requirements: *id005
92
+ name: jeweler
93
+ type: :development
94
+ - !ruby/object:Gem::Dependency
95
+ prerelease: false
96
+ requirement: &id006 !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ hash: 3
102
+ segments:
103
+ - 0
104
+ version: "0"
105
+ version_requirements: *id006
106
+ name: rcov
107
+ type: :development
108
+ - !ruby/object:Gem::Dependency
109
+ prerelease: false
110
+ requirement: &id007 !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ hash: 3
116
+ segments:
117
+ - 0
118
+ version: "0"
119
+ version_requirements: *id007
120
+ name: multi_json
121
+ type: :runtime
122
+ - !ruby/object:Gem::Dependency
123
+ prerelease: false
124
+ requirement: &id008 !ruby/object:Gem::Requirement
125
+ none: false
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ hash: 3
130
+ segments:
131
+ - 0
132
+ version: "0"
133
+ version_requirements: *id008
134
+ name: httparty
135
+ type: :runtime
136
+ description: Ruby notifier for bugsnag.com
137
+ email: james@bugsnag.com
138
+ executables: []
139
+
140
+ extensions: []
141
+
142
+ extra_rdoc_files:
143
+ - LICENSE.txt
144
+ - README.rdoc
145
+ files:
146
+ - .document
147
+ - Gemfile
148
+ - Gemfile.lock
149
+ - LICENSE.txt
150
+ - README.rdoc
151
+ - Rakefile
152
+ - VERSION
153
+ - lib/bugsnag.rb
154
+ - lib/bugsnag/configuration.rb
155
+ - lib/bugsnag/event.rb
156
+ - lib/bugsnag/notifier.rb
157
+ - lib/bugsnag/rack.rb
158
+ - lib/bugsnag/rails.rb
159
+ - lib/bugsnag/rails/action_controller_rescue.rb
160
+ - lib/bugsnag/rails/controller_methods.rb
161
+ - lib/bugsnag/railtie.rb
162
+ - lib/bugsnag/version.rb
163
+ - rails/init.rb
164
+ - test/helper.rb
165
+ - test/test_bugsnag.rb
166
+ homepage: http://github.com/bugsnag/bugsnag-ruby
167
+ licenses:
168
+ - MIT
169
+ post_install_message:
170
+ rdoc_options: []
171
+
172
+ require_paths:
173
+ - lib
174
+ required_ruby_version: !ruby/object:Gem::Requirement
175
+ none: false
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ hash: 3
180
+ segments:
181
+ - 0
182
+ version: "0"
183
+ required_rubygems_version: !ruby/object:Gem::Requirement
184
+ none: false
185
+ requirements:
186
+ - - ">="
187
+ - !ruby/object:Gem::Version
188
+ hash: 3
189
+ segments:
190
+ - 0
191
+ version: "0"
192
+ requirements: []
193
+
194
+ rubyforge_project:
195
+ rubygems_version: 1.8.10
196
+ signing_key:
197
+ specification_version: 3
198
+ summary: Ruby notifier for bugsnag.com
199
+ test_files: []
200
+