honeybadger 2.7.2 → 3.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|