airbrake-ruby 3.2.6-java → 4.0.0-java

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/lib/airbrake-ruby.rb +31 -138
  3. data/lib/airbrake-ruby/async_sender.rb +20 -8
  4. data/lib/airbrake-ruby/backtrace.rb +15 -13
  5. data/lib/airbrake-ruby/code_hunk.rb +2 -4
  6. data/lib/airbrake-ruby/config.rb +8 -38
  7. data/lib/airbrake-ruby/deploy_notifier.rb +4 -17
  8. data/lib/airbrake-ruby/filters/exception_attributes_filter.rb +5 -4
  9. data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +6 -4
  10. data/lib/airbrake-ruby/filters/keys_blacklist.rb +0 -1
  11. data/lib/airbrake-ruby/filters/keys_filter.rb +4 -4
  12. data/lib/airbrake-ruby/filters/keys_whitelist.rb +0 -1
  13. data/lib/airbrake-ruby/loggable.rb +31 -0
  14. data/lib/airbrake-ruby/nested_exception.rb +2 -3
  15. data/lib/airbrake-ruby/notice.rb +6 -6
  16. data/lib/airbrake-ruby/notice_notifier.rb +11 -47
  17. data/lib/airbrake-ruby/performance_notifier.rb +6 -18
  18. data/lib/airbrake-ruby/response.rb +5 -2
  19. data/lib/airbrake-ruby/sync_sender.rb +8 -6
  20. data/lib/airbrake-ruby/version.rb +1 -1
  21. data/spec/airbrake_spec.rb +1 -143
  22. data/spec/async_sender_spec.rb +83 -90
  23. data/spec/backtrace_spec.rb +36 -47
  24. data/spec/code_hunk_spec.rb +12 -15
  25. data/spec/config_spec.rb +79 -96
  26. data/spec/deploy_notifier_spec.rb +3 -7
  27. data/spec/filter_chain_spec.rb +1 -3
  28. data/spec/filters/context_filter_spec.rb +1 -3
  29. data/spec/filters/dependency_filter_spec.rb +1 -3
  30. data/spec/filters/exception_attributes_filter_spec.rb +1 -14
  31. data/spec/filters/gem_root_filter_spec.rb +1 -4
  32. data/spec/filters/git_last_checkout_filter_spec.rb +3 -5
  33. data/spec/filters/git_revision_filter_spec.rb +1 -3
  34. data/spec/filters/keys_blacklist_spec.rb +14 -25
  35. data/spec/filters/keys_whitelist_spec.rb +14 -25
  36. data/spec/filters/root_directory_filter_spec.rb +1 -4
  37. data/spec/filters/system_exit_filter_spec.rb +2 -2
  38. data/spec/filters/thread_filter_spec.rb +1 -3
  39. data/spec/nested_exception_spec.rb +3 -5
  40. data/spec/notice_notifier_spec.rb +23 -20
  41. data/spec/notice_notifier_spec/options_spec.rb +20 -25
  42. data/spec/notice_spec.rb +13 -12
  43. data/spec/performance_notifier_spec.rb +19 -31
  44. data/spec/response_spec.rb +23 -17
  45. data/spec/sync_sender_spec.rb +26 -33
  46. metadata +2 -1
@@ -9,9 +9,7 @@ module Airbrake
9
9
  # @return [Integer] how many lines should be read around the base line
10
10
  NLINES = 2
11
11
 
12
- def initialize(config)
13
- @config = config
14
- end
12
+ include Loggable
15
13
 
16
14
  # @param [String] file The file to read
17
15
  # @param [Integer] line The base line in the file
@@ -31,7 +29,7 @@ module Airbrake
31
29
  def get_from_cache(file)
32
30
  Airbrake::FileCache[file] ||= File.foreach(file)
33
31
  rescue StandardError => ex
