bullhorn 0.0.6 → 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.
@@ -2,72 +2,10 @@
2
2
 
3
3
  The Rack middleware drop-in for the bullhorn exception notification application.
4
4
 
5
- See http://bullhorn.it and signup for a free account!
5
+ See http://www.bullhorn.it and signup for a free account!
6
6
 
7
- == Sinatra Example
8
-
9
- require 'rubygems'
10
- require 'sinatra'
11
-
12
- # this must be enabled for errors to propagate
13
- set :raise_errors, true
14
-
15
- # of course the best way to do that is:
16
- set :raise_errors, production?
17
-
18
- # Let's say we have an error we don't want to be notified about
19
- MyOwnError = Class.new(StandardError)
20
-
21
- use Bullhorn, :api_key => "__your key here__",
22
- :filters => %w(password password_confirmation),
23
- :ignore_exceptions => [MyOwnError]
24
-
25
- get "/hello" do
26
- "Hello world"
27
- end
28
-
29
- get "/fail" do
30
- raise "Failure from the app"
31
- end
32
-
33
-
34
- == Rails 3 Example
35
-
36
- Whatever::Application.config.middleware.use Bullhorn,
37
- :api_key => "_your api key here_",
38
- :filters => %w(password password_confirmation credit_card)
39
-
40
- # by default, ActiveRecord::RecordNotFound,
41
- # AbstractController::ActionNotFound and ActionController::RoutingError
42
- # are ignored in a Rails 3 context.
43
-
44
- == Rails 2.3.5 backward compatibility
45
-
46
- # in config/environment.rb
47
-
48
- config.gem 'bullhorn'
49
-
50
- # in config/initializers/bullhorn.rb
51
- Bullhorn::Plugin.options = {
52
- :api_key => "_api key here_",
53
- :filters => %w(password password_confirmation credit_card)
54
- }
55
-
56
- # in your application controller
57
- class ApplicationController < ActionController::Base
58
- include Bullhorn::Plugin
59
- end
60
-
61
- == Note on Patches/Pull Requests
62
-
63
- * Fork the project.
64
- * Make your feature addition or bug fix.
65
- * Add tests for it. This is important so I don't break it in a
66
- future version unintentionally.
67
- * Commit, do not mess with rakefile, version, or history.
68
- (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
69
- * Send me a pull request. Bonus points for topic branches.
7
+ Installing instructions: http://www.bullhorn.it/page/installation
70
8
 
71
9
  == Copyright
72
10
 
73
- Copyright (c) 2010 Cyril David. See LICENSE for details.
11
+ Copyright (c) 2010 Cyril David, Rico Sta. Cruz and Sinefunc, Inc. Released under the MIT license.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.6
1
+ 0.1.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{bullhorn}
8
- s.version = "0.0.6"
8
+ s.version = "0.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Cyril David"]
12
- s.date = %q{2010-08-16}
12
+ s.date = %q{2010-10-18}
13
13
  s.description = %q{drop in rack middleware for bullhorn.it}
