honeybadger 1.15.3 → 1.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Appraisals +5 -0
- data/CHANGELOG.md +26 -0
- data/Gemfile.lock +1 -1
- data/README.md +8 -6
- data/Rakefile +1 -1
- data/features/rails.feature +1 -2
- data/gemfiles/delayed_job.gemfile +8 -0
- data/honeybadger.gemspec +5 -2
- data/lib/honeybadger.rb +2 -1
- data/lib/honeybadger/configuration.rb +1 -1
- data/lib/honeybadger/integrations.rb +1 -0
- data/lib/honeybadger/integrations/net_http.rb +1 -1
- data/lib/honeybadger/integrations/unicorn.rb +26 -0
- data/lib/honeybadger/monitor/sender.rb +2 -6
- data/lib/honeybadger/monitor/trace.rb +1 -1
- data/lib/honeybadger/monitor/worker.rb +4 -1
- data/lib/honeybadger/notice.rb +2 -7
- data/lib/honeybadger/rack/error_notifier.rb +2 -2
- data/lib/honeybadger/sender.rb +11 -8
- data/lib/honeybadger_tasks.rb +1 -1
- data/spec/honeybadger/configuration_spec.rb +38 -15
- data/spec/honeybadger/integrations/delayed_job_spec.rb +48 -32
- data/spec/honeybadger/integrations/unicorn_spec.rb +40 -0
- data/spec/honeybadger/monitor/trace_spec.rb +54 -0
- data/spec/honeybadger/monitor/worker_spec.rb +38 -0
- data/spec/honeybadger/notice_spec.rb +5 -5
- data/spec/honeybadger/rails/action_controller_spec.rb +1 -1
- data/spec/honeybadger_tasks_spec.rb +1 -1
- metadata +36 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 96b32638a5a4110849fe17df1314fe7af3c7db78
|
4
|
+
data.tar.gz: d7336c7884a124058b0c244d7853848fe5576c62
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 622deae28180540415aade234278decc7fc70bf4903adff5fa0259f6dedd7e6a87af629fe6e9b28f9dd185ffc66ae04bc0885fc684c68c2ee679461575eb2f5a
|
7
|
+
data.tar.gz: 2130c58c2ba59741f5ed5da2d45ffb180f06e7fb11d9b9ea4f20412ad3365ce710380e5153b794456ce04abf2755be63a96c7c3082a4af020277ee6e5ee48ef4
|
data/Appraisals
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,29 @@
|
|
1
|
+
## Honeybadger 1.16.0 ##
|
2
|
+
|
3
|
+
* Compress requests using deflate.
|
4
|
+
|
5
|
+
*Joshua Wood*
|
6
|
+
|
7
|
+
* Fix a bug where context wasn't reported from Sinatra applications
|
8
|
+
|
9
|
+
*Gavin Stark*
|
10
|
+
|
11
|
+
* Fix a bug which affected Rails 3.0 apps
|
12
|
+
(`ActiveRecord::Base.connection_config` missing).
|
13
|
+
|
14
|
+
*Joshua Wood*
|
15
|
+
|
16
|
+
* Stop sending non-server env.
|
17
|
+
|
18
|
+
*Joshua Wood*
|
19
|
+
|
20
|
+
* Automatically fork worker when Unicorn forks (removes the need to call
|
21
|
+
`Honeybadger::Monitor.worker.fork` in Unicorn's `after_fork` block.)
|
22
|
+
|
23
|
+
*Joshua Wood*
|
24
|
+
|
25
|
+
* Ruby 1.8.7 and 1.9.2 are no longer supported.
|
26
|
+
|
1
27
|
## Honeybadger 1.15.3 ##
|
2
28
|
|
3
29
|
* Send User-Agent header
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -8,17 +8,19 @@ This is the notifier gem for integrating apps with the :zap: [Honeybadger Except
|
|
8
8
|
When an uncaught exception occurs, Honeybadger will POST the relevant data
|
9
9
|
to the Honeybadger server specified in your environment.
|
10
10
|
|
11
|
-
## Documentation
|
12
|
-
|
13
|
-
[View the Documentation](http://docs.honeybadger.io/article/50-honeybadger-gem-documentation)
|
14
|
-
|
15
11
|
## Supported Ruby versions
|
16
12
|
|
17
|
-
|
13
|
+
#### IMPORTANT: As of version 1.16.0, Ruby 1.8.7 and 1.9.2 are unsupported. Please ensure you are running Ruby 1.9.3 or greater before upgrading.
|
14
|
+
|
15
|
+
Honeybadger supports Ruby 1.9.3 through 2.1.
|
18
16
|
|
19
17
|
## Supported Rails versions
|
20
18
|
|
21
|
-
Honeybadger supports Rails 2.3
|
19
|
+
Honeybadger supports Rails 2.3 through Rails 4.1 (latest releases).
|
20
|
+
|
21
|
+
## Documentation
|
22
|
+
|
23
|
+
[View the Documentation](http://docs.honeybadger.io/article/50-honeybadger-gem-documentation)
|
22
24
|
|
23
25
|
## Contributing
|
24
26
|
|
data/Rakefile
CHANGED
@@ -102,7 +102,7 @@ task :release => :build do
|
|
102
102
|
puts "You must be on the master branch to release!"
|
103
103
|
exit!
|
104
104
|
end
|
105
|
-
sh "git commit --allow-empty -a -m 'Release #{version}'"
|
105
|
+
sh "git commit --allow-empty -a -e -m 'Release #{version}'"
|
106
106
|
sh "git tag v#{version}"
|
107
107
|
sh "git push origin master"
|
108
108
|
sh "git push origin v#{version}"
|
data/features/rails.feature
CHANGED
@@ -233,9 +233,8 @@ Feature: Install the Gem in a Rails application
|
|
233
233
|
And I perform a request to "http://example.com:123/test/index?param=value&secret=blue42"
|
234
234
|
Then I should receive a Honeybadger notification
|
235
235
|
And the request should not contain "red23"
|
236
|
-
And the request params should contain "FILTERED"
|
237
236
|
And the request should not contain "blue42"
|
238
|
-
And the request
|
237
|
+
And the request params should contain "FILTERED"
|
239
238
|
|
240
239
|
Scenario: Filtering session in a controller
|
241
240
|
When I configure my application to require Honeybadger
|
data/honeybadger.gemspec
CHANGED
@@ -4,8 +4,8 @@ Gem::Specification.new do |s|
|
|
4
4
|
s.rubygems_version = '1.3.5'
|
5
5
|
|
6
6
|
s.name = 'honeybadger'
|
7
|
-
s.version = '1.
|
8
|
-
s.date = '2014-
|
7
|
+
s.version = '1.16.0'
|
8
|
+
s.date = '2014-07-09'
|
9
9
|
|
10
10
|
s.summary = 'Error reports you can be happy about.'
|
11
11
|
s.description = 'Make managing application errors a more pleasant experience.'
|
@@ -68,6 +68,7 @@ Gem::Specification.new do |s|
|
|
68
68
|
features/support/test.thor
|
69
69
|
features/thor.feature
|
70
70
|
gemfiles/binding_of_caller.gemfile
|
71
|
+
gemfiles/delayed_job.gemfile
|
71
72
|
gemfiles/rack.gemfile
|
72
73
|
gemfiles/rails.gemfile
|
73
74
|
gemfiles/rails2.3.gemfile
|
@@ -103,6 +104,7 @@ Gem::Specification.new do |s|
|
|
103
104
|
lib/honeybadger/integrations/passenger.rb
|
104
105
|
lib/honeybadger/integrations/sidekiq.rb
|
105
106
|
lib/honeybadger/integrations/thor.rb
|
107
|
+
lib/honeybadger/integrations/unicorn.rb
|
106
108
|
lib/honeybadger/monitor.rb
|
107
109
|
lib/honeybadger/monitor/railtie.rb
|
108
110
|
lib/honeybadger/monitor/sender.rb
|
@@ -144,6 +146,7 @@ Gem::Specification.new do |s|
|
|
144
146
|
spec/honeybadger/integrations/passenger_spec.rb
|
145
147
|
spec/honeybadger/integrations/sidekiq_spec.rb
|
146
148
|
spec/honeybadger/integrations/thor_spec.rb
|
149
|
+
spec/honeybadger/integrations/unicorn_spec.rb
|
147
150
|
spec/honeybadger/logger_spec.rb
|
148
151
|
spec/honeybadger/monitor/trace_spec.rb
|
149
152
|
spec/honeybadger/monitor/worker_spec.rb
|
data/lib/honeybadger.rb
CHANGED
@@ -20,11 +20,12 @@ require 'honeybadger/railtie' if defined?(Rails::Railtie)
|
|
20
20
|
require 'honeybadger/monitor'
|
21
21
|
|
22
22
|
module Honeybadger
|
23
|
-
VERSION = '1.
|
23
|
+
VERSION = '1.16.0'.freeze
|
24
24
|
LOG_PREFIX = "** [Honeybadger] ".freeze
|
25
25
|
|
26
26
|
HEADERS = {
|
27
27
|
'Content-type' => 'application/json',
|
28
|
+
'Content-Encoding' => 'deflate',
|
28
29
|
'Accept' => 'text/json, application/json',
|
29
30
|
'User-Agent' => "HB-Ruby #{VERSION}; #{RUBY_VERSION}; #{RUBY_PLATFORM}"
|
30
31
|
}.freeze
|
@@ -285,7 +285,7 @@ module Honeybadger
|
|
285
285
|
#
|
286
286
|
# Returns true if allowed to talk to API, false otherwise.
|
287
287
|
def public?
|
288
|
-
!development_environments.include?(environment_name)
|
288
|
+
api_key =~ /\S/ && !development_environments.include?(environment_name)
|
289
289
|
end
|
290
290
|
|
291
291
|
# Public: Determines whether to send metrics
|
@@ -26,7 +26,7 @@ module Honeybadger
|
|
26
26
|
Dependency.register do
|
27
27
|
requirement { defined?(::ActiveSupport::Notifications) }
|
28
28
|
requirement { defined?(::Net::HTTP) }
|
29
|
-
requirement { Honeybadger
|
29
|
+
requirement { defined?(::Honeybadger::Monitor) }
|
30
30
|
|
31
31
|
injection { ::Net::HTTP.send(:include, Integrations::NetHttp::Instrumentation) }
|
32
32
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Honeybadger
|
2
|
+
module Integrations
|
3
|
+
module Unicorn
|
4
|
+
module AfterForkExtension
|
5
|
+
def self.included(base)
|
6
|
+
base.send(:alias_method, :init_worker_process_without_honeybadger, :init_worker_process)
|
7
|
+
base.send(:alias_method, :init_worker_process, :init_worker_process_with_honeybadger)
|
8
|
+
end
|
9
|
+
|
10
|
+
def init_worker_process_with_honeybadger(*args, &block)
|
11
|
+
init_worker_process_without_honeybadger(*args, &block).tap do
|
12
|
+
Honeybadger::Monitor.worker.fork
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
Dependency.register do
|
20
|
+
requirement { defined?(::Honeybadger::Monitor) }
|
21
|
+
requirement { defined?(::Unicorn::HttpServer) }
|
22
|
+
|
23
|
+
injection { Honeybadger.write_verbose_log('Installing Unicorn integration') }
|
24
|
+
injection { ::Unicorn::HttpServer.send(:include, Integrations::Unicorn::AfterForkExtension) }
|
25
|
+
end
|
26
|
+
end
|
@@ -5,9 +5,7 @@ module Honeybadger
|
|
5
5
|
return unless Honeybadger.configuration.metrics?
|
6
6
|
return unless Honeybadger.configuration.features['metrics']
|
7
7
|
|
8
|
-
response =
|
9
|
-
http_connection.post('/v1/metrics', data.to_json, http_headers)
|
10
|
-
end
|
8
|
+
response = send_request('/v1/metrics', data.to_json)
|
11
9
|
|
12
10
|
if Net::HTTPSuccess === response
|
13
11
|
log(:info, "Metrics Success: #{response.class}", response, data) if Honeybadger.configuration.debug
|
@@ -26,9 +24,7 @@ module Honeybadger
|
|
26
24
|
return unless Honeybadger.configuration.traces?
|
27
25
|
return unless Honeybadger.configuration.features['traces']
|
28
26
|
|
29
|
-
response =
|
30
|
-
http_connection.post('/v1/traces', data.to_json, http_headers)
|
31
|
-
end
|
27
|
+
response = send_request('/v1/traces', data.to_json)
|
32
28
|
|
33
29
|
if Net::HTTPSuccess === response
|
34
30
|
log(:info, "Traces Success: #{response.class}", response, data) if Honeybadger.configuration.debug
|
@@ -130,7 +130,7 @@ module Honeybadger
|
|
130
130
|
return "Super long query" if event.payload[:sql].length > 1024
|
131
131
|
sql = event.payload[:sql]
|
132
132
|
sql = sql.gsub(EscapedQuotes, EmptyReplacement).gsub(SQuotedData, Replacement)
|
133
|
-
sql = sql.gsub(DQuotedData, Replacement) unless ::ActiveRecord::Base.
|
133
|
+
sql = sql.gsub(DQuotedData, Replacement) unless ::ActiveRecord::Base.connection_pool.spec.config[:adapter] =~ DoubleQuoters
|
134
134
|
sql.gsub(NumericData, Replacement).gsub(Newline, EmptyReplacement).squeeze(' ')
|
135
135
|
end
|
136
136
|
end
|
@@ -14,6 +14,7 @@ module Honeybadger
|
|
14
14
|
init_traces
|
15
15
|
@delay = defined?(::Rails) && ::Rails.env.development? ? 10 : 60
|
16
16
|
@per_request = 100
|
17
|
+
@traces_per_request = 20
|
17
18
|
@sender = Monitor::Sender.new(Honeybadger.configuration)
|
18
19
|
@lock = Mutex.new
|
19
20
|
start
|
@@ -73,6 +74,8 @@ module Honeybadger
|
|
73
74
|
end
|
74
75
|
|
75
76
|
def queue_trace
|
77
|
+
return unless trace
|
78
|
+
|
76
79
|
@lock.synchronize do
|
77
80
|
if trace.duration > Honeybadger.configuration.trace_threshold && (!@traces[trace.key] || @traces[trace.key].duration < trace.duration)
|
78
81
|
@traces[trace.key] = trace
|
@@ -142,7 +145,7 @@ module Honeybadger
|
|
142
145
|
|
143
146
|
Honeybadger.write_verbose_log('Sending traces')
|
144
147
|
|
145
|
-
traces.each_slice(@
|
148
|
+
traces.each_slice(@traces_per_request) do |t|
|
146
149
|
begin
|
147
150
|
@sender.send_traces({ :traces => t.compact.map(&:to_h), :environment => Honeybadger.configuration.environment_name, :hostname => Honeybadger.configuration.hostname })
|
148
151
|
rescue Exception => e
|
data/lib/honeybadger/notice.rb
CHANGED
@@ -137,9 +137,9 @@ module Honeybadger
|
|
137
137
|
self.send_request_session = args[:send_request_session].nil? ? true : args[:send_request_session]
|
138
138
|
|
139
139
|
find_session_data
|
140
|
-
clean_rack_request_data
|
141
140
|
also_use_rack_params_filters
|
142
141
|
set_context
|
142
|
+
clean_rack_request_data
|
143
143
|
end
|
144
144
|
|
145
145
|
# Deprecated. Remove in 2.0.
|
@@ -281,12 +281,7 @@ module Honeybadger
|
|
281
281
|
|
282
282
|
def clean_rack_request_data
|
283
283
|
if cgi_data
|
284
|
-
self.cgi_data = cgi_data.
|
285
|
-
cgi_data.delete("rack.request.form_vars")
|
286
|
-
cgi_data.delete("rack.request.query_string")
|
287
|
-
cgi_data.delete("rack.session")
|
288
|
-
cgi_data.delete("action_dispatch.request.parameters")
|
289
|
-
cgi_data.delete("action_dispatch.request.request_parameters")
|
284
|
+
self.cgi_data = cgi_data.reject {|k,_| k == 'QUERY_STRING' || !k.match(/\A[A-Z_]+\Z/) }
|
290
285
|
end
|
291
286
|
end
|
292
287
|
|
@@ -44,8 +44,6 @@ module Honeybadger
|
|
44
44
|
rescue Exception => raised
|
45
45
|
env['honeybadger.error_id'] = notify_honeybadger(raised, env)
|
46
46
|
raise
|
47
|
-
ensure
|
48
|
-
Honeybadger.context.clear!
|
49
47
|
end
|
50
48
|
|
51
49
|
framework_exception = env['rack.exception'] || env['sinatra.error']
|
@@ -54,6 +52,8 @@ module Honeybadger
|
|
54
52
|
end
|
55
53
|
|
56
54
|
response
|
55
|
+
ensure
|
56
|
+
Honeybadger.context.clear!
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|
data/lib/honeybadger/sender.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'zlib'
|
2
|
+
require 'stringio'
|
3
|
+
|
1
4
|
module Honeybadger
|
2
5
|
class Sender
|
3
6
|
NOTICES_URI = '/v1/notices/'.freeze
|
@@ -45,9 +48,7 @@ module Honeybadger
|
|
45
48
|
|
46
49
|
data = notice.is_a?(String) ? notice : notice.to_json
|
47
50
|
|
48
|
-
response =
|
49
|
-
http_connection.post(url.path, data, http_headers({'X-API-Key' => api_key}))
|
50
|
-
end
|
51
|
+
response = send_request(url.path, data, {'X-API-Key' => api_key})
|
51
52
|
|
52
53
|
if Net::HTTPSuccess === response
|
53
54
|
log(Honeybadger.configuration.debug ? :info : :debug, "Success: #{response.class}", response, data)
|
@@ -67,9 +68,7 @@ module Honeybadger
|
|
67
68
|
def ping(data = {})
|
68
69
|
return nil unless api_key_ok?
|
69
70
|
|
70
|
-
response =
|
71
|
-
http_connection.post('/v1/ping/', data.to_json, http_headers)
|
72
|
-
end
|
71
|
+
response = send_request('/v1/ping/', data.to_json)
|
73
72
|
|
74
73
|
if Net::HTTPSuccess === response
|
75
74
|
JSON.parse(response.body)
|
@@ -124,8 +123,8 @@ module Honeybadger
|
|
124
123
|
Honeybadger.write_verbose_log("Notice: #{data}", :debug) if data && Honeybadger.configuration.debug
|
125
124
|
end
|
126
125
|
|
127
|
-
def
|
128
|
-
|
126
|
+
def send_request(path, data, headers = {})
|
127
|
+
http_connection.post(path, compress(data), http_headers(headers))
|
129
128
|
rescue *HTTP_ERRORS => e
|
130
129
|
log(:error, "Unable to contact the Honeybadger server. HTTP Error=#{e}")
|
131
130
|
nil
|
@@ -176,5 +175,9 @@ module Honeybadger
|
|
176
175
|
Honeybadger.write_verbose_log("Original Exception: #{message}", :error)
|
177
176
|
end
|
178
177
|
end
|
178
|
+
|
179
|
+
def compress(string, level = Zlib::DEFAULT_COMPRESSION)
|
180
|
+
Zlib::Deflate.deflate(string, level)
|
181
|
+
end
|
179
182
|
end
|
180
183
|
end
|
data/lib/honeybadger_tasks.rb
CHANGED
@@ -57,7 +57,7 @@ module HoneybadgerTasks
|
|
57
57
|
response = http.request(post)
|
58
58
|
|
59
59
|
if Net::HTTPSuccess === response
|
60
|
-
puts "
|
60
|
+
puts "Successfully recorded deployment"
|
61
61
|
return true
|
62
62
|
else
|
63
63
|
$stderr.puts "Error recording deployment: #{response.class} -- #{response.body || 'no response'}"
|
@@ -194,23 +194,46 @@ describe Honeybadger::Configuration do
|
|
194
194
|
expect(config.development_environments).to eq %w(development test cucumber)
|
195
195
|
end
|
196
196
|
|
197
|
-
|
198
|
-
config
|
199
|
-
config.development_environments = %w(development)
|
200
|
-
config.environment_name = 'production'
|
201
|
-
expect(config.public?).to be_true
|
202
|
-
end
|
197
|
+
describe "#public?" do
|
198
|
+
let(:config) { Honeybadger::Configuration.new }
|
203
199
|
|
204
|
-
|
205
|
-
config = Honeybadger::Configuration.new
|
206
|
-
config.development_environments = %w(staging)
|
207
|
-
config.environment_name = 'staging'
|
208
|
-
expect(config.public?).to be_false
|
209
|
-
end
|
200
|
+
subject { config.public? }
|
210
201
|
|
211
|
-
|
212
|
-
|
213
|
-
|
202
|
+
before do
|
203
|
+
config.api_key = 'asdf'
|
204
|
+
end
|
205
|
+
|
206
|
+
context "when api_key is not configured" do
|
207
|
+
before { config.api_key = nil }
|
208
|
+
|
209
|
+
it { should be_false }
|
210
|
+
end
|
211
|
+
|
212
|
+
context "when api_key is configured" do
|
213
|
+
it { should be_true }
|
214
|
+
end
|
215
|
+
|
216
|
+
context "without an environment name" do
|
217
|
+
it { should be_true }
|
218
|
+
end
|
219
|
+
|
220
|
+
context "when environment is public" do
|
221
|
+
before do
|
222
|
+
config.development_environments = %w(development)
|
223
|
+
config.environment_name = 'production'
|
224
|
+
end
|
225
|
+
|
226
|
+
it { should be_true }
|
227
|
+
end
|
228
|
+
|
229
|
+
context "when environment is development" do
|
230
|
+
before do
|
231
|
+
config.development_environments = %w(development)
|
232
|
+
config.environment_name = 'development'
|
233
|
+
end
|
234
|
+
|
235
|
+
it { should be_false }
|
236
|
+
end
|
214
237
|
end
|
215
238
|
|
216
239
|
describe "#metrics?" do
|
@@ -1,47 +1,63 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'honeybadger/monitor'
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
begin
|
5
|
+
require 'delayed_job'
|
6
|
+
DELAYED_JOB_INSTALLED = true
|
7
|
+
rescue LoadError
|
8
|
+
DELAYED_JOB_INSTALLED = false
|
9
|
+
nil
|
10
|
+
end
|
7
11
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
12
|
+
if DELAYED_JOB_INSTALLED
|
13
|
+
# Prepend the load path with delayed_job's spec directory so that we can take
|
14
|
+
# advantage of their test backend:
|
15
|
+
# https://github.com/collectiveidea/delayed_job/blob/master/spec/delayed/backend/test.rb
|
16
|
+
$:.unshift(File.join(Gem::Specification.find_by_name('delayed_job').full_gem_path, 'spec'))
|
17
|
+
Delayed::Worker.backend = :test
|
13
18
|
|
14
|
-
|
15
|
-
|
16
|
-
let(:plugin_class) do
|
17
|
-
Class.new do
|
18
|
-
def self.callbacks(&block)
|
19
|
-
end
|
20
|
-
end
|
19
|
+
class ExceptionTester
|
20
|
+
def null_method
|
21
21
|
end
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
::Delayed.const_set(:Plugin, plugin_class)
|
26
|
-
::Delayed.const_set(:Worker, double(:plugins => plugins_array))
|
23
|
+
def will_raise
|
24
|
+
raise "raised from will_raise"
|
27
25
|
end
|
26
|
+
end
|
28
27
|
|
29
|
-
|
28
|
+
describe "DelayedJob integration" do
|
29
|
+
let(:worker) { Delayed::Worker.new }
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
expect(plugins_array).to include(Honeybadger::Integrations::DelayedJob::Plugin)
|
34
|
-
end
|
31
|
+
before { Honeybadger::Dependency.inject! }
|
32
|
+
after { Delayed::Job.delete_all }
|
35
33
|
|
36
|
-
context "
|
37
|
-
|
38
|
-
|
39
|
-
|
34
|
+
context "when a method is delayed" do
|
35
|
+
let(:method_name) { :null_method }
|
36
|
+
|
37
|
+
before { ExceptionTester.new.delay.send(method_name) }
|
38
|
+
|
39
|
+
specify { expect(Delayed::Job.count).to eq 1 }
|
40
|
+
|
41
|
+
it "queues a new trace" do
|
42
|
+
trace_id = nil
|
43
|
+
Honeybadger::Monitor.worker.should_receive(:queue_trace).once.and_return do
|
44
|
+
# This ensures that Honeybadger::Monitor.worker.trace is not nil when
|
45
|
+
# it's queued from the worker. There may still be an edge case where
|
46
|
+
# that's possible. (see #84)
|
47
|
+
trace_id = Thread.current[:hb_trace_id]
|
48
|
+
end
|
49
|
+
worker.work_off
|
50
|
+
expect(trace_id).not_to be_nil
|
40
51
|
end
|
41
52
|
|
42
|
-
|
43
|
-
|
44
|
-
|
53
|
+
context "and an exception occurs" do
|
54
|
+
let(:method_name) { :will_raise }
|
55
|
+
|
56
|
+
after { worker.work_off }
|
57
|
+
|
58
|
+
it "notifies Honeybadger" do
|
59
|
+
Honeybadger.should_receive(:notify_or_ignore).once
|
60
|
+
end
|
45
61
|
end
|
46
62
|
end
|
47
63
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Unicorn integration" do
|
4
|
+
before do
|
5
|
+
Honeybadger::Dependency.reset!
|
6
|
+
end
|
7
|
+
|
8
|
+
context "when unicorn is not installed" do
|
9
|
+
it "fails quietly" do
|
10
|
+
expect { Honeybadger::Dependency.inject! }.not_to raise_error
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context "when unicorn is installed" do
|
15
|
+
let(:shim) {
|
16
|
+
Class.new {
|
17
|
+
def init_worker_process(worker)
|
18
|
+
'foo'
|
19
|
+
end
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
before do
|
24
|
+
Object.const_set(:Unicorn, Module.new)
|
25
|
+
Unicorn.const_set(:HttpServer, shim)
|
26
|
+
end
|
27
|
+
after { Object.send(:remove_const, :Unicorn) }
|
28
|
+
|
29
|
+
it "logs installation" do
|
30
|
+
Honeybadger.should_receive(:write_verbose_log).with(/Unicorn/)
|
31
|
+
Honeybadger::Dependency.inject!
|
32
|
+
end
|
33
|
+
|
34
|
+
it "installs unicorn hooks" do
|
35
|
+
Honeybadger::Dependency.inject!
|
36
|
+
Honeybadger::Monitor.worker.should_receive(:fork)
|
37
|
+
expect(shim.new.init_worker_process(double('worker'))).to eq 'foo'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -3,9 +3,63 @@ require 'honeybadger/monitor'
|
|
3
3
|
|
4
4
|
describe Honeybadger::Monitor::Trace do
|
5
5
|
describe "::instrument" do
|
6
|
+
before do
|
7
|
+
Honeybadger::Monitor::Trace.stub(:generate_secure_id).and_return(:foo)
|
8
|
+
end
|
9
|
+
|
6
10
|
it "creates a new trace" do
|
7
11
|
Honeybadger::Monitor::Trace.should_receive(:new).and_call_original
|
8
12
|
described_class.instrument('testing', {}){}
|
9
13
|
end
|
14
|
+
|
15
|
+
it "temporarily stores trace id in thread local" do
|
16
|
+
described_class.instrument('testing', {}) do
|
17
|
+
expect(Thread.current[:hb_trace_id]).to eq :foo
|
18
|
+
end
|
19
|
+
|
20
|
+
expect(Thread.current[:hb_trace_id]).to be_nil
|
21
|
+
end
|
22
|
+
|
23
|
+
it "stores the trace on the worker's pending traces" do
|
24
|
+
described_class.instrument('testing', {}) do
|
25
|
+
expect(Honeybadger::Monitor.worker.pending_traces[:foo]).to be_a Honeybadger::Monitor::Trace
|
26
|
+
end
|
27
|
+
|
28
|
+
expect(Honeybadger::Monitor.worker.pending_traces[:foo]).to be_nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
begin
|
34
|
+
require 'active_support/notifications'
|
35
|
+
require 'active_record'
|
36
|
+
|
37
|
+
describe Honeybadger::Monitor::TraceCleaner::ActiveRecord do
|
38
|
+
let(:event) do
|
39
|
+
::ActiveSupport::Notifications::Event.new(
|
40
|
+
'sql.active_record', # name
|
41
|
+
now = Time.now.to_f, # start
|
42
|
+
now+0.2, # ending
|
43
|
+
'1', # transaction_id
|
44
|
+
{ # payload
|
45
|
+
:name => nil,
|
46
|
+
:sql => '',
|
47
|
+
:binds => [],
|
48
|
+
:connection_id => 123
|
49
|
+
}
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
before do
|
54
|
+
::ActiveRecord::Base.stub(:connection_pool).and_return(double(:spec => double(:config => {})))
|
55
|
+
end
|
56
|
+
|
57
|
+
# This will fail if the configuration is accessed through
|
58
|
+
# `ActiveRecord::Base.connection_config` in rails < 3.1.
|
59
|
+
it "safely accesses connection configuration" do
|
60
|
+
expect { described_class.new(event).to_s }.not_to raise_error
|
61
|
+
end
|
10
62
|
end
|
63
|
+
rescue LoadError
|
64
|
+
nil
|
11
65
|
end
|
@@ -16,6 +16,44 @@ describe Honeybadger::Monitor::Worker do
|
|
16
16
|
instance.stub(:lock) { instance.instance_variable_get(:@lock) }
|
17
17
|
end
|
18
18
|
|
19
|
+
describe "#queue_trace" do
|
20
|
+
let(:trace) { Honeybadger::Monitor::Trace.new(:foo) }
|
21
|
+
|
22
|
+
context "when a trace exists" do
|
23
|
+
before do
|
24
|
+
trace.stub(:key).and_return(:bar)
|
25
|
+
subject.pending_traces[:foo] = trace
|
26
|
+
Thread.current[:hb_trace_id] = :foo
|
27
|
+
end
|
28
|
+
|
29
|
+
context "and the same trace key exists" do
|
30
|
+
let(:old_trace) { Honeybadger::Monitor::Trace.new(:foo) }
|
31
|
+
|
32
|
+
before do
|
33
|
+
old_trace.stub(:duration).and_return(2000)
|
34
|
+
old_trace.stub(:key).and_return(:bar)
|
35
|
+
subject.traces[:bar] = old_trace
|
36
|
+
end
|
37
|
+
|
38
|
+
context "and the new duration is not greater" do
|
39
|
+
before { trace.stub(:duration).and_return(2000) }
|
40
|
+
|
41
|
+
it "replaces the existing trace" do
|
42
|
+
expect { subject.queue_trace }.not_to change { subject.traces[:bar] }.from(old_trace)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "and the new duration is greater" do
|
47
|
+
before { trace.stub(:duration).and_return(3000) }
|
48
|
+
|
49
|
+
it "replaces the existing trace" do
|
50
|
+
expect { subject.queue_trace }.to change { subject.traces[:bar] }.from(old_trace).to(trace)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
19
57
|
describe "#fork" do
|
20
58
|
before { Thread.unstub(:new) }
|
21
59
|
before { Honeybadger.stub(:write_verbose_log) }
|
@@ -264,7 +264,7 @@ describe Honeybadger::Notice do
|
|
264
264
|
end
|
265
265
|
|
266
266
|
it "accepts CGI data from a hash" do
|
267
|
-
data = { '
|
267
|
+
data = { 'STRING' => 'value' }
|
268
268
|
notice = build_notice(:cgi_data => data)
|
269
269
|
expect(notice.cgi_data).to eq data
|
270
270
|
end
|
@@ -297,14 +297,14 @@ describe Honeybadger::Notice do
|
|
297
297
|
assert_array_starts_with backtrace.lines, notice.backtrace.lines
|
298
298
|
end
|
299
299
|
|
300
|
-
it "removes
|
300
|
+
it "removes non-uppercase keys" do
|
301
301
|
original = {
|
302
|
-
|
303
|
-
|
302
|
+
'rack.request.form_vars' => 'story%5Btitle%5D=The+TODO+label',
|
303
|
+
'ABC' => "123"
|
304
304
|
}
|
305
305
|
|
306
306
|
notice = build_notice(:cgi_data => original)
|
307
|
-
expect(notice.cgi_data).to eq({
|
307
|
+
expect(notice.cgi_data).to eq({'ABC' => '123'})
|
308
308
|
end
|
309
309
|
|
310
310
|
it "does not send empty request data" do
|
@@ -65,7 +65,7 @@ begin
|
|
65
65
|
assert_sent_element(params['controller']) { |h| h['request']['component'] }
|
66
66
|
assert_sent_element(params['action']) { |h| h['request']['action'] }
|
67
67
|
assert_sent_element(url_from_request(request)) { |h| h['request']['url'] }
|
68
|
-
assert_sent_hash(request.env) { |h| h['request']['cgi_data'] }
|
68
|
+
assert_sent_hash(request.env.reject {|k,_| k == 'QUERY_STRING' || !k.match(/\A[A-Z_]+\Z/) }) { |h| h['request']['cgi_data'] }
|
69
69
|
end
|
70
70
|
|
71
71
|
def url_from_request(request)
|
@@ -92,7 +92,7 @@ describe HoneybadgerTasks do
|
|
92
92
|
end
|
93
93
|
|
94
94
|
it "puts the response body on success" do
|
95
|
-
HoneybadgerTasks.should_receive(:puts).with("
|
95
|
+
HoneybadgerTasks.should_receive(:puts).with("Successfully recorded deployment")
|
96
96
|
@http_proxy.should_receive(:request).with(anything).and_return(successful_response('body'))
|
97
97
|
HoneybadgerTasks.deploy(@options)
|
98
98
|
end
|
metadata
CHANGED
@@ -1,195 +1,195 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: honeybadger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.16.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joshua Wood
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-07-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: cucumber
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 1.3.10
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 1.3.10
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: 2.14.0
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - ~>
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 2.14.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: sham_rack
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - ~>
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 1.3.0
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - ~>
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 1.3.0
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: capistrano
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - ~>
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '2.0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - ~>
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '2.0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: guard
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - ~>
|
87
|
+
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: 1.8.3
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - ~>
|
94
|
+
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: 1.8.3
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: guard-rspec
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- -
|
101
|
+
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- -
|
108
|
+
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: rake
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - ">="
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '0'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- -
|
122
|
+
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: sinatra
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
|
-
- -
|
129
|
+
- - ">="
|
130
130
|
- !ruby/object:Gem::Version
|
131
131
|
version: '0'
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
|
-
- -
|
136
|
+
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: aruba
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
|
-
- -
|
143
|
+
- - ">="
|
144
144
|
- !ruby/object:Gem::Version
|
145
145
|
version: '0'
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- -
|
150
|
+
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
154
|
name: appraisal
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
156
156
|
requirements:
|
157
|
-
- -
|
157
|
+
- - ">="
|
158
158
|
- !ruby/object:Gem::Version
|
159
159
|
version: '0'
|
160
160
|
type: :development
|
161
161
|
prerelease: false
|
162
162
|
version_requirements: !ruby/object:Gem::Requirement
|
163
163
|
requirements:
|
164
|
-
- -
|
164
|
+
- - ">="
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0'
|
167
167
|
- !ruby/object:Gem::Dependency
|
168
168
|
name: fuubar
|
169
169
|
requirement: !ruby/object:Gem::Requirement
|
170
170
|
requirements:
|
171
|
-
- -
|
171
|
+
- - ">="
|
172
172
|
- !ruby/object:Gem::Version
|
173
173
|
version: '0'
|
174
174
|
type: :development
|
175
175
|
prerelease: false
|
176
176
|
version_requirements: !ruby/object:Gem::Requirement
|
177
177
|
requirements:
|
178
|
-
- -
|
178
|
+
- - ">="
|
179
179
|
- !ruby/object:Gem::Version
|
180
180
|
version: '0'
|
181
181
|
- !ruby/object:Gem::Dependency
|
182
182
|
name: growl
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
184
184
|
requirements:
|
185
|
-
- -
|
185
|
+
- - ">="
|
186
186
|
- !ruby/object:Gem::Version
|
187
187
|
version: '0'
|
188
188
|
type: :development
|
189
189
|
prerelease: false
|
190
190
|
version_requirements: !ruby/object:Gem::Requirement
|
191
191
|
requirements:
|
192
|
-
- -
|
192
|
+
- - ">="
|
193
193
|
- !ruby/object:Gem::Version
|
194
194
|
version: '0'
|
195
195
|
description: Make managing application errors a more pleasant experience.
|
@@ -229,6 +229,7 @@ files:
|
|
229
229
|
- features/support/test.thor
|
230
230
|
- features/thor.feature
|
231
231
|
- gemfiles/binding_of_caller.gemfile
|
232
|
+
- gemfiles/delayed_job.gemfile
|
232
233
|
- gemfiles/rack.gemfile
|
233
234
|
- gemfiles/rails.gemfile
|
234
235
|
- gemfiles/rails2.3.gemfile
|
@@ -264,6 +265,7 @@ files:
|
|
264
265
|
- lib/honeybadger/integrations/passenger.rb
|
265
266
|
- lib/honeybadger/integrations/sidekiq.rb
|
266
267
|
- lib/honeybadger/integrations/thor.rb
|
268
|
+
- lib/honeybadger/integrations/unicorn.rb
|
267
269
|
- lib/honeybadger/monitor.rb
|
268
270
|
- lib/honeybadger/monitor/railtie.rb
|
269
271
|
- lib/honeybadger/monitor/sender.rb
|
@@ -305,6 +307,7 @@ files:
|
|
305
307
|
- spec/honeybadger/integrations/passenger_spec.rb
|
306
308
|
- spec/honeybadger/integrations/sidekiq_spec.rb
|
307
309
|
- spec/honeybadger/integrations/thor_spec.rb
|
310
|
+
- spec/honeybadger/integrations/unicorn_spec.rb
|
308
311
|
- spec/honeybadger/logger_spec.rb
|
309
312
|
- spec/honeybadger/monitor/trace_spec.rb
|
310
313
|
- spec/honeybadger/monitor/worker_spec.rb
|
@@ -330,23 +333,23 @@ licenses: []
|
|
330
333
|
metadata: {}
|
331
334
|
post_install_message:
|
332
335
|
rdoc_options:
|
333
|
-
- --charset=UTF-8
|
334
|
-
- --markup tomdoc
|
336
|
+
- "--charset=UTF-8"
|
337
|
+
- "--markup tomdoc"
|
335
338
|
require_paths:
|
336
339
|
- lib
|
337
340
|
required_ruby_version: !ruby/object:Gem::Requirement
|
338
341
|
requirements:
|
339
|
-
- -
|
342
|
+
- - ">="
|
340
343
|
- !ruby/object:Gem::Version
|
341
344
|
version: '0'
|
342
345
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
343
346
|
requirements:
|
344
|
-
- -
|
347
|
+
- - ">="
|
345
348
|
- !ruby/object:Gem::Version
|
346
349
|
version: '0'
|
347
350
|
requirements: []
|
348
351
|
rubyforge_project:
|
349
|
-
rubygems_version: 2.
|
352
|
+
rubygems_version: 2.2.2
|
350
353
|
signing_key:
|
351
354
|
specification_version: 2
|
352
355
|
summary: Error reports you can be happy about.
|