airbrake 5.8.0.rc.2 → 5.8.0.rc.3

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: 739d297145e474289e0991518823f2a335730af1
4
- data.tar.gz: e342217370635b59ff72dab485a5ae2190693100
3
+ metadata.gz: 493f0a2aced008e37822fd5be783ee6874312987
4
+ data.tar.gz: 4d4f2e85c5f959d516aa0fd1e9a048f5db8977cd
5
5
  SHA512:
6
- metadata.gz: ab4c6612ef1301925779ca3519a85a119d213e5b72f10748f98f144b00547b4e8db8a57babc398238f72096575d05392f8cd14d532cdfad7f0c8068ff405c520
7
- data.tar.gz: 1bcc18a8234ba41e3d28a19e7cf1071611c21275cf049f843003a018995b0f9e75642b1c7d9f7a22165c3f78286f48aedeaa99604409fb79ba6c65e476742efa
6
+ metadata.gz: 8381916743bd4d1ada0027a85acd10212cb1f9a0fec53f2c5aec6b0623e56641bb7b0a1972dd1de85ab40726e1412d2be92291073c4ad394305a906a8605d0d8
7
+ data.tar.gz: 32e1cb6fa237f035c01f68619e40bcda26aedfb2b02b9b4f42b9c46d10f66c79fd6a3bf5344ba5cfba4a2138a60961855e82c36f2a88200693df53a879afbdf1
@@ -25,7 +25,8 @@ require 'airbrake/resque/failure' if defined?(Resque)
25
25
  require 'airbrake/sidekiq/error_handler' if defined?(Sidekiq)
26
26
  require 'airbrake/shoryuken/error_handler' if defined?(Shoryuken)
27
27
  require 'airbrake/delayed_job/plugin' if defined?(Delayed)
28
- require 'airbrake/logger/logger_ext' if defined?(Logger)
28
+
29
+ require 'airbrake/logger/airbrake_logger'
29
30
 
30
31
  ##
31
32
  # This module reopens the original Airbrake module from airbrake-ruby and adds
@@ -0,0 +1,106 @@
1
+ require 'logger'
2
+
3
+ module Airbrake
4
+ ##
5
+ # Decorator for +Logger+ from stdlib. Endows loggers the ability to both log
6
+ # and report errors to Airbrake.
7
+ #
8
+ # @example
9
+ # # Create a logger like you normally do and decorate it.
10
+ # logger = Airbrake::AirbrakeLogger.new(Logger.new(STDOUT))
11
+ #
12
+ # # Just use the logger like you normally do.
13
+ # logger.fatal('oops')
14
+ class AirbrakeLogger < SimpleDelegator
15
+ ##
16
+ # @example
17
+ # # Assign a default Airbrake notifier
18
+ # logger.airbrake_notifier = Airbrake[:default]
19
+ # @return [Airbrake::Notifier] notifier to be used to send notices
20
+ attr_accessor :airbrake_notifier
21
+
22
+ ##
23
+ # @example
24
+ # logger.airbrake_level = Logger::FATAL
25
+ # @return [Integer]
26
+ attr_accessor :airbrake_level
27
+
28
+ def initialize(logger)
29
+ __setobj__(logger)
30
+ @airbrake_notifier = Airbrake[:default]
31
+ @airbrake_level = Logger::WARN
32
+ end
33
+
34
+ ##
35
+ # @see Logger#warn
36
+ def warn(progname = nil, &block)
37
+ notify_airbrake(Logger::WARN, progname)
38
+ super
39
+ end
40
+
41
+ ##
42
+ # @see Logger#error
43
+ def error(progname = nil, &block)
44
+ notify_airbrake(Logger::ERROR, progname)
45
+ super
46
+ end
47
+
48
+ ##
49
+ # @see Logger#fatal
50
+ def fatal(progname = nil, &block)
51
+ notify_airbrake(Logger::FATAL, progname)
52
+ super
53
+ end
54
+
55
+ ##
56
+ # @see Logger#unknown
57
+ def unknown(progname = nil, &block)
58
+ notify_airbrake(Logger::UNKNOWN, progname)
59
+ super
60
+ end
61
+
62
+ ##
63
+ # Sets airbrake severity level. Does not permit values below `Logger::WARN`.
64
+ #
65
+ # @example
66
+ # logger.airbrake_level = Logger::FATAL
67
+ # @return [void]
68
+ def airbrake_level=(level)
69
+ if level < Logger::WARN
70
+ raise "Airbrake severity level #{level} is not allowed. " \
71
+ "Minimum allowed level is #{Logger::WARN}"
72
+ end
73
+ @airbrake_level = level
74
+ end
75
+
76
+ private
77
+
78
+ def notify_airbrake(severity, progname)
79
+ return if severity < @airbrake_level || !@airbrake_notifier
80
+
81
+ notice = @airbrake_notifier.build_notice(progname)
82
+
83
+ # Get rid of unwanted internal Logger frames. Examples:
84
+ # * /ruby-2.4.0/lib/ruby/2.4.0/logger.rb
85
+ # * /gems/activesupport-4.2.7.1/lib/active_support/logger.rb
86
+ backtrace = notice[:errors].first[:backtrace]
87
+ notice[:errors].first[:backtrace] =
88
+ backtrace.drop_while { |frame| frame[:file] =~ %r{/logger.rb\z} }
89
+
90
+ notice[:context][:component] = 'log'
91
+ notice[:context][:severity] = normalize_severity(severity)
92
+
93
+ @airbrake_notifier.notify(notice)
94
+ end
95
+
96
+ def normalize_severity(severity)
97
+ (case severity
98
+ when Logger::WARN then 'warning'
99
+ when Logger::ERROR, Logger::UNKNOWN then 'error'
100
+ when Logger::FATAL then 'critical'
101
+ else
102
+ raise "Unknown airbrake severity: #{severity}"
103
+ end).freeze
104
+ end
105
+ end
106
+ end
@@ -25,9 +25,9 @@ module Airbrake
25
25
 
