forked from toolmantim/toadhopper
-
Notifications
You must be signed in to change notification settings - Fork 1
/
toadhopper.rb
78 lines (77 loc) · 2.33 KB
/
toadhopper.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
require 'net/http'
require 'yaml'
module Toadhopper
class << self
# Set the API key
def api_key=(key)
@api_key = key
end
# Returns the key set by Toadhopper.api_key=
def api_key
@api_key
end
# Sets patterns to [FILTER] out sensitive data such as passwords, emails and credit card numbers.
#
# Toadhopper.filters = /password/, /email/, /credit_card_number/
def filters=(*filters)
@filters = filters.flatten
end
# Returns the filters set by Toadhopper.filters=
def filters
[@filters].flatten.compact
end
# Replaces the values of the keys matching Toadhopper.filters with [FILTERED]. Typically used on the params and environment hashes.
def filter(hash)
hash.inject({}) do |acc, (key, val)|
acc[key] = filters.any? {|f| key.to_s =~ Regexp.new(f)} ? "[FILTERED]" : val
acc
end
end
# Posts an error to Hoptoad
def post!(error, options={}, header_options={})
uri = URI.parse("http://hoptoadapp.com/notices/")
Net::HTTP.start(uri.host, uri.port) do |http|
headers = {
'Content-type' => 'application/x-yaml',
'Accept' => 'text/xml, application/xml',
'X-Hoptoad-Client-Name' => 'Toadhopper',
}.merge(header_options)
http.read_timeout = 5 # seconds
http.open_timeout = 2 # seconds
begin
http.post uri.path, {"notice" => notice_params(error, options)}.to_yaml, headers
rescue TimeoutError => e
end
end
end
def notice_params(error, options={}) # :nodoc:
clean_non_serializable_data(stringify_keys(
{
:api_key => api_key,
:error_class => error.class.name,
:error_message => error.message,
:backtrace => error.backtrace,
}.merge(options)
))
end
def stringify_keys(hash) #:nodoc:
hash.inject({}) do |h, pair|
h[pair.first.to_s] = pair.last.is_a?(Hash) ? stringify_keys(pair.last) : pair.last
h
end
end
def serializable?(value) #:nodoc:
value.is_a?(Fixnum) ||
value.is_a?(Array) ||
value.is_a?(String) ||
value.is_a?(Hash) ||
value.is_a?(Bignum)
end
def clean_non_serializable_data(data) #:nodoc:
data.select{|k,v| serializable?(v) }.inject({}) do |h, pair|
h[pair.first] = pair.last.is_a?(Hash) ? clean_non_serializable_data(pair.last) : pair.last
h
end
end
end
end