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

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