forked from dummied/resque-mongo
-
Notifications
You must be signed in to change notification settings - Fork 7
/
airbrake.rb
133 lines (117 loc) · 3.69 KB
/
airbrake.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
require 'net/https'
require 'builder'
require 'uri'
module Resque
module Failure
# A Failure backend that sends exceptions raised by jobs to Airbrake.
#
# To use it, put this code in an initializer, Rake task, or wherever:
#
# require 'resque/failure/airbrake'
#
# Resque::Failure::Airbrake.configure do |config|
# config.api_key = 'blah'
# config.secure = true
#
# # optional proxy support
# config.proxy_host = 'x.y.z.t'
# config.proxy_port = 8080
#
# # server env support, defaults to RAILS_ENV or RACK_ENV
# config.server_environment = "test"
# end
class Airbrake < Base
# From the airbrake plugin
INPUT_FORMAT = /^([^:]+):(\d+)(?::in `([^']+)')?$/
class << self
attr_accessor :secure, :api_key, :proxy_host, :proxy_port
attr_accessor :server_environment
end
def self.count
# We can't get the total # of errors from Airbrake so we fake it
# by asking Resque how many errors it has seen.
Stat[:failed]
end
def self.configure
yield self
Resque::Failure.backend = self
end
def save
http = use_ssl? ? :https : :http
url = URI.parse("#{http}://airbrakeapp.com/notifier_api/v2/notices")
request = Net::HTTP::Proxy(self.class.proxy_host, self.class.proxy_port)
http = request.new(url.host, url.port)
headers = {
'Content-type' => 'text/xml',
'Accept' => 'text/xml, application/xml'
}
http.read_timeout = 5 # seconds
http.open_timeout = 2 # seconds
http.use_ssl = use_ssl?
begin
response = http.post(url.path, xml, headers)
rescue TimeoutError => e
log "Timeout while contacting the Airbrake server."
end
case response
when Net::HTTPSuccess then
log "Airbrake Success: #{response.class}"
else
body = response.body if response.respond_to? :body
log "Airbrake Failure: #{response.class}\n#{body}"
end
end
def xml
x = Builder::XmlMarkup.new
x.instruct!
x.notice :version=>"2.0" do
x.tag! "api-key", api_key
x.notifier do
x.name "Resque"
x.version "0.1"
x.url "http://github.com/defunkt/resque"
end
x.error do
x.tag! "class", exception.class.name
x.message "#{exception.class.name}: #{exception.message}"
x.backtrace do
fill_in_backtrace_lines(x)
end
end
x.request do
x.url queue.to_s
x.component worker.to_s
x.params do
x.var :key=>"payload_class" do
x.text! payload["class"].to_s
end
x.var :key=>"payload_args" do
x.text! payload["args"].to_s
end
end
end
x.tag!("server-environment") do
x.tag!("project-root", "RAILS_ROOT")
x.tag!("environment-name",server_environment)
end
end
end
def fill_in_backtrace_lines(x)
Array(exception.backtrace).each do |unparsed_line|
_, file, number, method = unparsed_line.match(INPUT_FORMAT).to_a
x.line :file => file,:number => number
end
end
def use_ssl?
self.class.secure
end
def api_key
self.class.api_key
end
def server_environment
return self.class.server_environment if self.class.server_environment
defined?(Rails) ? Rails.env : ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'production'
end
end
end
end