Module: Hubble
- Extended by:
- Hubble
- Included in:
- Hubble
- Defined in:
- lib/hubble.rb,
lib/hubble/version.rb,
lib/hubble/middleware.rb
Defined Under Namespace
Modules: Backend, Client Classes: Rescuer
Constant Summary collapse
- VERSION =
"0.1.0"
Instance Attribute Summary collapse
-
#backend ⇒ Object
Load and initialize the exception reporting backend as specified by the ‘backend’ configuration option.
-
#raise_errors ⇒ Object
writeonly
Sets the attribute raise_errors.
Instance Method Summary collapse
- #backend! ⇒ Object
-
#backend_name ⇒ Object
The name of the backend that should be used to post exceptions to the exceptions-collection service.
-
#boomtown! ⇒ Object
Public: Trigger an Exception.
-
#cast(data) ⇒ Object
Send the exception data to the relay service using a non-waiting cast call.
-
#config ⇒ Object
Hash of configuration data from lib/hubble/config.yml.
-
#config_file ⇒ Object
Location of config.yml config file.
-
#context ⇒ Object
Stack of context information to include in the next Hubble report.
- #default_options ⇒ Object
- #default_options=(hash) ⇒ Object
-
#environment ⇒ Object
The current “environment”.
-
#exception_info(e) ⇒ Object
Extract exception info into a simple Hash.
- #fail ⇒ Object
-
#haystack ⇒ Object
The URL where exceptions should be posted.
- #hostname ⇒ Object
-
#install_unhandled_exception_hook! ⇒ Object
Installs an at_exit hook to report exceptions that raise all the way out of the stack and halt the interpreter.
- #logger ⇒ Object
- #logger=(logger) ⇒ Object
-
#pop ⇒ Object
Remove the last info hash from the context stack.
-
#push(info = {}) ⇒ Object
Add info to be sent in the next Hubble report, should one occur.
-
#raise_errors? ⇒ Boolean
Determines whether exceptions are raised instead of being reported to the exception tracking service.
-
#report(e, other = {}) ⇒ Object
Public: Sends an exception to the exception tracking service along with a hash of custom attributes to be included with the report.
- #report!(e, other = {}) ⇒ Object
-
#reports ⇒ Object
Public: exceptions that were reported.
-
#reset! ⇒ Object
Reset the context stack to a pristine state.
-
#service ⇒ Object
(also: #svc)
Deprecated.
-
#setup(_config = {}) ⇒ Object
Reset the backend and optionally override the environment configuration.
-
#squash_context(*other) ⇒ Object
Combines all context hashes into a single hash converting non-standard data types in values to strings, then combines the result with a custom info hash provided in the other argument.
Instance Attribute Details
#backend ⇒ Object
Load and initialize the exception reporting backend as specified by the ‘backend’ configuration option.
Raises ArgumentError for invalid backends.
223 224 225 |
# File 'lib/hubble.rb', line 223 def backend @backend ||= backend! end |
#raise_errors=(value) ⇒ Object (writeonly)
Sets the attribute raise_errors
70 71 72 |
# File 'lib/hubble.rb', line 70 def raise_errors=(value) @raise_errors = value end |
Instance Method Details
#backend! ⇒ Object
228 229 230 231 232 233 234 235 236 237 |
# File 'lib/hubble.rb', line 228 def backend! case backend_name when 'memory' Hubble::Backend::Memory.new when 'haystack' Hubble::Backend::Haystack.new(haystack) else raise ArgumentError, "Unknown backend: #{backend_name.inspect}" end end |
#backend_name ⇒ Object
The name of the backend that should be used to post exceptions to the exceptions-collection service. The fellowing backends are available:
memory - Dummy backend that simply save exceptions in memory. Typically
used in testing environments.
heroku - In-process posting for outside of vpn apps
Returns the String backend name. See also ‘Hubble.backend`.
53 54 55 |
# File 'lib/hubble.rb', line 53 def backend_name config['backend'] end |
#boomtown! ⇒ Object
Public: Trigger an Exception
Returns nothing.
281 282 283 284 |
# File 'lib/hubble.rb', line 281 def boomtown! e = ArgumentError.new("BOOMTOWN") report(e) end |
#cast(data) ⇒ Object
Send the exception data to the relay service using a non-waiting cast call.
data - Hash of string key => string value pairs.
Returns nothing.
215 216 217 |
# File 'lib/hubble.rb', line 215 def cast(data) backend.report(data) end |
#config ⇒ Object
Hash of configuration data from lib/hubble/config.yml.
29 30 31 |
# File 'lib/hubble.rb', line 29 def config @config ||= YAML.load_file(config_file)[environment] end |
#config_file ⇒ Object
Location of config.yml config file.
34 35 36 |
# File 'lib/hubble.rb', line 34 def config_file File.('../hubble/config.yml', __FILE__) end |
#context ⇒ Object
Stack of context information to include in the next Hubble report. These hashes are condensed down into one and included in the next report. Don’t mess with this structure directly - use the #push and #pop methods.
81 82 83 |
# File 'lib/hubble.rb', line 81 def context @context ||= [{'server' => hostname, 'type' => 'exception'}] end |
#default_options ⇒ Object
302 303 304 |
# File 'lib/hubble.rb', line 302 def context[0] end |
#default_options=(hash) ⇒ Object
306 307 308 |
# File 'lib/hubble.rb', line 306 def (hash) context[0] = hash end |
#environment ⇒ Object
The current “environment”. This dictates which section will be read from the config.yml config file.
40 41 42 |
# File 'lib/hubble.rb', line 40 def environment @environment ||= ENV['HUBBLE_ENV'] || ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development' end |
#exception_info(e) ⇒ Object
Extract exception info into a simple Hash.
e - The exception object to turn into a Hash.
Returns a Hash including a ‘class’, ‘message’, ‘backtrace’, and ‘rollup’
keys. The rollup value is a MD5 hash of the exception class, file, and line
number and is used to group exceptions.
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/hubble.rb', line 187 def exception_info(e) backtrace = Array(e.backtrace)[0, 500] res = { 'class' => e.class.to_s, 'message' => e., 'backtrace' => backtrace.join("\n"), 'rollup' => Digest::MD5.hexdigest("#{e.class}#{backtrace[0]}") } if original = (e.respond_to?(:original_exception) && e.original_exception) remote_backtrace = [] remote_backtrace << original. if original.backtrace remote_backtrace.concat(Array(original.backtrace)[0,500]) end res['remote_backtrace'] = remote_backtrace.join("\n") end res end |
#fail ⇒ Object
298 299 300 |
# File 'lib/hubble.rb', line 298 def fail raise "failure failure!" end |
#haystack ⇒ Object
The URL where exceptions should be posted. Each exception is converted into JSON and posted to this URL.
74 75 76 |
# File 'lib/hubble.rb', line 74 def haystack ENV['HUBBLE_ENDPOINT'] || config['haystack'] end |
#hostname ⇒ Object
274 275 276 |
# File 'lib/hubble.rb', line 274 def hostname @hostname ||= Socket.gethostname end |
#install_unhandled_exception_hook! ⇒ Object
Installs an at_exit hook to report exceptions that raise all the way out of the stack and halt the interpreter. This is useful for catching boot time errors as well and even signal kills.
To use, call this method very early during the program’s boot to cover as much code as possible:
require 'hubble'
Hubble.install_unhandled_exception_hook!
Returns true when the hook was installed, nil when the hook had previously been installed by another component.
251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
# File 'lib/hubble.rb', line 251 def install_unhandled_exception_hook! # only install the hook once, even when called from multiple locations return if @unhandled_exception_hook_installed # the $! is set when the interpreter is exiting due to an exception at_exit do boom = $! if boom && !raise_errors? && !boom.is_a?(SystemExit) report(boom, 'argv' => ([$0]+ARGV).join(" "), 'halting' => true) end end @unhandled_exception_hook_installed = true end |
#logger ⇒ Object
266 267 268 |
# File 'lib/hubble.rb', line 266 def logger @logger ||= Logger.new($stderr) end |
#logger=(logger) ⇒ Object
270 271 272 |
# File 'lib/hubble.rb', line 270 def logger=(logger) @logger = logger end |
#pop ⇒ Object
Remove the last info hash from the context stack.
100 101 102 |
# File 'lib/hubble.rb', line 100 def pop context.pop if context.size > 1 end |
#push(info = {}) ⇒ Object
Add info to be sent in the next Hubble report, should one occur.
info - Hash of name => value pairs to include in the exception report. block - When given, the info is removed from the current context after the
block is executed.
Returns the value returned by the block when given; otherwise, returns nil.
92 93 94 95 96 97 |
# File 'lib/hubble.rb', line 92 def push(info={}) context.push(info) yield if block_given? ensure pop if block_given? end |
#raise_errors? ⇒ Boolean
Determines whether exceptions are raised instead of being reported to the exception tracking service. This is typically enabled in development and test environments. When set true, no exception information is reported and the exception is raised instead. When false (default in production environments), the exception is reported to the exception tracking service but not raised.
63 64 65 66 67 68 69 |
# File 'lib/hubble.rb', line 63 def raise_errors? if @raise_errors.nil? config['raise_errors'] else @raise_errors end end |
#report(e, other = {}) ⇒ Object
Public: Sends an exception to the exception tracking service along with a hash of custom attributes to be included with the report. When the raise_errors option is set, this method raises the exception instead of reporting to the exception tracking service.
e - The Exception object. Must respond to #message and #backtrace. other - Hash of additional attributes to include with the report.
Examples
begin
my_code
rescue => e
Hubble.report(e, :user => current_user)
end
Returns nothing.
126 127 128 129 130 131 132 133 |
# File 'lib/hubble.rb', line 126 def report(e, other = {}) if raise_errors? squash_context(exception_info(e), other) # surface problems squashing raise e else report!(e, other) end end |
#report!(e, other = {}) ⇒ Object
135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/hubble.rb', line 135 def report!(e, other = {}) data = squash_context(exception_info(e), other) cast(data) rescue Object => i # don't fail for any reason logger.debug "Hubble: #{data.inspect}" rescue nil logger.debug e. rescue nil logger.debug e.backtrace.join("\n") rescue nil logger.debug i. rescue nil logger.debug i.backtrace.join("\n") rescue nil end |
#reports ⇒ Object
Public: exceptions that were reported. Only available when using the memory and file backends.
Returns an Array of exceptions data Hash.
151 152 153 |
# File 'lib/hubble.rb', line 151 def reports backend.reports end |
#reset! ⇒ Object
Reset the context stack to a pristine state.
105 106 107 |
# File 'lib/hubble.rb', line 105 def reset! @context = [context[0]] end |
#service ⇒ Object Also known as: svc
Deprecated
291 292 293 294 |
# File 'lib/hubble.rb', line 291 def service warn "Hubble.service is deprecated. #{caller[0]}" @service ||= BERTRPC::Service.new(config['host'], config['port']) end |
#setup(_config = {}) ⇒ Object
Reset the backend and optionally override the environment configuration.
config - The optional configuration Hash.
Returns nothing.
22 23 24 25 26 |
# File 'lib/hubble.rb', line 22 def setup(_config={}) config.merge!(_config) @backend = nil @raise_errors = nil end |
#squash_context(*other) ⇒ Object
Combines all context hashes into a single hash converting non-standard data types in values to strings, then combines the result with a custom info hash provided in the other argument.
other - Optional array of hashes to also squash in on top of the context
stack hashes.
Returns a Hash with all keys and values.
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/hubble.rb', line 163 def squash_context(*other) merged = {} (context + other).each do |hash| hash.each do |key, value| value = (value.call rescue nil) if value.kind_of?(Proc) merged[key.to_s] = case value when String, Numeric, true, false value.to_s else value.inspect end end end merged end |