diff --git a/.gitignore b/.gitignore index f979985..bab9d46 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ tmtags .\#* ## VIM +*.swo *.swp ## PROJECT::GENERAL diff --git a/lib/bullhorn.rb b/lib/bullhorn.rb index 04d0478..56f5603 100644 --- a/lib/bullhorn.rb +++ b/lib/bullhorn.rb @@ -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) @@ -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| diff --git a/lib/bullhorn/backtrace.rb b/lib/bullhorn/backtrace.rb index 850b0c9..4e5134c 100644 --- a/lib/bullhorn/backtrace.rb +++ b/lib/bullhorn/backtrace.rb @@ -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) @@ -29,12 +29,14 @@ def get_context(fname, line, size = 2) def to_a @raw.inject([]) do |arr, line| - m = line.match(/^(?.+):(?[0-9]+):in `(?.*)'$/) - 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 diff --git a/lib/bullhorn/sender.rb b/lib/bullhorn/sender.rb index f17d01d..8cca471 100644 --- a/lib/bullhorn/sender.rb +++ b/lib/bullhorn/sender.rb @@ -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, @@ -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) diff --git a/test/test_bullhorn.rb b/test/test_bullhorn.rb index ef59962..2d9a02a 100644 --- a/test/test_bullhorn.rb +++ b/test/test_bullhorn.rb @@ -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 @@ -182,4 +188,4 @@ module ::ActionController assert bh.ignore_exceptions.include?(ActionController::RoutingError) end end -end \ No newline at end of file +end