honeybadger 2.0.12 → 2.1.0.beta.1
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 +73 -0
- data/lib/honeybadger/agent/metrics_collection.rb +6 -8
- data/lib/honeybadger/agent/worker.rb +28 -8
- data/lib/honeybadger/backend/debug.rb +1 -0
- data/lib/honeybadger/cli/main.rb +2 -0
- data/lib/honeybadger/config.rb +12 -6
- data/lib/honeybadger/config/defaults.rb +124 -51
- data/lib/honeybadger/config/env.rb +13 -18
- data/lib/honeybadger/config/yaml.rb +2 -0
- data/lib/honeybadger/init/rails.rb +28 -10
- data/lib/honeybadger/init/sinatra.rb +16 -6
- data/lib/honeybadger/notice.rb +52 -97
- data/lib/honeybadger/plugins/delayed_job/plugin.rb +21 -8
- data/lib/honeybadger/plugins/local_variables.rb +9 -0
- data/lib/honeybadger/plugins/net_http.rb +4 -1
- data/lib/honeybadger/plugins/resque.rb +63 -0
- data/lib/honeybadger/plugins/sidekiq.rb +7 -4
- data/lib/honeybadger/trace.rb +46 -14
- data/lib/honeybadger/util/request_payload.rb +36 -0
- data/lib/honeybadger/util/sanitizer.rb +11 -1
- data/lib/honeybadger/util/stats.rb +22 -3
- data/lib/honeybadger/version.rb +1 -1
- data/vendor/capistrano-honeybadger/lib/capistrano/tasks/deploy.cap +1 -1
- data/vendor/capistrano-honeybadger/lib/honeybadger/capistrano/legacy.rb +1 -1
- metadata +6 -4
@@ -26,6 +26,15 @@ module Honeybadger
|
|
26
26
|
Plugin.register do
|
27
27
|
requirement { config[:'exceptions.local_variables'] }
|
28
28
|
requirement { defined?(::BindingOfCaller) }
|
29
|
+
requirement do
|
30
|
+
if res = defined?(::BetterErrors)
|
31
|
+
logger.warn("The local variables feature is incompatible with the " \
|
32
|
+
"better_errors gem; to remove this warning, set " \
|
33
|
+
"exceptions.local_variables to false for environments " \
|
34
|
+
"which load better_errors.")
|
35
|
+
end
|
36
|
+
!res
|
37
|
+
end
|
29
38
|
requirement { !::Exception.included_modules.include?(ExceptionExtension) }
|
30
39
|
|
31
40
|
execution { ::Exception.send(:include, ExceptionExtension) }
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'honeybadger/plugin'
|
2
|
+
require 'honeybadger/trace'
|
2
3
|
|
3
4
|
module Honeybadger
|
4
5
|
module Plugins
|
@@ -18,7 +19,9 @@ module Honeybadger
|
|
18
19
|
end
|
19
20
|
|
20
21
|
ActiveSupport::Notifications.instrument("net_http.request", { :uri => uri, :method => request.method }) do
|
21
|
-
|
22
|
+
# Disable tracing during #request so that additional calls (i.e.
|
23
|
+
# when connection wasn't started) don't result in double counting.
|
24
|
+
Trace.ignore_events { request_without_honeybadger(*args, &block) }
|
22
25
|
end
|
23
26
|
end
|
24
27
|
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'honeybadger/plugin'
|
2
|
+
require 'honeybadger'
|
3
|
+
|
4
|
+
module Honeybadger
|
5
|
+
module Plugins
|
6
|
+
module Resque
|
7
|
+
module Extension
|
8
|
+
def around_perform_with_honeybadger(*args)
|
9
|
+
Honeybadger.flush do
|
10
|
+
begin
|
11
|
+
Honeybadger::Trace.instrument("#{self.name}#perform", { source: 'resque', class: self.name }) do
|
12
|
+
yield
|
13
|
+
end
|
14
|
+
rescue Exception => e
|
15
|
+
Honeybadger.notify(e, parameters: { job_arguments: args })
|
16
|
+
raise e
|
17
|
+
end
|
18
|
+
end
|
19
|
+
ensure
|
20
|
+
Honeybadger.context.clear!
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module Installer
|
25
|
+
def self.included(base)
|
26
|
+
base.send(:alias_method, :payload_class_without_honeybadger, :payload_class)
|
27
|
+
base.send(:alias_method, :payload_class, :payload_class_with_honeybadger)
|
28
|
+
end
|
29
|
+
|
30
|
+
def payload_class_with_honeybadger
|
31
|
+
payload_class_without_honeybadger.tap do |klass|
|
32
|
+
unless klass.respond_to?(:around_perform_with_honeybadger)
|
33
|
+
klass.instance_eval do
|
34
|
+
extend(::Honeybadger::Plugins::Resque::Extension)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
Plugin.register do
|
42
|
+
requirement { defined?(::Resque::Job) }
|
43
|
+
|
44
|
+
requirement do
|
45
|
+
if resque_honeybadger = defined?(::Resque::Failure::Honeybadger)
|
46
|
+
logger.warn("Support for Resque has been moved " \
|
47
|
+
"to the honeybadger gem. Please remove " \
|
48
|
+
"resque-honeybadger from your " \
|
49
|
+
"Gemfile.")
|
50
|
+
end
|
51
|
+
!resque_honeybadger
|
52
|
+
end
|
53
|
+
|
54
|
+
execution do
|
55
|
+
::Resque::Job.send(:include, Installer)
|
56
|
+
::Resque.after_fork do |job|
|
57
|
+
Honeybadger::Agent.fork
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -17,15 +17,18 @@ module Honeybadger
|
|
17
17
|
requirement { defined?(::Sidekiq) }
|
18
18
|
|
19
19
|
execution do
|
20
|
-
::Sidekiq.configure_server do |
|
21
|
-
|
20
|
+
::Sidekiq.configure_server do |sidekiq|
|
21
|
+
sidekiq.server_middleware do |chain|
|
22
22
|
chain.add Middleware
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
26
|
if defined?(::Sidekiq::VERSION) && ::Sidekiq::VERSION > '3'
|
27
|
-
::Sidekiq.configure_server do |
|
28
|
-
|
27
|
+
::Sidekiq.configure_server do |sidekiq|
|
28
|
+
sidekiq.error_handlers << lambda {|ex, params|
|
29
|
+
return if params['retry'] && params['retry_count'].to_i < config[:'sidekiq.attempt_threshold'].to_i
|
30
|
+
Honeybadger.notify_or_ignore(ex, parameters: params)
|
31
|
+
}
|
29
32
|
end
|
30
33
|
end
|
31
34
|
end
|
data/lib/honeybadger/trace.rb
CHANGED
@@ -15,7 +15,31 @@ module Honeybadger
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def self.instrument(key, payload = {}, &block)
|
18
|
-
|
18
|
+
current = self.current
|
19
|
+
self.create(SecureRandom.uuid).instrument(key, payload, &block)
|
20
|
+
ensure
|
21
|
+
Thread.current[:__hb_trace] = current
|
22
|
+
end
|
23
|
+
|
24
|
+
# Internal: Disables event tracing for executed code block.
|
25
|
+
#
|
26
|
+
# block - The code which should not be traced.
|
27
|
+
#
|
28
|
+
# Returns the return value from the block.
|
29
|
+
def self.ignore_events
|
30
|
+
return yield if ignoring_events?
|
31
|
+
|
32
|
+
begin
|
33
|
+
Thread.current[:__hb_ignore_trace_events] = true
|
34
|
+
yield
|
35
|
+
ensure
|
36
|
+
Thread.current[:__hb_ignore_trace_events] = false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Internal: Is event tracing currently disabled?
|
41
|
+
def self.ignoring_events?
|
42
|
+
!!Thread.current[:__hb_ignore_trace_events]
|
19
43
|
end
|
20
44
|
|
21
45
|
def initialize(id)
|
@@ -27,28 +51,28 @@ module Honeybadger
|
|
27
51
|
end
|
28
52
|
|
29
53
|
def add(event)
|
54
|
+
return if ignoring_events?
|
30
55
|
ce = clean_event(event)
|
31
56
|
@events << ce.to_a if ce.render?
|
32
57
|
end
|
33
58
|
|
34
59
|
def add_query(event)
|
35
|
-
if
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
end
|
60
|
+
return if ignoring_events?
|
61
|
+
return add(event) unless event.duration < 6
|
62
|
+
|
63
|
+
ce = clean_event(event)
|
64
|
+
return unless ce.render?
|
65
|
+
query = ce.to_s
|
66
|
+
if @fast_queries[query]
|
67
|
+
@fast_queries[query][:duration] += ce.event.duration
|
68
|
+
@fast_queries[query][:count] += 1
|
45
69
|
else
|
46
|
-
|
70
|
+
@fast_queries[query] = { :duration => ce.event.duration, :count => 1 }
|
47
71
|
end
|
48
72
|
end
|
49
73
|
|
50
|
-
def complete(event)
|
51
|
-
@meta = clean_event(event).to_h
|
74
|
+
def complete(event, payload = {})
|
75
|
+
@meta = clean_event(event).to_h.merge(payload)
|
52
76
|
@duration = event.duration
|
53
77
|
@key = "#{event.payload[:controller]}##{event.payload[:action]}"
|
54
78
|
Thread.current[:__hb_trace] = nil
|
@@ -72,8 +96,16 @@ module Honeybadger
|
|
72
96
|
@meta.merge({ :events => @events, :key => @key, :fast_queries => @fast_queries.map {|k,v| [ k, v[:duration], v[:count] ] } })
|
73
97
|
end
|
74
98
|
|
99
|
+
# Private helpers: use at your own risk.
|
100
|
+
|
101
|
+
attr_reader :meta
|
102
|
+
|
75
103
|
protected
|
76
104
|
|
105
|
+
def ignoring_events?
|
106
|
+
self.class.ignoring_events?
|
107
|
+
end
|
108
|
+
|
77
109
|
def clean_event(event)
|
78
110
|
TraceCleaner.create(event)
|
79
111
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'honeybadger/util/sanitizer'
|
2
|
+
|
3
|
+
module Honeybadger
|
4
|
+
module Util
|
5
|
+
# Internal: Constructs/sanitizes request data for notices and traces.
|
6
|
+
module RequestPayload
|
7
|
+
# Internal: default values to use for request data.
|
8
|
+
DEFAULTS = {
|
9
|
+
url: nil,
|
10
|
+
component: nil,
|
11
|
+
action: nil,
|
12
|
+
params: {}.freeze,
|
13
|
+
session: {}.freeze,
|
14
|
+
cgi_data: {}.freeze
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
# Internal: allowed keys.
|
18
|
+
KEYS = DEFAULTS.keys.freeze
|
19
|
+
|
20
|
+
def self.build(opts = {})
|
21
|
+
sanitizer = opts.fetch(:sanitizer) { Sanitizer.new }
|
22
|
+
|
23
|
+
payload = DEFAULTS.dup
|
24
|
+
KEYS.each do |key|
|
25
|
+
next unless opts[key]
|
26
|
+
payload[key] = sanitizer.sanitize(opts[key])
|
27
|
+
end
|
28
|
+
|
29
|
+
payload[:session] = opts[:session][:data] if opts[:session] && opts[:session][:data]
|
30
|
+
payload[:url] = sanitizer.filter_url(payload[:url]) if payload[:url]
|
31
|
+
|
32
|
+
payload
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -5,6 +5,10 @@ module Honeybadger
|
|
5
5
|
|
6
6
|
FILTERED_REPLACEMENT = '[FILTERED]'.freeze
|
7
7
|
|
8
|
+
TRUNCATION_REPLACEMENT = '[TRUNCATED]'.freeze
|
9
|
+
|
10
|
+
MAX_STRING_SIZE = 2048
|
11
|
+
|
8
12
|
def initialize(opts = {})
|
9
13
|
@max_depth = opts.fetch(:max_depth, 20)
|
10
14
|
|
@@ -92,7 +96,7 @@ module Honeybadger
|
|
92
96
|
)
|
93
97
|
end
|
94
98
|
|
95
|
-
def
|
99
|
+
def valid_encoding(data)
|
96
100
|
return data if valid_encoding?(data)
|
97
101
|
|
98
102
|
if data.encoding == Encoding::UTF_8
|
@@ -101,6 +105,12 @@ module Honeybadger
|
|
101
105
|
data.encode(Encoding::UTF_8, ENCODE_OPTS)
|
102
106
|
end
|
103
107
|
end
|
108
|
+
|
109
|
+
def sanitize_string(data)
|
110
|
+
data = valid_encoding(data)
|
111
|
+
return data unless data.respond_to?(:size) && data.size > MAX_STRING_SIZE
|
112
|
+
data[0...MAX_STRING_SIZE] + TRUNCATION_REPLACEMENT
|
113
|
+
end
|
104
114
|
end
|
105
115
|
end
|
106
116
|
end
|
@@ -12,8 +12,8 @@ module Honeybadger
|
|
12
12
|
# From https://github.com/bloopletech/webstats/blob/master/server/data_providers/mem_info.rb
|
13
13
|
def memory
|
14
14
|
out = {}
|
15
|
-
if HAS_MEM
|
16
|
-
out[:total], out[:free], out[:buffers], out[:cached] =
|
15
|
+
if HAS_MEM && (meminfo = run_meminfo)
|
16
|
+
out[:total], out[:free], out[:buffers], out[:cached] = meminfo[0..4].map { |l| l =~ /^.*?\: +(.*?) kB$/; ($1.to_i / 1024.0).to_f }
|
17
17
|
out[:free_total] = out[:free] + out[:buffers] + out[:cached]
|
18
18
|
end
|
19
19
|
out
|
@@ -22,9 +22,28 @@ module Honeybadger
|
|
22
22
|
# From https://github.com/bloopletech/webstats/blob/master/server/data_providers/cpu_info.rb
|
23
23
|
def load
|
24
24
|
out = {}
|
25
|
-
|
25
|
+
if HAS_LOAD && (loadavg = run_loadavg)
|
26
|
+
out[:one], out[:five], out[:fifteen] = loadavg.split(' ', 4).map(&:to_f)
|
27
|
+
end
|
26
28
|
out
|
27
29
|
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def run_meminfo
|
34
|
+
run { IO.readlines("/proc/meminfo") }
|
35
|
+
end
|
36
|
+
|
37
|
+
def run_loadavg
|
38
|
+
run { IO.read("/proc/loadavg") }
|
39
|
+
end
|
40
|
+
|
41
|
+
def run
|
42
|
+
yield
|
43
|
+
rescue Errno::ENFILE
|
44
|
+
# Catch issues like 'Too many open files in system'
|
45
|
+
nil
|
46
|
+
end
|
28
47
|
end
|
29
48
|
end
|
30
49
|
end
|
data/lib/honeybadger/version.rb
CHANGED
@@ -31,7 +31,7 @@ module Honeybadger
|
|
31
31
|
logger.info 'DRY RUN: Notification not actually run.'
|
32
32
|
else
|
33
33
|
result = ''
|
34
|
-
run(notify_options, :once => true, :pty => false) { |ch, stream, data| result << data }
|
34
|
+
run("#{ notify_options }; true", :once => true, :pty => false) { |ch, stream, data| result << data }
|
35
35
|
end
|
36
36
|
logger.info 'Honeybadger Notification Complete.'
|
37
37
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: honeybadger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.1.0.beta.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Honeybadger Industries LLC
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-05-27 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Make managing application errors a more pleasant experience.
|
14
14
|
email:
|
@@ -60,6 +60,7 @@ files:
|
|
60
60
|
- lib/honeybadger/plugins/net_http.rb
|
61
61
|
- lib/honeybadger/plugins/passenger.rb
|
62
62
|
- lib/honeybadger/plugins/rails.rb
|
63
|
+
- lib/honeybadger/plugins/resque.rb
|
63
64
|
- lib/honeybadger/plugins/sidekiq.rb
|
64
65
|
- lib/honeybadger/plugins/thor.rb
|
65
66
|
- lib/honeybadger/plugins/unicorn.rb
|
@@ -73,6 +74,7 @@ files:
|
|
73
74
|
- lib/honeybadger/templates/feedback_form.erb
|
74
75
|
- lib/honeybadger/trace.rb
|
75
76
|
- lib/honeybadger/util/http.rb
|
77
|
+
- lib/honeybadger/util/request_payload.rb
|
76
78
|
- lib/honeybadger/util/sanitizer.rb
|
77
79
|
- lib/honeybadger/util/stats.rb
|
78
80
|
- lib/honeybadger/version.rb
|
@@ -139,9 +141,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
139
141
|
version: 1.9.3
|
140
142
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
141
143
|
requirements:
|
142
|
-
- - "
|
144
|
+
- - ">"
|
143
145
|
- !ruby/object:Gem::Version
|
144
|
-
version:
|
146
|
+
version: 1.3.1
|
145
147
|
requirements: []
|
146
148
|
rubyforge_project:
|
147
149
|
rubygems_version: 2.4.5
|