honeybadger 2.7.2 → 3.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +58 -3
- data/README.md +8 -15
- data/lib/honeybadger.rb +9 -232
- data/lib/honeybadger/agent.rb +292 -134
- data/lib/honeybadger/backend.rb +6 -6
- data/lib/honeybadger/backend/base.rb +11 -0
- data/lib/honeybadger/backend/server.rb +2 -14
- data/lib/honeybadger/cli.rb +0 -2
- data/lib/honeybadger/cli/deploy.rb +42 -0
- data/lib/honeybadger/cli/exec.rb +138 -0
- data/lib/honeybadger/cli/heroku.rb +1 -22
- data/lib/honeybadger/cli/install.rb +74 -0
- data/lib/honeybadger/cli/main.rb +138 -153
- data/lib/honeybadger/cli/notify.rb +66 -0
- data/lib/honeybadger/cli/test.rb +266 -0
- data/lib/honeybadger/config.rb +178 -162
- data/lib/honeybadger/config/defaults.rb +5 -5
- data/lib/honeybadger/config/env.rb +8 -6
- data/lib/honeybadger/config/ruby.rb +100 -0
- data/lib/honeybadger/config/yaml.rb +18 -19
- data/lib/honeybadger/const.rb +3 -16
- data/lib/honeybadger/context_manager.rb +50 -0
- data/lib/honeybadger/init/rails.rb +9 -21
- data/lib/honeybadger/init/rake.rb +2 -0
- data/lib/honeybadger/init/ruby.rb +9 -0
- data/lib/honeybadger/init/sinatra.rb +13 -6
- data/lib/honeybadger/notice.rb +29 -14
- data/lib/honeybadger/plugins/delayed_job/plugin.rb +4 -5
- data/lib/honeybadger/plugins/passenger.rb +1 -2
- data/lib/honeybadger/plugins/rails.rb +0 -28
- data/lib/honeybadger/plugins/resque.rb +2 -5
- data/lib/honeybadger/plugins/shoryuken.rb +2 -2
- data/lib/honeybadger/plugins/sidekiq.rb +2 -2
- data/lib/honeybadger/plugins/sucker_punch.rb +1 -0
- data/lib/honeybadger/plugins/thor.rb +2 -2
- data/lib/honeybadger/plugins/warden.rb +1 -0
- data/lib/honeybadger/rack/error_notifier.rb +11 -9
- data/lib/honeybadger/rack/user_feedback.rb +6 -4
- data/lib/honeybadger/rack/user_informer.rb +6 -4
- data/lib/honeybadger/ruby.rb +2 -0
- data/lib/honeybadger/singleton.rb +26 -0
- data/lib/honeybadger/util/http.rb +12 -0
- data/lib/honeybadger/util/request_hash.rb +71 -0
- data/lib/honeybadger/util/sanitizer.rb +101 -64
- data/lib/honeybadger/version.rb +1 -1
- data/lib/honeybadger/worker.rb +246 -0
- metadata +17 -13
- data/lib/honeybadger/agent/batch.rb +0 -50
- data/lib/honeybadger/agent/null_worker.rb +0 -26
- data/lib/honeybadger/agent/worker.rb +0 -243
- data/lib/honeybadger/cli/helpers.rb +0 -160
- data/lib/honeybadger/config/callbacks.rb +0 -70
- data/lib/honeybadger/plugins/unicorn.rb +0 -27
- data/lib/honeybadger/rack/metrics_reporter.rb +0 -16
- data/lib/honeybadger/rack/request_hash.rb +0 -55
@@ -1,160 +0,0 @@
|
|
1
|
-
require 'logger'
|
2
|
-
|
3
|
-
module Honeybadger
|
4
|
-
module CLI
|
5
|
-
module Helpers
|
6
|
-
def rails?(opts = {})
|
7
|
-
@rails ||= load_rails(opts)
|
8
|
-
end
|
9
|
-
|
10
|
-
def load_rails(opts = {})
|
11
|
-
begin
|
12
|
-
require 'honeybadger/init/rails'
|
13
|
-
if ::Rails::VERSION::MAJOR >= 3
|
14
|
-
say("Detected Rails #{::Rails::VERSION::STRING}") if opts[:verbose]
|
15
|
-
else
|
16
|
-
say("Error: Rails #{::Rails::VERSION::STRING} is unsupported.", :red)
|
17
|
-
exit(1)
|
18
|
-
end
|
19
|
-
rescue LoadError
|
20
|
-
say("Rails was not detected, loading standalone.") if opts[:verbose]
|
21
|
-
return @rails = false
|
22
|
-
rescue StandardError => e
|
23
|
-
say("Error while detecting Rails: #{e.class} -- #{e.message}", :red)
|
24
|
-
exit(1)
|
25
|
-
end
|
26
|
-
|
27
|
-
begin
|
28
|
-
require File.expand_path('config/application')
|
29
|
-
rescue LoadError
|
30
|
-
say('Error: could not load Rails application. Please ensure you run this command from your project root.', :red)
|
31
|
-
exit(1)
|
32
|
-
end
|
33
|
-
|
34
|
-
@rails = true
|
35
|
-
end
|
36
|
-
|
37
|
-
def load_rails_env(opts = {})
|
38
|
-
return false unless rails?(opts)
|
39
|
-
|
40
|
-
puts('Loading Rails environment') if opts[:verbose]
|
41
|
-
::Rails.application.require_environment!
|
42
|
-
|
43
|
-
true
|
44
|
-
end
|
45
|
-
|
46
|
-
def rails_framework_opts
|
47
|
-
return {} unless defined?(::Rails)
|
48
|
-
|
49
|
-
{
|
50
|
-
:root => ::Rails.root,
|
51
|
-
:env => ::Rails.env,
|
52
|
-
:'config.path' => ::Rails.root.join('config', 'honeybadger.yml'),
|
53
|
-
:framework => :rails
|
54
|
-
}
|
55
|
-
end
|
56
|
-
|
57
|
-
def test_exception_class
|
58
|
-
exception_name = ENV['EXCEPTION'] || 'HoneybadgerTestingException'
|
59
|
-
Object.const_get(exception_name)
|
60
|
-
rescue
|
61
|
-
Object.const_set(exception_name, Class.new(Exception))
|
62
|
-
end
|
63
|
-
|
64
|
-
def send_test(verbose = true)
|
65
|
-
if defined?(::Rails)
|
66
|
-
rails_test(verbose)
|
67
|
-
else
|
68
|
-
standalone_test
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def standalone_test
|
73
|
-
Honeybadger.notify(test_exception_class.new('Testing honeybadger via "honeybadger test". If you can see this, it works.'))
|
74
|
-
end
|
75
|
-
|
76
|
-
def rails_test(verbose = true)
|
77
|
-
if verbose
|
78
|
-
::Rails.logger = if defined?(::ActiveSupport::TaggedLogging)
|
79
|
-
::ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
|
80
|
-
else
|
81
|
-
Logger.new(STDOUT)
|
82
|
-
end
|
83
|
-
::Rails.logger.level = Logger::INFO
|
84
|
-
end
|
85
|
-
|
86
|
-
# Suppress error logging in Rails' exception handling middleware. Rails 3.0
|
87
|
-
# uses ActionDispatch::ShowExceptions to rescue/show exceptions, but does
|
88
|
-
# not log anything but application trace. Rails 3.2 now falls back to
|
89
|
-
# logging the framework trace (moved to ActionDispatch::DebugExceptions),
|
90
|
-
# which caused cluttered output while running the test task.
|
91
|
-
defined?(::ActionDispatch::DebugExceptions) and
|
92
|
-
::ActionDispatch::DebugExceptions.class_eval { def logger(*args) ; @logger ||= Logger.new('/dev/null') ; end }
|
93
|
-
defined?(::ActionDispatch::ShowExceptions) and
|
94
|
-
::ActionDispatch::ShowExceptions.class_eval { def logger(*args) ; @logger ||= Logger.new('/dev/null') ; end }
|
95
|
-
|
96
|
-
# Detect and disable the better_errors gem
|
97
|
-
if defined?(::BetterErrors::Middleware)
|
98
|
-
say('Better Errors detected: temporarily disabling middleware.', :yellow)
|
99
|
-
::BetterErrors::Middleware.class_eval { def call(env) @app.call(env); end }
|
100
|
-
end
|
101
|
-
|
102
|
-
begin
|
103
|
-
require './app/controllers/application_controller'
|
104
|
-
rescue LoadError
|
105
|
-
nil
|
106
|
-
end
|
107
|
-
|
108
|
-
unless defined?(::ApplicationController)
|
109
|
-
say('Error: No ApplicationController found.', :red)
|
110
|
-
return false
|
111
|
-
end
|
112
|
-
|
113
|
-
say('Setting up the Controller.')
|
114
|
-
eval(<<-CONTROLLER)
|
115
|
-
class Honeybadger::TestController < ApplicationController
|
116
|
-
# This is to bypass any filters that may prevent access to the action.
|
117
|
-
if respond_to?(:prepend_before_action)
|
118
|
-
prepend_before_action :test_honeybadger
|
119
|
-
else
|
120
|
-
prepend_before_filter :test_honeybadger
|
121
|
-
end
|
122
|
-
|
123
|
-
def test_honeybadger
|
124
|
-
puts "Raising '#{test_exception_class.name}' to simulate application failure."
|
125
|
-
raise #{test_exception_class}.new, 'Testing honeybadger via "honeybadger test", it works.'
|
126
|
-
end
|
127
|
-
|
128
|
-
# Ensure we actually have an action to go to.
|
129
|
-
def verify; end
|
130
|
-
end
|
131
|
-
CONTROLLER
|
132
|
-
|
133
|
-
::Rails.application.routes.tap do |r|
|
134
|
-
# RouteSet#disable_clear_and_finalize prevents existing routes from
|
135
|
-
# being cleared. We'll set it back to the original value when we're
|
136
|
-
# done so not to mess with Rails state.
|
137
|
-
d = r.disable_clear_and_finalize
|
138
|
-
begin
|
139
|
-
r.disable_clear_and_finalize = true
|
140
|
-
r.clear!
|
141
|
-
r.draw do
|
142
|
-
match 'verify' => 'honeybadger/test#verify', :as => 'verify', :via => :get
|
143
|
-
end
|
144
|
-
::Rails.application.routes_reloader.paths.each{ |path| load(path) }
|
145
|
-
::ActiveSupport.on_load(:action_controller) { r.finalize! }
|
146
|
-
ensure
|
147
|
-
r.disable_clear_and_finalize = d
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
say('Processing request.')
|
152
|
-
|
153
|
-
ssl = defined?(::Rails.configuration.force_ssl) && ::Rails.configuration.force_ssl
|
154
|
-
env = ::Rack::MockRequest.env_for("http#{ ssl ? 's' : nil }://www.example.com/verify", 'REMOTE_ADDR' => '127.0.0.1')
|
155
|
-
|
156
|
-
::Rails.application.call(env)
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
@@ -1,70 +0,0 @@
|
|
1
|
-
module Honeybadger
|
2
|
-
class Config
|
3
|
-
class Callbacks
|
4
|
-
attr_reader :backtrace_filter, :exception_filter, :exception_fingerprint
|
5
|
-
|
6
|
-
def initialize
|
7
|
-
@backtrace_filter = nil
|
8
|
-
@exception_filter = nil
|
9
|
-
@exception_fingerprint = nil
|
10
|
-
end
|
11
|
-
|
12
|
-
# Public: Takes a block and adds it to the list of backtrace filters. When
|
13
|
-
# the filters run, the block will be handed each line of the backtrace and
|
14
|
-
# can modify it as necessary.
|
15
|
-
#
|
16
|
-
# &block - The new backtrace filter.
|
17
|
-
#
|
18
|
-
# Examples:
|
19
|
-
#
|
20
|
-
# config.backtrace_filter do |line|
|
21
|
-
# line.gsub(/^#{Rails.root}/, "[Rails.root]")
|
22
|
-
# end
|
23
|
-
#
|
24
|
-
# Yields a line in the backtrace.
|
25
|
-
def backtrace_filter(&block)
|
26
|
-
@backtrace_filter = Proc.new if block_given?
|
27
|
-
@backtrace_filter
|
28
|
-
end
|
29
|
-
|
30
|
-
# Public: Takes a block and adds it to the list of ignore filters. When
|
31
|
-
# the filters run, the block will be handed the exception.
|
32
|
-
#
|
33
|
-
# &block - The new ignore filter
|
34
|
-
# If the block returns true the exception will be ignored, otherwise it
|
35
|
-
# will be processed by honeybadger.
|
36
|
-
#
|
37
|
-
# Examples:
|
38
|
-
#
|
39
|
-
# config.exception_filter do |exception|
|
40
|
-
# if exception.class < MyError
|
41
|
-
# nil
|
42
|
-
# else
|
43
|
-
# exception
|
44
|
-
# end
|
45
|
-
# end
|
46
|
-
#
|
47
|
-
# Yields the the exception data given to Honeybadger.notify
|
48
|
-
def exception_filter(&block)
|
49
|
-
@exception_filter = Proc.new if block_given?
|
50
|
-
@exception_filter
|
51
|
-
end
|
52
|
-
|
53
|
-
# Public: Generate custom fingerprint (optional)
|
54
|
-
#
|
55
|
-
# block - An optional block returning object responding to #to_s
|
56
|
-
#
|
57
|
-
# Examples
|
58
|
-
#
|
59
|
-
# config.exception_fingerprint do |notice|
|
60
|
-
# [notice[:error_class], notice[:component], notice[:backtrace].to_s].join(':')
|
61
|
-
# end
|
62
|
-
#
|
63
|
-
# Returns configured fingerprint generator (should respond to #call(notice))
|
64
|
-
def exception_fingerprint
|
65
|
-
@exception_fingerprint = Proc.new if block_given?
|
66
|
-
@exception_fingerprint
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
require 'honeybadger/plugin'
|
2
|
-
require 'honeybadger/agent'
|
3
|
-
|
4
|
-
module Honeybadger
|
5
|
-
module Plugins
|
6
|
-
module Unicorn
|
7
|
-
module AfterForkExtension
|
8
|
-
def self.included(base)
|
9
|
-
base.send(:alias_method, :init_worker_process_without_honeybadger, :init_worker_process)
|
10
|
-
base.send(:alias_method, :init_worker_process, :init_worker_process_with_honeybadger)
|
11
|
-
end
|
12
|
-
|
13
|
-
def init_worker_process_with_honeybadger(*args, &block)
|
14
|
-
init_worker_process_without_honeybadger(*args, &block).tap do
|
15
|
-
Honeybadger::Agent.fork
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
Plugin.register do
|
21
|
-
requirement { defined?(::Unicorn::HttpServer) }
|
22
|
-
|
23
|
-
execution { ::Unicorn::HttpServer.send(:include, AfterForkExtension) }
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
require 'honeybadger'
|
2
|
-
|
3
|
-
module Honeybadger
|
4
|
-
module Rack
|
5
|
-
class MetricsReporter
|
6
|
-
def initialize(app, config)
|
7
|
-
@app = app
|
8
|
-
config.logger.warn('DEPRECATION WARNING: `Honeybadger::Rack::MetricsReporter` no longer has any effect and will be removed.')
|
9
|
-
end
|
10
|
-
|
11
|
-
def call(env)
|
12
|
-
@app.call(env)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,55 +0,0 @@
|
|
1
|
-
module Honeybadger
|
2
|
-
module Rack
|
3
|
-
# Internal: Constructs a request hash from a Rack::Request matching the
|
4
|
-
# /v1/notices API specification.
|
5
|
-
class RequestHash < ::Hash
|
6
|
-
# Internal
|
7
|
-
CGI_BLACKLIST = ['QUERY_STRING', 'RAW_POST_DATA', 'ORIGINAL_FULLPATH', 'REQUEST_URI'].freeze
|
8
|
-
CGI_KEY_REGEXP = /\A[A-Z_]+\Z/
|
9
|
-
|
10
|
-
def initialize(request)
|
11
|
-
self[:url] = extract_url(request)
|
12
|
-
self[:params] = extract_params(request)
|
13
|
-
self[:component] = self[:params]['controller']
|
14
|
-
self[:action] = self[:params]['action']
|
15
|
-
self[:session] = extract_session(request)
|
16
|
-
self[:cgi_data] = extract_cgi_data(request)
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def extract_url(request)
|
22
|
-
request.env['honeybadger.request.url'] || request.url
|
23
|
-
rescue => e
|
24
|
-
# TODO: Log these errors
|
25
|
-
"Error: #{e.message}"
|
26
|
-
end
|
27
|
-
|
28
|
-
def extract_params(request)
|
29
|
-
(request.env['action_dispatch.request.parameters'] || request.params).to_hash || {}
|
30
|
-
rescue => e
|
31
|
-
{ error: "Failed to access params -- #{e.message}" }
|
32
|
-
end
|
33
|
-
|
34
|
-
def extract_session(request)
|
35
|
-
request.session.to_hash
|
36
|
-
rescue => e
|
37
|
-
# Rails raises ArgumentError when `config.secret_token` is missing, and
|
38
|
-
# ActionDispatch::Session::SessionRestoreError when the session can't be
|
39
|
-
# restored.
|
40
|
-
{ error: "Failed to access session data -- #{e.message}" }
|
41
|
-
end
|
42
|
-
|
43
|
-
def extract_cgi_data(request)
|
44
|
-
request.env.reject {|k,_| cgi_blacklist?(k) }
|
45
|
-
end
|
46
|
-
|
47
|
-
def cgi_blacklist?(key)
|
48
|
-
return true if CGI_BLACKLIST.include?(key)
|
49
|
-
return true unless key.match(CGI_KEY_REGEXP)
|
50
|
-
|
51
|
-
false
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|