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 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.