14
14
  s.email = %q{cyx.ucron@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -78,6 +78,7 @@ Gem::Specification.new do |s|
78
78
  "examples/foobar/test/unit/helpers/raiser_helper_test.rb",
79
79
  "examples/sinatra.rb",
80
80
  "lib/bullhorn.rb",
81
+ "lib/bullhorn/backtrace.rb",
81
82
  "lib/bullhorn/plugin.rb",
82
83
  "lib/bullhorn/sender.rb",
83
84
  "test/helper.rb",
@@ -88,7 +89,7 @@ Gem::Specification.new do |s|
88
89
  s.homepage = %q{http://github.com/sinefunc/bullhorn}
89
90
  s.rdoc_options = ["--charset=UTF-8"]
90
91
  s.require_paths = ["lib"]
91
- s.rubygems_version = %q{1.3.6}
92
+ s.rubygems_version = %q{1.3.7}
92
93
  s.summary = %q{rack middleware client for bullhorn.it}
93
94
  s.test_files = [
94
95
  "test/helper.rb",
@@ -123,7 +124,7 @@ Gem::Specification.new do |s|
123
124
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
124
125
  s.specification_version = 3
125
126
 
126
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
127
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
127
128
  s.add_development_dependency(%q<contest>, [">= 0"])
128
129
  s.add_development_dependency(%q<mocha>, [">= 0"])
129
130
  s.add_development_dependency(%q<rack-test>, [">= 0"])
@@ -8,7 +8,10 @@ require 'digest/sha1'
8
8
  class Bullhorn
9
9
  autoload :Plugin, "bullhorn/plugin"
10
10
  autoload :Sender, "bullhorn/sender"
11
+ autoload :Backtrace, "bullhorn/backtrace"
11
12
 
13
+ LANGUAGE = "ruby"
14
+ CLIENT_NAME = "bullhorn-ruby"
12
15
  VERSION = "0.0.5"
13
16
 
14
17
  URL = "http://www.bullhorn.it/api/v1/exception"
@@ -19,6 +22,7 @@ class Bullhorn
19
22
  attr :api_key
20
23
  attr :url
21
24
  attr :ignore_exceptions
25
+ attr :show_code_context
22
26
 
23
27
  include Sender
24
28
 
@@ -28,6 +32,7 @@ class Bullhorn
28
32
  @filters = Array(options[:filters])
29
33
  @url = options[:url] || URL
30
34
  @ignore_exceptions = Array(options[:ignore_exceptions] || default_ignore_exceptions)
35
+ @show_code_context = (options[:show_code_context].nil? ? true : options[:show_code_context])
31
36
  end
32
37
 
33
38
  def call(env)
@@ -0,0 +1,47 @@
1
+ class Bullhorn
2
+ class Backtrace
3
+ def initialize(exception, options = {})
4
+ @exception = exception
5
+ @raw = exception.backtrace # Array
6
+ @options = { :context => true }
7
+
8
+ @options.merge!(options)
9
+
10
+ # Sample:
11
+ # [ "(irb):3:in `irb_binding'",
12
+ # "/Users/rsc/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/irb/workspace.rb:80:in `eval'",
13
+ # "/Users/rsc/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/irb.rb:159:in `block (2 levels) in eval_input'",
14
+ end
15
+
16
+ # Returns nil or an array.
17
+ def get_context(fname, line, size = 2)
18
+ begin
19
+ line = line.to_i
20
+ from = [0, (line-size-1)].max
21
+ lines = File.open(fname, 'r') { |file| file.lines.to_a[from...(line+size)] }
22
+
23
+ i = [line - size, 0].max
24
+ lines.map { |hash| i += 1; { (i-1) => hash } }
25
+ rescue
26
+ nil
27
+ end
28
+ end
29
+
30
+ def to_a
31
+ @raw.inject([]) do |arr, line|
32
+ m = line.match(/^(?<file>[^:]+):(?<line>[0-9]+):in `(?<function>.*)'$/)
33
+
34
+ arr << { :function => m[:function],
35
+ :file => m[:file],
36
+ :line => m[:line],
37
+ :context => (@options[:context] ? get_context(m[:file], m[:line]) : nil)
38
+ }
39
+ arr
40
+ end
41
+ end
42
+
43
+ def to_json
44
+ to_a.send(:to_json)
45
+ end
46
+ end
47
+ end
@@ -7,17 +7,33 @@ class Bullhorn
7
7
  end
8
8
 
9
9
  def notify(exception, env)
10
+ bt = Backtrace.new(exception, :context => @show_code_context)
11
+
10
12
  Net::HTTP.post_form(URI(url), {
11
13
  :api_key => api_key,
12
14
  :message => exception.message,
13
- :backtrace => serialize(exception.backtrace),
15
+ :backtrace => serialize(bt.to_a),
14
16
  :env => serialize(whitelist(env)),
15
17
  :request_body => serialize(whitelist(request_body(env))),
16
- :sha1 => sha1(exception)
18
+ :sha1 => sha1(exception),
19
+ # APIv2
20
+ :language => Bullhorn::LANGUAGE,
21
+ :client_name => Bullhorn::CLIENT_NAME,
22
+ :client_version => Bullhorn::VERSION,
23
+ :url => [ "http://", env['HTTP_HOST'], env['REQUEST_URI'] ].join(''),
24
+ :class => exception.class.to_s
17
25
  })
18
26
  end
19
27
 
20
28
  protected
29
+ def sha1(exception)
30
+ # Treat 2 exceptions as the same if they match the same exception class
31
+ # and same origin.
32
+ salt = '#bh#' + Bullhorn::CLIENT_NAME
33
+ str = [ salt, exception.class.to_s, exception.backtrace.first ].join('|')
34
+ Digest::SHA1.hexdigest(str)
35
+ end
36
+
21
37
  def request_body(env)
22
38
  if io = env['rack.input']
23
39
  io.rewind if io.respond_to?(:rewind)
@@ -55,9 +71,5 @@ class Bullhorn
55
71
  end
56
72
  end
57
73
  end
58
-
59
- def sha1(exception)
60
- Digest::SHA1.hexdigest(exception.message + exception.backtrace.inspect)
61
- end
62
74
  end
63
75
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
+ - 1
7
8
  - 0
8
- - 6
9
- version: 0.0.6
9
+ version: 0.1.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Cyril David
@@ -14,13 +14,14 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-08-16 00:00:00 +08:00
17
+ date: 2010-10-18 00:00:00 +08:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: contest
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
24
25
  requirements:
25
26
  - - ">="
26
27
  - !ruby/object:Gem::Version
@@ -33,6 +34,7 @@ dependencies:
33
34
  name: mocha
34
35
  prerelease: false
35
36
  requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
36
38
  requirements:
37
39
  - - ">="
38
40
  - !ruby/object:Gem::Version
@@ -45,6 +47,7 @@ dependencies:
45
47
  name: rack-test
46
48
  prerelease: false
47
49
  requirement: &id003 !ruby/object:Gem::Requirement
50
+ none: false
48
51
  requirements:
49
52
  - - ">="
50
53
  - !ruby/object:Gem::Version
@@ -57,6 +60,7 @@ dependencies:
57
60
  name: fakeweb
58
61
  prerelease: false
59
62
  requirement: &id004 !ruby/object:Gem::Requirement
63
+ none: false
60
64
  requirements:
61
65
  - - ">="
62
66
  - !ruby/object:Gem::Version
@@ -136,6 +140,7 @@ files:
136
140
  - examples/foobar/test/unit/helpers/raiser_helper_test.rb
137
141
  - examples/sinatra.rb
138
142
  - lib/bullhorn.rb
143
+ - lib/bullhorn/backtrace.rb
139
144
  - lib/bullhorn/plugin.rb
140
145
  - lib/bullhorn/sender.rb
141
146
  - test/helper.rb
@@ -152,6 +157,7 @@ rdoc_options:
152
157
  require_paths:
153
158
  - lib
154
159
  required_ruby_version: !ruby/object:Gem::Requirement
160
+ none: false
155
161
  requirements:
156
162
  - - ">="
157
163
  - !ruby/object:Gem::Version
@@ -159,6 +165,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
159
165
  - 0
160
166
  version: "0"
161
167
  required_rubygems_version: !ruby/object:Gem::Requirement
168
+ none: false
162
169
  requirements:
163
170
  - - ">="
164
171
  - !ruby/object:Gem::Version
@@ -168,7 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
168
175
  requirements: []
169
176
 
170
177
  rubyforge_project:
171
- rubygems_version: 1.3.6
178
+ rubygems_version: 1.3.7
172
179
  signing_key:
173
180
  specification_version: 3
174
181
  summary: rack middleware client for bullhorn.it