honeybadger 1.15.3 → 1.16.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9cfe3439d58b7af28a565d2de4933b569739de24
4
- data.tar.gz: bbce3f75341c717bb1509ef572e13d5383b7e156
3
+ metadata.gz: 96b32638a5a4110849fe17df1314fe7af3c7db78
4
+ data.tar.gz: d7336c7884a124058b0c244d7853848fe5576c62
5
5
  SHA512:
6
- metadata.gz: 4e26c85da0f200e09d0d89a19cef8d49d01bab91ef6a430257c4b39987636b29b927cdda9a1d15d880507383309b62b1b1ad01fa8a391620273db44542fb3a6b
7
- data.tar.gz: 43a4170cc003e0c4f1191255734bb3437c632ce30c708b12b8031fcf323927d1fcdd6825d26bf49001acc5cc41a02545a52a3fc6313567e844fa55bd46cb0e3c
6
+ metadata.gz: 622deae28180540415aade234278decc7fc70bf4903adff5fa0259f6dedd7e6a87af629fe6e9b28f9dd185ffc66ae04bc0885fc684c68c2ee679461575eb2f5a
7
+ data.tar.gz: 2130c58c2ba59741f5ed5da2d45ffb180f06e7fb11d9b9ea4f20412ad3365ce710380e5153b794456ce04abf2755be63a96c7c3082a4af020277ee6e5ee48ef4
data/Appraisals CHANGED
@@ -36,6 +36,11 @@ appraise 'rails2.3' do
36
36
  gem 'capistrano', '~> 2.0'
37
37
  end
38
38
 
39
+ appraise 'delayed_job' do
40
+ gem 'delayed_job'
41
+ gem 'honeybadger', :path => '../'
42
+ end
43
+
39
44
  if RUBY_VERSION > '1.9'
40
45
  appraise 'rails3.0' do
41
46
  gem 'rails', '~> 3.0.17'
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- honeybadger (1.15.3)
4
+ honeybadger (1.16.0)
5
5
  json
6
6
 
7
7
  GEM
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
- Honeybadger supports Ruby 1.8.7 through 2.1.
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.18 through Rails 4.1.0.
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}"
@@ -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 cgi_data should contain "FILTERED"
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
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "delayed_job"
6
+ gem "honeybadger", :path=>"../"
7
+
8
+ gemspec :path=>"../"
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.15.3'
8
- s.date = '2014-06-21'
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.15.3'.freeze
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
@@ -5,3 +5,4 @@ require 'honeybadger/integrations/sidekiq'
5
5
  require 'honeybadger/integrations/thor'
6
6
  require 'honeybadger/integrations/net_http'
7
7
  require 'honeybadger/integrations/passenger'
8
+ require 'honeybadger/integrations/unicorn'
@@ -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.configuration.traces? }
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 = rescue_http_errors do
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 = rescue_http_errors do
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.connection_config[:adapter] =~ DoubleQuoters
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(@per_request) do |t|
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
@@ -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.dup
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
@@ -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 = rescue_http_errors do
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 = rescue_http_errors do
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 rescue_http_errors(&block)
128
- yield
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
@@ -57,7 +57,7 @@ module HoneybadgerTasks
57
57
  response = http.request(post)
58
58
 
59
59
  if Net::HTTPSuccess === response
60
- puts "Succesfully recorded deployment"
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
- it "is public in a public environment" do
198
- config = Honeybadger::Configuration.new
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
- it "is not public in a development environment" do
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
- it "is public without an environment name" do
212
- config = Honeybadger::Configuration.new
213
- expect(config.public?).to be_true
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
- describe "DelayedJob Dependency" do
4
- before do
5
- Honeybadger::Dependency.reset!
6
- end
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
- context "when delayed_job is not installed" do
9
- it "fails quietly" do
10
- expect { Honeybadger::Dependency.inject! }.not_to raise_error
11
- end
12
- end
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
- context "when delayed_job is installed" do
15
- let(:plugins_array) { [] }
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
- before do
24
- Object.const_set(:Delayed, Module.new)
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
- after { Object.send(:remove_const, :Delayed) }
28
+ describe "DelayedJob integration" do
29
+ let(:worker) { Delayed::Worker.new }
30
30
 
31
- it "adds the plugin to DelayedJob" do
32
- Honeybadger::Dependency.inject!
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 "and delayed_job_honeybadger is installed" do
37
- before do
38
- ::Delayed.const_set(:Plugins, Module.new)
39
- ::Delayed::Plugins.const_set(:Honeybadger, Class.new(plugin_class))
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
- it "warns the user of the conflict" do
43
- Honeybadger.should_receive(:write_verbose_log).with(/Support for Delayed Job has been moved/, :warn).once
44
- Honeybadger::Dependency.inject!
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 = { 'string' => 'value' }
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 rack.request.form_vars" do
300
+ it "removes non-uppercase keys" do
301
301
  original = {
302
- "rack.request.form_vars" => "story%5Btitle%5D=The+TODO+label",
303
- "abc" => "123"
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({"abc" => "123"})
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("Succesfully recorded deployment")
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.15.3
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-06-21 00:00:00.000000000 Z
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.1.5
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.