34
- @config.logger.error(
32
+ logger.error(
35
33
  "#{self.class.name}: can't read code hunk for #{file}: #{ex}"
36
34
  )
37
35
  nil
@@ -5,6 +5,13 @@ module Airbrake
5
5
  # @api public
6
6
  # @since v1.0.0
7
7
  class Config
8
+ @instance = new
9
+
10
+ class << self
11
+ # @return [Config]
12
+ attr_accessor :instance
13
+ end
14
+
8
15
  # @return [Integer] the project identificator. This value *must* be set.
9
16
  # @api public
10
17
  attr_accessor :project_id
@@ -97,7 +104,6 @@ module Airbrake
97
104
 
98
105
  # @param [Hash{Symbol=>Object}] user_config the hash to be used to build the
99
106
  # config
100
- # rubocop:disable Metrics/AbcSize
101
107
  def initialize(user_config = {})
102
108
  @validator = Config::Validator.new(self)
103
109
 
@@ -105,10 +111,7 @@ module Airbrake
105
111
  self.queue_size = 100
106
112
  self.workers = 1
107
113
  self.code_hunks = true
108
-
109
- self.logger = Logger.new(STDOUT)
110
- logger.level = Logger::WARN
111
-
114
+ self.logger = ::Logger.new(File::NULL)
112
115
  self.project_id = user_config[:project_id]
113
116
  self.project_key = user_config[:project_key]
114
117
  self.host = 'https://api.airbrake.io'
@@ -131,7 +134,6 @@ module Airbrake
131
134
 
132
135
  merge(user_config)
133
136
  end
134
- # rubocop:enable Metrics/AbcSize
135
137
 
136
138
  # The full URL to the Airbrake Notice API. Based on the +:host+ option.
137
139
  # @return [URI] the endpoint address
@@ -195,38 +197,6 @@ module Airbrake
195
197
  end
196
198
  end
197
199
 
198
- def route_stats
199
- logger.warn(
200
- "#{LOG_LABEL} the 'route_stats' option is deprecated. " \
201
- "Use 'performance_stats' instead"
202
- )
203
- @performance_stats
204
- end
205
-
206
- def route_stats=(value)
207
- logger.warn(
208
- "#{LOG_LABEL} the 'route_stats' option is deprecated. " \
209
- "Use 'performance_stats' instead"
210
- )
211
- @performance_stats = value
212
- end
213
-
214
- def route_stats_flush_period
215
- logger.warn(
216
- "#{LOG_LABEL} the 'route_stats_flush_period' option is deprecated. " \
217
- "Use 'performance_stats_flush_period' instead"
218
- )
219
- @performance_stats_flush_period
220
- end
221
-
222
- def route_stats_flush_period=(value)
223
- logger.warn(
224
- "#{LOG_LABEL} the 'route_stats_flush_period' option is deprecated. " \
225
- "Use 'performance_stats' instead"
226
- )
227
- @performance_stats_flush_period = value
228
- end
229
-
230
200
  private
231
201
 
232
202
  def set_option(option, value)
@@ -12,25 +12,12 @@ module Airbrake
12
12
  class DeployNotifier
13
13
  include Inspectable
14
14
 
15
- # @param [Airbrake::Config] config
16
- def initialize(config)
17
- @config =
18
- if config.is_a?(Config)
19
- config
20
- else
21
- loc = caller_locations(1..1).first
22
- signature = "#{self.class.name}##{__method__}"
23
- warn(
24
- "#{loc.path}:#{loc.lineno}: warning: passing a Hash to #{signature} " \
25
- 'is deprecated. Pass `Airbrake::Config` instead'
26
- )
27
- Config.new(config)
28
- end
29
-
30
- @sender = SyncSender.new(@config)
15
+ def initialize
16
+ @config = Airbrake::Config.instance
17
+ @sender = SyncSender.new
31
18
  end
32
19
 
33
- # @see Airbrake.create_deploy
20
+ # @see Airbrake.notify_deploy
34
21
  def notify(deploy_info, promise = Airbrake::Promise.new)
35
22
  if @config.ignored_environment?
36
23
  return promise.reject("The '#{@config.environment}' environment is ignored")
@@ -6,8 +6,9 @@ module Airbrake
6
6
  # @api private
7
7
  # @since v2.10.0
8
8
  class ExceptionAttributesFilter
9
- def initialize(logger)
10
- @logger = logger
9
+ include Loggable
10
+
11
+ def initialize
11
12
  @weight = 118
12
13
  end
13
14
 
@@ -20,13 +21,13 @@ module Airbrake
20
21
  begin
21
22
  attributes = exception.to_airbrake
22
23
  rescue StandardError => ex
23
- @logger.error(
24
+ logger.error(
24
25
  "#{LOG_LABEL} #{exception.class}#to_airbrake failed. #{ex.class}: #{ex}"
25
26
  )
26
27
  end
27
28
 
28
29
  unless attributes.is_a?(Hash)
29
- @logger.error(
30
+ logger.error(
30
31
  "#{LOG_LABEL} #{self.class}: wanted Hash, got #{attributes.class}"
31
32
  )
32
33
  return
@@ -20,11 +20,11 @@ module Airbrake
20
20
  # file (checkout information is omitted)
21
21
  MIN_HEAD_COLS = 6
22
22
 
23
- # @param [Logger] logger
23
+ include Loggable
24
+
24
25
  # @param [String] root_directory
25
- def initialize(logger, root_directory)
26
+ def initialize(root_directory)
26
27
  @git_path = File.join(root_directory, '.git')
27
- @logger = logger
28
28
  @weight = 116
29
29
  @last_checkout = nil
30
30
  end
@@ -45,12 +45,13 @@ module Airbrake
45
45
 
46
46
  private
47
47
 
48
+ # rubocop:disable Metrics/AbcSize
48
49
  def last_checkout
49
50
  return unless (line = last_checkout_line)
50
51
 
51
52
  parts = line.chomp.split("\t").first.split(' ')
52
53
  if parts.size < MIN_HEAD_COLS
53
- @logger.error(
54
+ logger.error(
54
55
  "#{LOG_LABEL} Airbrake::#{self.class.name}: can't parse line: #{line}"
55
56
  )
56
57
  return
@@ -64,6 +65,7 @@ module Airbrake
64
65
  time: timestamp(parts[-2].to_i)
65
66
  }
66
67
  end
68
+ # rubocop:enable Metrics/AbcSize
67
69
 
68
70
  def last_checkout_line
69
71
  head_path = File.join(@git_path, 'logs', 'HEAD')
@@ -5,7 +5,6 @@ module Airbrake
5
5
  #
6
6
  # @example
7
7
  # filter = Airbrake::Filters::KeysBlacklist.new(
8
- # Logger.new(STDOUT),
9
8
  # [:email, /credit/i, 'password']
10
9
  # )
11
10
  # airbrake.add_filter(filter)
@@ -26,16 +26,16 @@ module Airbrake
26
26
  # be modified by blacklist/whitelist filters
27
27
  FILTERABLE_CONTEXT_KEYS = %i[user headers].freeze
28
28
 
29
+ include Loggable
30
+
29
31
  # @return [Integer]
30
32
  attr_reader :weight
31
33
 
32
34
  # Creates a new KeysBlacklist or KeysWhitelist filter that uses the given
33
35
  # +patterns+ for filtering a notice's payload.
34
36
  #
35
- # @param [Logger, #error] logger
36
37
  # @param [Array<String,Regexp,Symbol>] patterns
37
- def initialize(logger, patterns)
38
- @logger = logger
38
+ def initialize(patterns)
39
39
  @patterns = patterns
40
40
  @valid_patterns = false
41
41
  end
@@ -122,7 +122,7 @@ module Airbrake
122
122
 
123
123
  return if @valid_patterns
124
124
 
125
- @logger.error(
125
+ logger.error(
126
126
  "#{LOG_LABEL} one of the patterns in #{self.class} is invalid. " \
127
127
  "Known patterns: #{@patterns}"
128
128
  )
@@ -5,7 +5,6 @@ module Airbrake
5
5
  #
6
6
  # @example
7
7
  # filter = Airbrake::Filters::KeysBlacklist.new(
8
- # Logger.new(STDOUT),
9
8
  # [:email, /credit/i, 'password']
10
9
  # )
11
10
  # airbrake.add_filter(filter)
@@ -0,0 +1,31 @@
1
+ module Airbrake
2
+ # Loggable is included into any class that wants to be able to log.
3
+ #
4
+ # By default, Loggable defines a null logger that doesn't do anything. You are
5
+ # supposed to overwrite it via the {instance} method before calling {logger}.
6
+ #
7
+ # @example
8
+ # class A
9
+ # include Loggable
10
+ #
11
+ # def initialize
12
+ # logger.debug('Initialized A')
13
+ # end
14
+ # end
15
+ #
16
+ # @since v4.0.0
17
+ # @api private
18
+ module Loggable
19
+ @instance = ::Logger.new(File::NULL)
20
+
21
+ class << self
22
+ # @return [Logger]
23
+ attr_accessor :instance
24
+ end
25
+
26
+ # @return [Logger] standard Ruby logger object
27
+ def logger
28
+ Loggable.instance
29
+ end
30
+ end
31
+ end
@@ -9,8 +9,7 @@ module Airbrake
9
9
  # can unwrap. Exceptions that have a longer cause chain will be ignored
10
10
  MAX_NESTED_EXCEPTIONS = 3
11
11
 
12
- def initialize(config, exception)
13
- @config = config
12
+ def initialize(exception)
14
13
  @exception = exception
15
14
  end
16
15
 
@@ -18,7 +17,7 @@ module Airbrake
18
17
  unwind_exceptions.map do |exception|
19
18
  { type: exception.class.name,
20
19
  message: exception.message,
21
- backtrace: Backtrace.parse(@config, exception) }
20
+ backtrace: Backtrace.parse(exception) }
22
21
  end
23
22
  end
24
23
 
@@ -50,6 +50,7 @@ module Airbrake
50
50
  DEFAULT_SEVERITY = 'error'.freeze
51
51
 
52
52
  include Ignorable
53
+ include Loggable
53
54
 
54
55
  # @since v1.7.0
55
56
  # @return [Hash{Symbol=>Object}] the hash with arbitrary objects to be used
@@ -57,11 +58,10 @@ module Airbrake
57
58
  attr_reader :stash
58
59
 
59
60
  # @api private
60
- def initialize(config, exception, params = {})
61
- @config = config
62
-
61
+ def initialize(exception, params = {})
62
+ @config = Airbrake::Config.instance
63
63
  @payload = {
64
- errors: NestedException.new(config, exception).as_json,
64
+ errors: NestedException.new(exception).as_json,
65
65
  context: context,
66
66
  environment: {
67
67
  program_name: $PROGRAM_NAME
@@ -84,7 +84,7 @@ module Airbrake
84
84
  begin
85
85
  json = @payload.to_json
86
86
  rescue *JSON_EXCEPTIONS => ex
87
- @config.logger.debug("#{LOG_LABEL} `notice.to_json` failed: #{ex.class}: #{ex}")
87
+ logger.debug("#{LOG_LABEL} `notice.to_json` failed: #{ex.class}: #{ex}")
88
88
  else
89
89
  return json if json && json.bytesize <= MAX_NOTICE_SIZE
90
90
  end
@@ -152,7 +152,7 @@ module Airbrake
152
152
 
153
153
  new_max_size = @truncator.reduce_max_size
154
154
  if new_max_size == 0
155
- @config.logger.error(
155
+ logger.error(
156
156
  "#{LOG_LABEL} truncation failed. File an issue at " \
157
157
  "https://github.com/airbrake/airbrake-ruby " \
158
158
  "and attach the following payload: #{@payload}"
@@ -5,7 +5,6 @@ module Airbrake
5
5
  # @see Airbrake::Config The list of options
6
6
  # @since v1.0.0
7
7
  # @api public
8
- # rubocop:disable Metrics/ClassLength
9
8
  class NoticeNotifier
10
9
  # @return [Array<Class>] filters to be executed first
11
10
  DEFAULT_FILTERS = [
@@ -17,35 +16,14 @@ module Airbrake
17
16
  ].freeze
18
17
 
19
18
  include Inspectable
19
+ include Loggable
20
20
 
21
- # Creates a new notice notifier with the given config options.
22
- #
23
- # @example
24
- # config = Airbrake::Config.new
25
- # config.project_id = 123
26
- # config.project_key = '321'
27
- # notice_notifier = Airbrake::NoticeNotifier.new(config)
28
- #
29
- # @param [Airbrake::Config] config
30
- def initialize(config, perf_notifier = nil)
31
- @config =
32
- if config.is_a?(Config)
33
- config
34
- else
35
- loc = caller_locations(1..1).first
36
- signature = "#{self.class.name}##{__method__}"
37
- warn(
38
- "#{loc.path}:#{loc.lineno}: warning: passing a Hash to #{signature} " \
39
- 'is deprecated. Pass `Airbrake::Config` instead'
40
- )
41
- Config.new(config)
42
- end
43
-
21
+ def initialize
22
+ @config = Airbrake::Config.instance
44
23
  @context = {}
45
24
  @filter_chain = FilterChain.new
46
- @async_sender = AsyncSender.new(@config)
47
- @sync_sender = SyncSender.new(@config)
48
- @perf_notifier = perf_notifier
25
+ @async_sender = AsyncSender.new
26
+ @sync_sender = SyncSender.new
49
27
 
50
28
  add_default_filters
51
29
  end
@@ -60,15 +38,6 @@ module Airbrake
60
38
  send_notice(exception, params, @sync_sender, &block).value
61
39
  end
62
40
 
63
- # @deprecated Update the airbrake gem to v8.1.0 or higher
64
- def notify_request(request_info, promise = Promise.new)
65
- @config.logger.info(
66
- "#{LOG_LABEL} #{self.class}##{__method__} is deprecated. Update " \
67
- 'the airbrake gem to v8.1.0 or higher'
68
- )
69
- @perf_notifier.notify(Request.new(request_info), promise)
70
- end
71
-
72
41
  # @macro see_public_api_method
73
42
  def add_filter(filter = nil, &block)
74
43
  @filter_chain.add_filter(block_given? ? block : filter)
@@ -90,7 +59,7 @@ module Airbrake
90
59
  exception[:params].merge!(params)
91
60
  exception
92
61
  else
93
- Notice.new(@config, convert_to_exception(exception), params.dup)
62
+ Notice.new(convert_to_exception(exception), params.dup)
94
63
  end
95
64
  end
96
65
 
@@ -143,7 +112,7 @@ module Airbrake
143
112
  def default_sender
144
113
  return @async_sender if @async_sender.has_workers?
145
114
 
146
- @config.logger.warn(
115
+ logger.warn(
147
116
  "#{LOG_LABEL} falling back to sync delivery because there are no " \
148
117
  "running async workers"
149
118
  )
@@ -165,19 +134,15 @@ module Airbrake
165
134
  DEFAULT_FILTERS.each { |f| add_filter(f.new) }
166
135
 
167
136
  if (whitelist_keys = @config.whitelist_keys).any?
168
- add_filter(
169
- Airbrake::Filters::KeysWhitelist.new(@config.logger, whitelist_keys)
170
- )
137
+ add_filter(Airbrake::Filters::KeysWhitelist.new(whitelist_keys))
171
138
  end
172
139
 
173
140
  if (blacklist_keys = @config.blacklist_keys).any?
174
- add_filter(
175
- Airbrake::Filters::KeysBlacklist.new(@config.logger, blacklist_keys)
176
- )
141
+ add_filter(Airbrake::Filters::KeysBlacklist.new(blacklist_keys))
177
142
  end
178
143
 
179
144
  add_filter(Airbrake::Filters::ContextFilter.new(@context))
180
- add_filter(Airbrake::Filters::ExceptionAttributesFilter.new(@config.logger))
145
+ add_filter(Airbrake::Filters::ExceptionAttributesFilter.new)
181
146
 
182
147
  return unless (root_directory = @config.root_directory)
183
148
  [
@@ -189,10 +154,9 @@ module Airbrake
189
154
  end
190
155
 
191
156
  add_filter(
192
- Airbrake::Filters::GitLastCheckoutFilter.new(@config.logger, root_directory)
157
+ Airbrake::Filters::GitLastCheckoutFilter.new(root_directory)
193
158
  )
194
159
  end
195
160
  # rubocop:enable Metrics/AbcSize
196
161
  end
197
- # rubocop:enable Metrics/ClassLength
198
162
  end