26
26
  def self.try_current_user(rack_env)
27
27
  controller = rack_env['action_controller.instance']
28
- return unless controller.respond_to?(:current_user)
28
+ return unless controller.respond_to?(:current_user, true)
29
29
  return unless [-1, 0].include?(controller.method(:current_user).arity)
30
- controller.current_user
30
+ controller.__send__(:current_user)
31
31
  end
32
32
  private_class_method :try_current_user
33
33
 
@@ -2,5 +2,5 @@
2
2
  # We use Semantic Versioning v2.0.0
3
3
  # More information: http://semver.org/
4
4
  module Airbrake
5
- AIRBRAKE_VERSION = '5.8.0.rc.2'.freeze
5
+ AIRBRAKE_VERSION = '5.8.0.rc.3'.freeze
6
6
  end
@@ -0,0 +1,121 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Airbrake::AirbrakeLogger do
4
+ let(:project_id) { 113743 }
5
+ let(:project_key) { 'fd04e13d806a90f96614ad8e529b2822' }
6
+
7
+ let(:endpoint) do
8
+ "https://airbrake.io/api/v3/projects/#{project_id}/notices?key=#{project_key}"
9
+ end
10
+
11
+ let(:airbrake) do
12
+ Airbrake::Notifier.new(project_id: project_id, project_key: project_key)
13
+ end
14
+
15
+ let(:logger) { Logger.new('/dev/null') }
16
+
17
+ subject { described_class.new(logger) }
18
+
19
+ def wait_for_a_request_with_body(body)
20
+ wait_for(a_request(:post, endpoint).with(body: body)).to have_been_made.once
21
+ end
22
+
23
+ before do
24
+ stub_request(:post, endpoint).to_return(status: 201, body: '{}')
25
+ end
26
+
27
+ describe "#airbrake_notifier" do
28
+ it "has the default notifier installed by default" do
29
+ expect(subject.airbrake_notifier).to be_an(Airbrake::Notifier)
30
+ end
31
+
32
+ it "installs Airbrake notifier" do
33
+ notifier_id = airbrake.object_id
34
+ expect(subject.airbrake_notifier.object_id).not_to eq(notifier_id)
35
+
36
+ subject.airbrake_notifier = airbrake
37
+ expect(subject.airbrake_notifier.object_id).to eq(notifier_id)
38
+ end
39
+
40
+ context "when Airbrake is installed explicitly" do
41
+ let(:out) { StringIO.new }
42
+ let(:logger) { Logger.new(out) }
43
+
44
+ before do
45
+ subject.airbrake_notifier = airbrake
46
+ end
47
+
48
+ it "both logs and notifies" do
49
+ msg = 'bingo'
50
+ subject.fatal(msg)
51
+
52
+ wait_for_a_request_with_body(/"message":"#{msg}"/)
53
+ expect(out.string).to match(/FATAL -- : #{msg}/)
54
+ end
55
+
56
+ it "sets the correct severity" do
57
+ subject.fatal('bango')
58
+ wait_for_a_request_with_body(/"context":{.*"severity":"critical".*}/)
59
+ end
60
+
61
+ it "sets the correct component" do
62
+ subject.fatal('bingo')
63
+ wait_for_a_request_with_body(/"component":"log"/)
64
+ end
65
+
66
+ it "strips out internal logger frames" do
67
+ subject.fatal('bongo')
68
+
69
+ wait_for(
70
+ a_request(:post, endpoint).
71
+ with(body: %r{"file":".+/logger.rb"})
72
+ ).not_to have_been_made
73
+ wait_for(a_request(:post, endpoint)).to have_been_made.once
74
+ end
75
+ end
76
+
77
+ context "when Airbrake is not installed" do
78
+ it "only logs, never notifies" do
79
+ out = StringIO.new
80
+ l = described_class.new(Logger.new(out))
81
+ l.airbrake_notifier = nil
82
+ msg = 'bango'
83
+
84
+ l.fatal(msg)
85
+
86
+ wait_for(a_request(:post, endpoint)).not_to have_been_made
87
+ expect(out.string).to match('FATAL -- : bango')
88
+ end
89
+ end
90
+ end
91
+
92
+ describe "#airbrake_level" do
93
+ context "when not set" do
94
+ it "defaults to Logger::WARN" do
95
+ expect(subject.airbrake_level).to eq(Logger::WARN)
96
+ end
97
+ end
98
+
99
+ context "when set" do
100
+ before do
101
+ subject.airbrake_level = Logger::FATAL
102
+ end
103
+
104
+ it "does not notify below the specified level" do
105
+ subject.error('bingo')
106
+ wait_for(a_request(:post, endpoint)).not_to have_been_made
107
+ end
108
+
109
+ it "notifies in the current or above level" do
110
+ subject.fatal('bingo')
111
+ wait_for(a_request(:post, endpoint)).to have_been_made
112
+ end
113
+
114
+ it "raises error when below the allowed level" do
115
+ expect do
116
+ subject.airbrake_level = Logger::DEBUG
117
+ end.to raise_error(/severity level \d is not allowed/)
118
+ end
119
+ end
120
+ end
121
+ end
@@ -137,6 +137,27 @@ RSpec.describe Airbrake::Rack::User do
137
137
  end
138
138
  end
139
139
  end
140
+
141
+ context 'and it is a private method' do
142
+ context "and it is not nil" do
143
+ let(:dummy_controller) do
144
+ Class.new do
145
+ private
146
+
147
+ def current_user
148
+ "username"
149
+ end
150
+ end
151
+ end
152
+
153
+ let(:controller) { dummy_controller.new }
154
+
155
+ it "returns the wrapped user" do
156
+ retval = described_class.extract(env)
157
+ expect(retval).to be_a(described_class)
158
+ end
159
+ end
160
+ end
140
161
  end
141
162
  end
142
163
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: airbrake
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.8.0.rc.2
4
+ version: 5.8.0.rc.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Airbrake Technologies, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-27 00:00:00.000000000 Z
11
+ date: 2017-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: airbrake-ruby
@@ -197,7 +197,7 @@ files:
197
197
  - lib/airbrake.rb
198
198
  - lib/airbrake/capistrano/tasks.rb
199
199
  - lib/airbrake/delayed_job/plugin.rb
200
- - lib/airbrake/logger/logger_ext.rb
200
+ - lib/airbrake/logger/airbrake_logger.rb
201
201
  - lib/airbrake/rack/context_filter.rb
202
202
  - lib/airbrake/rack/http_headers_filter.rb
203
203
  - lib/airbrake/rack/http_params_filter.rb
@@ -235,7 +235,7 @@ files:
235
235
  - spec/integration/sinatra/sinatra_spec.rb
236
236
  - spec/spec_helper.rb
237
237
  - spec/unit/airbrake_spec.rb
238
- - spec/unit/logger/logger_ext_spec.rb
238
+ - spec/unit/logger/airbrake_logger_spec.rb
239
239
  - spec/unit/rack/context_filter_spec.rb
240
240
  - spec/unit/rack/http_headers_filter_spec.rb
241
241
  - spec/unit/rack/http_params_filter_spec.rb
@@ -290,7 +290,7 @@ test_files:
290
290
  - spec/integration/sinatra/sinatra_spec.rb
291
291
  - spec/spec_helper.rb
292
292
  - spec/unit/airbrake_spec.rb
293
- - spec/unit/logger/logger_ext_spec.rb
293
+ - spec/unit/logger/airbrake_logger_spec.rb
294
294
  - spec/unit/rack/context_filter_spec.rb
295
295
  - spec/unit/rack/http_headers_filter_spec.rb
296
296
  - spec/unit/rack/http_params_filter_spec.rb
@@ -1,78 +0,0 @@
1
- ##
2
- # Redefine +Logger+ from stdlib, so it can both log and report errors to
3
- # Airbrake.
4
- #
5
- # @example
6
- # # Create a logger like you normally do.
7
- # logger = Logger.new(STDOUT)
8
- #
9
- # # Assign a default Airbrake notifier
10
- # logger.airbrake_notifier = Airbrake[:default]
11
- #
12
- # # Just use the logger like you normally do.
13
- # logger.fatal('oops')
14
- class Logger
15
- # Store the orginal methods to use them later.
16
- alias add_without_airbrake add
17
- alias initialize_without_airbrake initialize
18
-
19
- ##
20
- # @see https://goo.gl/MvlYq3 Logger#initialize
21
- def initialize(*args)
22
- @airbrake_notifier = Airbrake[:default]
23
- @airbrake_severity_level = WARN
24
- initialize_without_airbrake(*args)
25
- end
26
-
27
- ##
28
- # @return [Airbrake::Notifier] notifier to be used to send notices
29
- attr_accessor :airbrake_notifier
30
-
31
- ##
32
- # @example
33
- # logger.airbrake_severity_level = Logger::FATAL
34
- # @return [Integer]
35
- attr_accessor :airbrake_severity_level
36
-
37
- ##
38
- # @see https://goo.gl/8zPyoM Logger#add
39
- def add(severity, message = nil, progname = nil, &block)
40
- if severity >= airbrake_severity_level && airbrake_notifier
41
- notify_airbrake(severity, message || progname)
42
- end
43
- add_without_airbrake(severity, message, progname, &block)
44
- end
45
-
46
- private
47
-
48
- def notify_airbrake(severity, message)
49
- notice = airbrake_notifier.build_notice(message)
50
-
51
- # Get rid of unwanted internal Logger frames. Examples:
52
- # * /ruby-2.4.0/lib/ruby/2.4.0/logger.rb
53
- # * /gems/activesupport-4.2.7.1/lib/active_support/logger.rb
54
- backtrace = notice[:errors].first[:backtrace]
55
- notice[:errors].first[:backtrace] =
56
- backtrace.drop_while { |frame| frame[:file] =~ %r{/logger.rb\z} }
57
-
58
- notice[:context][:component] = 'log'
59
- notice[:context][:severity] = airbrake_severity(severity)
60
-
61
- airbrake_notifier.notify(notice)
62
- end
63
-
64
- def airbrake_severity(severity)
65
- (case severity
66
- when DEBUG
67
- 'debug'
68
- when INFO
69
- 'info'
70
- when WARN
71
- 'warning'
72
- when ERROR, UNKNOWN
73
- 'error'
74
- when FATAL
75
- 'critical'
76
- end).freeze
77
- end
78
- end
@@ -1,113 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe Logger do
4
- let(:project_id) { 113743 }
5
- let(:project_key) { 'fd04e13d806a90f96614ad8e529b2822' }
6
-
7
- let(:endpoint) do
8
- "https://airbrake.io/api/v3/projects/#{project_id}/notices?key=#{project_key}"
9
- end
10
-
11
- let(:airbrake) do
12
- Airbrake::Notifier.new(project_id: project_id, project_key: project_key)
13
- end
14
-
15
- let(:logger) { Logger.new('/dev/null') }
16
-
17
- def wait_for_a_request_with_body(body)
18
- wait_for(a_request(:post, endpoint).with(body: body)).to have_been_made.once
19
- end
20
-
21
- before do
22
- stub_request(:post, endpoint).to_return(status: 201, body: '{}')
23
- end
24
-
25
- describe "#airbrake" do
26
- it "has the default notifier installed by default" do
27
- expect(logger.airbrake_notifier).to be_an(Airbrake::Notifier)
28
- end
29
-
30
- it "installs Airbrake notifier" do
31
- notifier_id = airbrake.object_id
32
- expect(logger.airbrake_notifier.object_id).not_to eq(notifier_id)
33
-
34
- logger.airbrake_notifier = airbrake
35
- expect(logger.airbrake_notifier.object_id).to eq(notifier_id)
36
- end
37
- end
38
-
39
- context "when Airbrake is installed" do
40
- let(:out) { StringIO.new }
41
- let(:logger) { Logger.new(out) }
42
-
43
- before do
44
- logger.airbrake_notifier = airbrake
45
- end
46
-
47
- it "both logs and notifies" do
48
- msg = 'bingo'
49
- logger.fatal(msg)
50
-
51
- wait_for_a_request_with_body(/"message":"#{msg}"/)
52
- expect(out.string).to match(/FATAL -- : #{msg}/)
53
- end
54
-
55
- it "sets the correct severity" do
56
- logger.fatal('bango')
57
- wait_for_a_request_with_body(/"context":{.*"severity":"critical".*}/)
58
- end
59
-
60
- it "sets the correct component" do
61
- logger.fatal('bingo')
62
- wait_for_a_request_with_body(/"component":"log"/)
63
- end
64
-
65
- it "strips out internal logger frames" do
66
- logger.fatal('bongo')
67
-
68
- wait_for(
69
- a_request(:post, endpoint).
70
- with(body: %r{"file":".+/logger.rb"})
71
- ).not_to have_been_made
72
- wait_for(a_request(:post, endpoint)).to have_been_made.once
73
- end
74
- end
75
-
76
- describe "#airbrake_severity_level" do
77
- context "when not set" do
78
- it "defaults to Logger::WARN" do
79
- expect(logger.airbrake_severity_level).to eq(Logger::WARN)
80
- end
81
- end
82
-
83
- context "when set" do
84
- before do
85
- logger.airbrake_severity_level = Logger::FATAL
86
- end
87
-
88
- it "does not notify below the specified level" do
89
- logger.error('bingo')
90
- wait_for(a_request(:post, endpoint)).not_to have_been_made
91
- end
92
-
93
- it "notifies in the current or above level" do
94
- logger.fatal('bingo')
95
- wait_for(a_request(:post, endpoint)).to have_been_made
96
- end
97
- end
98
- end
99
-
100
- context "when Airbrake is not installed" do
101
- it "only logs, never notifies" do
102
- out = StringIO.new
103
- l = Logger.new(out)
104
- l.airbrake_notifier = nil
105
- msg = 'bango'
106
-
107
- l.fatal(msg)
108
-
109
- wait_for(a_request(:post, endpoint)).not_to have_been_made
110
- expect(out.string).to match('FATAL -- : bango')
111
- end
112
- end
113
- end