This repository was archived by the owner on Nov 11, 2017. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 98
/
Copy pathhoptoad_notifier.rb
150 lines (127 loc) · 4.9 KB
/
hoptoad_notifier.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
require 'net/http'
require 'net/https'
require 'rubygems'
require 'active_support'
require 'hoptoad_notifier/configuration'
require 'hoptoad_notifier/notice'
require 'hoptoad_notifier/sender'
require 'hoptoad_notifier/catcher'
require 'hoptoad_notifier/backtrace'
# Plugin for applications to automatically post errors to the Hoptoad of their choice.
module HoptoadNotifier
VERSION = "2.0.18"
API_VERSION = "2.0"
LOG_PREFIX = "** [Hoptoad] "
HEADERS = {
'Content-type' => 'text/xml',
'Accept' => 'text/xml, application/xml'
}
class << self
# The sender object is responsible for delivering formatted data to the Hoptoad server.
# Must respond to #send_to_hoptoad. See HoptoadNotifier::Sender.
attr_accessor :sender
# A Hoptoad configuration object. Must act like a hash and return sensible
# values for all Hoptoad configuration options. See HoptoadNotifier::Configuration.
attr_accessor :configuration
# Tell the log that the Notifier is good to go
def report_ready
write_verbose_log("Notifier #{VERSION} ready to catch errors")
end
# Prints out the environment info to the log for debugging help
def report_environment_info
write_verbose_log("Environment Info: #{environment_info}")
end
# Prints out the response body from Hoptoad for debugging help
def report_response_body(response)
write_verbose_log("Response from Hoptoad: \n#{response}")
end
# Returns the Ruby version, Rails version, and current Rails environment
def environment_info
info = "[Ruby: #{RUBY_VERSION}]"
info << " [Rails: #{::Rails::VERSION::STRING}]" if defined?(Rails)
info << " [Env: #{configuration.environment_name}]"
end
# Writes out the given message to the #logger
def write_verbose_log(message)
logger.info LOG_PREFIX + message if logger
end
# Look for the Rails logger currently defined
def logger
if defined?(Rails.logger)
Rails.logger
elsif defined?(RAILS_DEFAULT_LOGGER)
RAILS_DEFAULT_LOGGER
end
end
# Call this method to modify defaults in your initializers.
#
# @example
# HoptoadNotifier.configure do |config|
# config.api_key = '1234567890abcdef'
# config.secure = false
# end
def configure(silent = false)
self.configuration ||= Configuration.new
yield(configuration)
self.sender = Sender.new(configuration)
report_ready unless silent
end
# Sends an exception manually using this method, even when you are not in a controller.
#
# @param [Exception] exception The exception you want to notify Hoptoad about.
# @param [Hash] opts Data that will be sent to Hoptoad.
#
# @option opts [String] :api_key The API key for this project. The API key is a unique identifier that Hoptoad uses for identification.
# @option opts [String] :error_message The error returned by the exception (or the message you want to log).
# @option opts [String] :backtrace A backtrace, usually obtained with +caller+.
# @option opts [String] :request The controller's request object.
# @option opts [String] :session The contents of the user's session.
# @option opts [String] :environment ENV merged with the contents of the request's environment.
def notify(exception, opts = {})
send_notice(build_notice_for(exception, opts))
end
# Sends the notice unless it is one of the default ignored exceptions
# @see HoptoadNotifier.notify
def notify_or_ignore(exception, opts = {})
notice = build_notice_for(exception, opts)
send_notice(notice) unless notice.ignore?
end
def build_lookup_hash_for(exception, options = {})
notice = build_notice_for(exception, options)
result = {}
result[:action] = notice.action rescue nil
result[:component] = notice.component rescue nil
result[:error_class] = notice.error_class if notice.error_class
result[:environment_name] = 'production'
unless notice.backtrace.lines.empty?
result[:file] = notice.backtrace.lines.first.file
result[:line_number] = notice.backtrace.lines.first.number
end
result
end
private
def send_notice(notice)
if configuration.public?
sender.send_to_hoptoad(notice.to_xml)
end
end
def build_notice_for(exception, opts = {})
exception = unwrap_exception(exception)
if exception.respond_to?(:to_hash)
opts = opts.merge(exception)
else
opts = opts.merge(:exception => exception)
end
Notice.new(configuration.merge(opts))
end
def unwrap_exception(exception)
if exception.respond_to?(:original_exception)
exception.original_exception
elsif exception.respond_to?(:continued_exception)
exception.continued_exception
else
exception
end
end
end
end