Permalink
Browse files

First commit. Manual test.

  • Loading branch information...
0 parents commit ed66dcb4fffbf9808a82ca729facb89766207d04 @ismasan committed Nov 20, 2011
Showing with 167 additions and 0 deletions.
  1. +4 −0 .gitignore
  2. +4 −0 Gemfile
  3. +2 −0 Rakefile
  4. +24 −0 em_airbrake.gemspec
  5. +130 −0 lib/em_airbrake.rb
  6. +3 −0 lib/em_airbrake/version.rb
@@ -0,0 +1,4 @@
+*.gem
+.bundle
+Gemfile.lock
+pkg/*
@@ -0,0 +1,4 @@
+source "http://rubygems.org"
+
+# Specify your gem's dependencies in em_airbrake.gemspec
+gemspec
@@ -0,0 +1,2 @@
+require 'bundler'
+Bundler::GemHelper.install_tasks
@@ -0,0 +1,24 @@
+# -*- encoding: utf-8 -*-
+$:.push File.expand_path("../lib", __FILE__)
+require "em_airbrake/version"
+
+Gem::Specification.new do |s|
+ s.name = "em_airbrake"
+ s.version = EmAirbrake::VERSION
+ s.platform = Gem::Platform::RUBY
+ s.authors = ["Ismael Celis"]
+ s.email = ["ismaelct@gmail.com"]
+ s.homepage = "http://github.com/ismasan/em_airbrake"
+ s.summary = %q{Send error notifications to your Airbrake account from within EventMachine servers (Thin, EM)}
+ s.description = %q{Async Airbrake notifier for EventMachine apps}
+
+ s.add_dependency 'eventmachine', ">= 0.12.10"
+ s.add_dependency 'em-http-request'
+
+ s.rubyforge_project = "em_airbrake"
+
+ s.files = `git ls-files`.split("\n")
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+ s.require_paths = ["lib"]
+end
@@ -0,0 +1,130 @@
+require 'ostruct'
+require 'eventmachine'
+require 'em-http'
+require 'em_airbrake/version'
+require 'builder'
+
+module EmAirbrake
+ ENDPOINT = 'http://airbrake.io/notifier_api/v2/notices'.freeze
+ BACKTRACE_EXP = %r{^([^:]+):(\d+)(?::in `([^']+)')?$}.freeze
+ API_VERSION = '2.0'.freeze
+ GEM_HOME = 'http://github.com/ismasan/em_airbrake'.freeze
+
+ attr_reader :config
+
+ def configure(&block)
+ @config = OpenStruct.new
+ block.call @config
+ check_config!
+ end
+
+ def notify(args = {})
+ error = args.delete(:error)
+ backtrace = error.respond_to?(:backtrace) ? error.backtrace : nil
+ default_url = args.delete(:url) || 'default'
+
+ data = {
+ :error_class => error.class.name,
+ :parameters => {},
+ :api_key => config.api_key,
+ :error_message => "#{error.class.name}:#{error.respond_to?(:message) ? error.message : ''}",
+ :backtrace => backtrace,
+ :parameters => {},
+ :session => {},
+ :url => default_url,
+ :component => default_url
+ }.merge(args)
+
+ post(data)
+ end
+
+ protected
+
+ def check_config!
+ raise ArgumentError, "you need config.api_key" unless config.api_key
+ end
+
+ def post(data)
+ @req = EM::HttpRequest.new(ENDPOINT).post(
+ :head => {'Content-Type' => 'text/xml', 'Accept' => 'text/xml, application/xml', 'User-Agent'=>'Ruby'},
+ :body => xml(data)
+ )
+ @req.callback {
+ p [:req, @req.response_header.status, @req.response]
+ }
+ @req
+ end
+
+ def xml_vars_for(builder, hash)
+ hash.each do |key, value|
+ if value.respond_to?(:to_hash)
+ builder.var(:key => key){|b| xml_vars_for(b, value.to_hash) }
+ else
+ builder.var(value.to_s, :key => key)
+ end
+ end
+ end
+
+ def xml(data)
+ builder = Builder::XmlMarkup.new
+ builder.instruct!
+ xml = builder.notice(:version => API_VERSION) do |notice|
+ # API KEY ===================
+ notice.tag!("api-key", config.api_key)
+ # NOTIFIER ===================
+ notice.notifier do |notifier|
+ notifier.name('EmAirbrake')
+ notifier.version(EmAirbrake::VERSION)
+ notifier.url(GEM_HOME)
+ end
+ notice.error do |error|
+ error.tag!('class', data[:error_class])
+ error.message(data[:error_message])
+
+ # BACKTRACE ===================
+ if data[:backtrace]
+ error.backtrace do |backtrace|
+
+ data[:backtrace].each do |line|
+ _, file, number, method = line.match(BACKTRACE_EXP).to_a
+ backtrace.line(:number => number,
+ :file => file,
+ :method => method)
+ end
+ end
+ end
+
+ end
+
+ # REQUEST ==================
+ notice.request do |request|
+ # Required
+ request.url(data[:url])
+ # Required
+ request.component(data[:component])
+ # PARAMS ===================
+ if data[:parameters]
+ request.params do |params|
+ xml_vars_for(params, data[:parameters])
+ end
+ end
+
+ end
+
+ # SERVER ENV
+ notice.tag!("server-environment") do |env|
+ env.tag!("project-root", ::File.dirname($0))
+ env.tag!("environment-name", environment_name)
+ env.tag!("hostname", `hostname`.chomp)
+ end
+
+ end
+ xml.to_s
+ end
+
+ def environment_name
+ ENV['RACK_ENV'] || ENV['RAILS_ENV'] || ENV['ENVIRONMENT'] || 'development'
+ end
+
+ extend self
+end
@@ -0,0 +1,3 @@
+module EmAirbrake
+ VERSION = "0.0.1"
+end

0 comments on commit ed66dcb

Please sign in to comment.