Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rails <3 #1

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ tmtags
.\#*

## VIM
*.swo
*.swp

## PROJECT::GENERAL
Expand Down
58 changes: 55 additions & 3 deletions lib/bullhorn.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ class Bullhorn

def initialize(app, options = {})
@app = app
@api_key = options[:api_key] || raise(ArgumentError, ":api_key is required")
@filters = Array(options[:filters])
@api_key = options[:api_key] || @@api_key || raise(ArgumentError, ":api_key is required")
@filters = Array(options[:filters] || @@filters)
@url = options[:url] || URL
@ignore_exceptions = Array(options[:ignore_exceptions] || default_ignore_exceptions)
@show_code_context = (options[:show_code_context].nil? ? true : options[:show_code_context])
@show_code_context = (options[:show_code_context].nil? ? (@@show_code_context || true) : options[:show_code_context])
end

def call(env)
Expand All @@ -50,6 +50,58 @@ def call(env)
[status, headers, body]
end

class << self

def api_key=(key)
@@api_key = key
end

def api_key
@@api_key
end

def filters=(val)
@@filters = val
end

def filters
@@filters
end

def show_code_context=(val)
@@show_code_context
end

def show_code_context
@@show_code_context
end


def notify_exception(exception)

bt = Bullhorn::Backtrace.new(exception, :context => @show_code_context)

post_options = {
:api_key => api_key,
:message => exception.message[0..100],
:backtrace => Bullhorn::Sender.serialize(bt.to_a),
:env => Bullhorn::Sender.serialize({}),
:request_body => Bullhorn::Sender.serialize(""),
:sha1 => Bullhorn::Sender.sha1(exception),
# APIv2
:language => Bullhorn::LANGUAGE,
:client_name => Bullhorn::CLIENT_NAME,
:client_version => Bullhorn::VERSION,
:url => "",
:class => exception.class.to_s
}

Net::HTTP.post_form(URI(Bullhorn::URL), post_options)

end
end


protected
def default_ignore_exceptions
[].tap do |exceptions|
Expand Down
16 changes: 9 additions & 7 deletions lib/bullhorn/backtrace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ class Bullhorn
class Backtrace
def initialize(exception, options = {})
@exception = exception
@raw = exception.backtrace # Array
@raw = exception.backtrace || [] # Array
@options = { :context => true }

@options.merge!(options)
Expand All @@ -29,12 +29,14 @@ def get_context(fname, line, size = 2)

def to_a
@raw.inject([]) do |arr, line|
m = line.match(/^(?<file>.+):(?<line>[0-9]+):in `(?<function>.*)'$/)
arr << { :function => m[:function],
:file => m[:file],
:line => m[:line],
:context => (@options[:context] ? get_context(m[:file], m[:line]) : nil)
}
m = line.match(/^(.+):([0-9]+):in `(.*)'$/)

arr << { :function => m[3],
:file => m[1],
:line => m[2],
:context => (@options[:context] ? get_context(m[2], m[2]) : nil)
} if m

arr
end
end
Expand Down
7 changes: 4 additions & 3 deletions lib/bullhorn/sender.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def serialize(str)
end

def notify(exception, env = {})
bt = Backtrace.new(exception, :context => @show_code_context)
bt = Bullhorn::Backtrace.new(exception, :context => @show_code_context)

Net::HTTP.post_form(URI(url), {
:api_key => api_key,
Expand All @@ -25,15 +25,16 @@ def notify(exception, env = {})
})
end

protected
def sha1(exception)
# Treat 2 exceptions as the same if they match the same exception class
# and same origin.
salt = '#bh#' + Bullhorn::CLIENT_NAME
str = [ salt, exception.class.to_s, exception.backtrace.first ].join('|')
str = [ salt, exception.class.to_s, (exception.backtrace ? exception.backtrace.first : nil) ].join('|')
Digest::SHA1.hexdigest(str)
end

protected

def request_body(env)
if io = env['rack.input']
io.rewind if io.respond_to?(:rewind)
Expand Down
8 changes: 7 additions & 1 deletion test/test_bullhorn.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ class TestBullhorn < Test::Unit::TestCase
end
end

test "accept the api key from class level" do
Bullhorn.api_key = "key"
Bullhorn.new(@app)
assert_equal Bullhorn.api_key, "key"
end

test "accepts a filter of string arrays" do
bullhorn = Bullhorn.new(@app, :api_key => "key", :filters => ['a', 'b'])
assert_equal ['a', 'b'], bullhorn.filters
Expand Down Expand Up @@ -182,4 +188,4 @@ module ::ActionController
assert bh.ignore_exceptions.include?(ActionController::RoutingError)
end
end
end
end