airbrake-ruby 4.13.3-java → 5.0.0.rc.1-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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/lib/airbrake-ruby.rb +23 -32
  3. data/lib/airbrake-ruby/async_sender.rb +1 -1
  4. data/lib/airbrake-ruby/config.rb +65 -13
  5. data/lib/airbrake-ruby/config/processor.rb +80 -0
  6. data/lib/airbrake-ruby/config/validator.rb +4 -0
  7. data/lib/airbrake-ruby/filter_chain.rb +15 -1
  8. data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +2 -1
  9. data/lib/airbrake-ruby/filters/{keys_whitelist.rb → keys_allowlist.rb} +3 -3
  10. data/lib/airbrake-ruby/filters/{keys_blacklist.rb → keys_blocklist.rb} +3 -3
  11. data/lib/airbrake-ruby/filters/keys_filter.rb +5 -5
  12. data/lib/airbrake-ruby/notice_notifier.rb +6 -0
  13. data/lib/airbrake-ruby/performance_notifier.rb +1 -1
  14. data/lib/airbrake-ruby/remote_settings.rb +128 -0
  15. data/lib/airbrake-ruby/remote_settings/settings_data.rb +116 -0
  16. data/lib/airbrake-ruby/sync_sender.rb +1 -1
  17. data/lib/airbrake-ruby/thread_pool.rb +1 -0
  18. data/lib/airbrake-ruby/version.rb +1 -1
  19. data/spec/airbrake_spec.rb +71 -36
  20. data/spec/config/processor_spec.rb +223 -0
  21. data/spec/config/validator_spec.rb +18 -1
  22. data/spec/config_spec.rb +38 -6
  23. data/spec/filter_chain_spec.rb +27 -0
  24. data/spec/filters/git_last_checkout_filter_spec.rb +20 -3
  25. data/spec/filters/{keys_whitelist_spec.rb → keys_allowlist_spec.rb} +10 -10
  26. data/spec/filters/{keys_blacklist_spec.rb → keys_blocklist_spec.rb} +10 -10
  27. data/spec/filters/sql_filter_spec.rb +3 -3
  28. data/spec/notice_notifier/options_spec.rb +4 -4
  29. data/spec/performance_notifier_spec.rb +2 -2
  30. data/spec/remote_settings/settings_data_spec.rb +327 -0
  31. data/spec/remote_settings_spec.rb +212 -0
  32. data/spec/sync_sender_spec.rb +3 -1
  33. data/spec/thread_pool_spec.rb +25 -5
  34. metadata +20 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6a2b4edf2ff6ca87fdc92fd067485afa4d01692c33e29c3ea60b0a93d2363f60
4
- data.tar.gz: f2d238127b26e3fdfdc1b7848f847760993a87d15182ec7266e42d7db753609c
3
+ metadata.gz: 6a60c7ee3f35357ecbe72d0bdedb89a61b248101ac58d866166e5daa1e2f79eb
4
+ data.tar.gz: 53a68e1f1bab4158d773593ad201dce948a0df60c0fd1b80a27451a96dc5596c
5
5
  SHA512:
6
- metadata.gz: fcbb40c30a2b67182992498f0582d36210de1798454403145cbf029d1778c7fe34a2426e6caf96678cafa6427bba9fc51cd6cbd96b1bd0c517d0800b07ef387c
7
- data.tar.gz: 845c5c487af401362663273c85d56fb924578332a227ba534ced253d954af17ebdade9c6d5346a8e9640fcb4c8583ad068c8c43d0bc85fa7ec41298aff07c978
6
+ metadata.gz: 8d14d8843ea3d8c8923b654d5c1110fbefb83b40b63a15c930b5243de81f5ecd594d8e08be64a8242884793a6203f535d16088ebbbef3328d519f8cfd440d19e
7
+ data.tar.gz: '08fdf62186815e85696acd66641f60bfeca556c2a3e30c0b7d7c49c3f02bdd208d795aceee9af65a4683773580682f8efa96a61434a716118a8a85346432d41f'
@@ -12,6 +12,9 @@ require 'airbrake-ruby/mergeable'
12
12
  require 'airbrake-ruby/grouppable'
13
13
  require 'airbrake-ruby/config'
14
14
  require 'airbrake-ruby/config/validator'
15
+ require 'airbrake-ruby/config/processor'
16
+ require 'airbrake-ruby/remote_settings/settings_data'
17
+ require 'airbrake-ruby/remote_settings'
15
18
  require 'airbrake-ruby/promise'
16
19
  require 'airbrake-ruby/thread_pool'
17
20
  require 'airbrake-ruby/sync_sender'
@@ -24,8 +27,8 @@ require 'airbrake-ruby/notice'
24
27
  require 'airbrake-ruby/backtrace'
25
28
  require 'airbrake-ruby/truncator'
26
29
  require 'airbrake-ruby/filters/keys_filter'
27
- require 'airbrake-ruby/filters/keys_whitelist'
28
- require 'airbrake-ruby/filters/keys_blacklist'
30
+ require 'airbrake-ruby/filters/keys_allowlist'
31
+ require 'airbrake-ruby/filters/keys_blocklist'
29
32
  require 'airbrake-ruby/filters/gem_root_filter'
30
33
  require 'airbrake-ruby/filters/system_exit_filter'
31
34
  require 'airbrake-ruby/filters/root_directory_filter'
@@ -117,7 +120,15 @@ module Airbrake
117
120
  def configure
118
121
  yield config = Airbrake::Config.instance
119
122
  Airbrake::Loggable.instance = config.logger
120
- process_config_options(config)
123
+
124
+ config_processor = Airbrake::Config::Processor.new(config)
125
+
126
+ config_processor.process_blocklist(notice_notifier)
127
+ config_processor.process_allowlist(notice_notifier)
128
+
129
+ @remote_settings ||= config_processor.process_remote_configuration
130
+
131
+ config_processor.add_filters(notice_notifier)
121
132
  end
122
133
 
123
134
  # @since v4.2.3
@@ -260,8 +271,8 @@ module Airbrake
260
271
  # Airbrake.close
261
272
  # Airbrake.notify('App crashed!') #=> raises Airbrake::Error
262
273
  #
263
- # @return [void]
264
- # rubocop:disable Style/GuardClause, Style/IfUnlessModifier
274
+ # @return [nil]
275
+ # rubocop:disable Style/IfUnlessModifier, Metrics/CyclomaticComplexity
265
276
  def close
266
277
  if defined?(@notice_notifier) && @notice_notifier
267
278
  @notice_notifier.close
@@ -270,8 +281,14 @@ module Airbrake
270
281
  if defined?(@performance_notifier) && @performance_notifier
271
282
  @performance_notifier.close
272
283
  end
284
+
285
+ if defined?(@remote_settings) && @remote_settings
286
+ @remote_settings.stop_polling
287
+ end
288
+
289
+ nil
273
290
  end
274
- # rubocop:enable Style/GuardClause, Style/IfUnlessModifier
291
+ # rubocop:enable Style/IfUnlessModifier, Metrics/CyclomaticComplexity
275
292
 
276
293
  # Pings the Airbrake Deploy API endpoint about the occurred deploy.
277
294
  #
@@ -567,32 +584,6 @@ module Airbrake
567
584
  self.notice_notifier = NoticeNotifier.new
568
585
  self.deploy_notifier = DeployNotifier.new
569
586
  end
570
-
571
- private
572
-
573
- def process_config_options(config)
574
- if config.blacklist_keys.any?
575
- blacklist = Airbrake::Filters::KeysBlacklist.new(config.blacklist_keys)
576
- notice_notifier.add_filter(blacklist)
577
- end
578
-
579
- if config.whitelist_keys.any?
580
- whitelist = Airbrake::Filters::KeysWhitelist.new(config.whitelist_keys)
581
- notice_notifier.add_filter(whitelist)
582
- end
583
-
584
- return if configured?
585
- return unless config.root_directory
586
-
587
- [
588
- Airbrake::Filters::RootDirectoryFilter,
589
- Airbrake::Filters::GitRevisionFilter,
590
- Airbrake::Filters::GitRepositoryFilter,
591
- Airbrake::Filters::GitLastCheckoutFilter,
592
- ].each do |filter|
593
- notice_notifier.add_filter(filter.new(config.root_directory))
594
- end
595
- end
596
587
  end
597
588
  end
598
589
  # rubocop:enable Metrics/ModuleLength
@@ -16,7 +16,7 @@ module Airbrake
16
16
  #
17
17
  # @param [Hash] payload Whatever needs to be sent
18
18
  # @return [Airbrake::Promise]
19
- def send(payload, promise, endpoint = @config.endpoint)
19
+ def send(payload, promise, endpoint = @config.error_endpoint)
20
20
  unless thread_pool << [payload, promise, endpoint]
21
21
  return promise.reject(
22
22
  "AsyncSender has reached its capacity of #{@config.queue_size}",
@@ -4,6 +4,7 @@ module Airbrake
4
4
  #
5
5
  # @api public
6
6
  # @since v1.0.0
7
+ # rubocop:disable Metrics/ClassLength
7
8
  class Config
8
9
  # @return [Integer] the project identificator. This value *must* be set.
9
10
  # @api public
@@ -46,6 +47,17 @@ module Airbrake
46
47
  # @api public
47
48
  attr_accessor :host
48
49
 
50
+ # @since v?.?.?
51
+ alias error_host host
52
+ # @since v?.?.?
53
+ alias error_host= host=
54
+
55
+ # @return [String] the host, which provides the API endpoint to which
56
+ # APM data should be sent
57
+ # @api public
58
+ # @since v?.?.?
59
+ attr_accessor :apm_host
60
+
49
61
  # @return [String, Pathname] the working directory of your project
50
62
  # @api public
51
63
  attr_accessor :root_directory
@@ -68,14 +80,20 @@ module Airbrake
68
80
  # @return [Array<String, Symbol, Regexp>] the keys, which should be
69
81
  # filtered
70
82
  # @api public
71
- # @since v1.2.0
72
- attr_accessor :blacklist_keys
83
+ # @since v4.15.0
84
+ attr_accessor :allowlist_keys
85
+
86
+ # @deprecated Use allowlist_keys instead
87
+ alias whitelist_keys allowlist_keys
73
88
 
74
- # @return [Array<String, Symbol, Regexp>] the keys, which shouldn't be
89
+ # @return [Array<String, Symbol, Regexp>] the keys, which should be
75
90
  # filtered
76
91
  # @api public
77
- # @since v1.2.0
78
- attr_accessor :whitelist_keys
92
+ # @since v4.15.0
93
+ attr_accessor :blocklist_keys
94
+
95
+ # @deprecated Use blocklist_keys instead
96
+ alias blacklist_keys blocklist_keys
79
97
 
80
98
  # @return [Boolean] true if the library should attach code hunks to each
81
99
  # frame in a backtrace, false otherwise
@@ -107,6 +125,18 @@ module Airbrake
107
125
  # @since v4.12.0
108
126
  attr_accessor :job_stats
109
127
 
128
+ # @return [Boolean] true if the library should send error reports to
129
+ # Airbrake, false otherwise
130
+ # @api public
131
+ # @since ?.?.?
132
+ attr_accessor :error_notifications
133
+
134
+ # @note Not for public use!
135
+ # @return [Boolean]
136
+ # @api private
137
+ # @since ?.?.?
138
+ attr_accessor :__remote_configuration
139
+
110
140
  class << self
111
141
  # @return [Config]
112
142
  attr_writer :instance
@@ -128,14 +158,15 @@ module Airbrake
128
158
  self.logger = ::Logger.new(File::NULL).tap { |l| l.level = Logger::WARN }
129
159
  self.project_id = user_config[:project_id]
130
160
  self.project_key = user_config[:project_key]
131
- self.host = 'https://api.airbrake.io'
161
+ self.error_host = 'https://api.airbrake.io'
162
+ self.apm_host = 'https://api.airbrake.io'
132
163
 
133
164
  self.ignore_environments = []
134
165
 
135
166
  self.timeout = user_config[:timeout]
136
167
 
137
- self.blacklist_keys = []
138
- self.whitelist_keys = []
168
+ self.blocklist_keys = []
169
+ self.allowlist_keys = []
139
170
 
140
171
  self.root_directory = File.realpath(
141
172
  (defined?(Bundler) && Bundler.root) ||
@@ -147,19 +178,39 @@ module Airbrake
147
178
  self.performance_stats_flush_period = 15
148
179
  self.query_stats = true
149
180
  self.job_stats = true
181
+ self.error_notifications = true
182
+ self.__remote_configuration = false
150
183
 
151
184
  merge(user_config)
152
185
  end
153
186
  # rubocop:enable Metrics/AbcSize
154
187
 
155
- # The full URL to the Airbrake Notice API. Based on the +:host+ option.
188
+ def blacklist_keys=(keys)
189
+ loc = caller_locations(1..1).first
190
+ Kernel.warn(
191
+ "#{loc.path}:#{loc.lineno}: warning: blacklist_keys= is deprecated " \
192
+ "use blocklist_keys= instead",
193
+ )
194
+ self.blocklist_keys = keys
195
+ end
196
+
197
+ def whitelist_keys=(keys)
198
+ loc = caller_locations(1..1).first
199
+ Kernel.warn(
200
+ "#{loc.path}:#{loc.lineno}: warning: whitelist_keys= is deprecated " \
201
+ "use allowlist_keys= instead",
202
+ )
203
+ self.allowlist_keys = keys
204
+ end
205
+
206
+ # The full URL to the Airbrake Notice API. Based on the +:error_host+ option.
156
207
  # @return [URI] the endpoint address
157
- def endpoint
158
- @endpoint ||=
208
+ def error_endpoint
209
+ @error_endpoint ||=
159
210
  begin
160
- self.host = ('https://' << host) if host !~ %r{\Ahttps?://}
211
+ self.error_host = ('https://' << error_host) if error_host !~ %r{\Ahttps?://}
161
212
  api = "api/v3/projects/#{project_id}/notices"
162
- URI.join(host, api)
213
+ URI.join(error_host, api)
163
214
  end
164
215
  end
165
216
 
@@ -237,4 +288,5 @@ module Airbrake
237
288
  raise Airbrake::Error, "unknown option '#{option}'"
238
289
  end
239
290
  end
291
+ # rubocop:enable Metrics/ClassLength
240
292
  end
@@ -0,0 +1,80 @@
1
+ module Airbrake
2
+ class Config
3
+ # Processor is a helper class, which is responsible for setting default
4
+ # config values, default notifier filters and remote configuration changes.
5
+ #
6
+ # @since v?.?.?
7
+ # @api private
8
+ class Processor
9
+ # @param [Airbrake::Config] config
10
+ # @return [Airbrake::Config::Processor]
11
+ def self.process(config)
12
+ new(config).process
13
+ end
14
+
15
+ # @param [Airbrake::Config] config
16
+ def initialize(config)
17
+ @config = config
18
+ @blocklist_keys = @config.blocklist_keys
19
+ @allowlist_keys = @config.allowlist_keys
20
+ @project_id = @config.project_id
21
+ end
22
+
23
+ # @param [Airbrake::NoticeNotifier] notifier
24
+ # @return [void]
25
+ def process_blocklist(notifier)
26
+ return if @blocklist_keys.none?
27
+
28
+ blocklist = Airbrake::Filters::KeysBlocklist.new(@blocklist_keys)
29
+ notifier.add_filter(blocklist)
30
+ end
31
+
32
+ # @param [Airbrake::NoticeNotifier] notifier
33
+ # @return [void]
34
+ def process_allowlist(notifier)
35
+ return if @allowlist_keys.none?
36
+
37
+ allowlist = Airbrake::Filters::KeysAllowlist.new(@allowlist_keys)
38
+ notifier.add_filter(allowlist)
39
+ end
40
+
41
+ # @return [Airbrake::RemoteSettings]
42
+ def process_remote_configuration
43
+ return if !@project_id || !@config.__remote_configuration
44
+
45
+ RemoteSettings.poll(@project_id, &method(:poll_callback))
46
+ end
47
+
48
+ # @param [Airbrake::NoticeNotifier] notifier
49
+ # @return [void]
50
+ def add_filters(notifier)
51
+ return unless @config.root_directory
52
+
53
+ [
54
+ Airbrake::Filters::RootDirectoryFilter,
55
+ Airbrake::Filters::GitRevisionFilter,
56
+ Airbrake::Filters::GitRepositoryFilter,
57
+ Airbrake::Filters::GitLastCheckoutFilter,
58
+ ].each do |filter|
59
+ next if notifier.has_filter?(filter)
60
+
61
+ notifier.add_filter(filter.new(@config.root_directory))
62
+ end
63
+ end
64
+
65
+ # @param [Airbrake::RemoteSettings::SettingsData] data
66
+ # @return [void]
67
+ def poll_callback(data)
68
+ @config.logger.debug(
69
+ "#{LOG_LABEL} applying remote settings: #{data.to_h}",
70
+ )
71
+
72
+ @config.error_host = data.error_host if data.error_host
73
+ @config.apm_host = data.apm_host if data.apm_host
74
+
75
+ @config.error_notifications = data.error_notifications?
76
+ @config.performance_stats = data.performance_stats?
77
+ end
78
+ end
79
+ end
80
+ end
@@ -44,6 +44,10 @@ module Airbrake
44
44
  def check_notify_ability(config)
45
45
  promise = Airbrake::Promise.new
46
46
 
47
+ unless config.error_notifications
48
+ return promise.reject('error notifications are disabled')
49
+ end
50
+
47
51
  if ignored_environment?(config)
48
52
  return promise.reject(
49
53
  "current environment '#{config.environment}' is ignored",
@@ -76,7 +76,7 @@ module Airbrake
76
76
 
77
77
  # @return [String] customized inspect to lessen the amount of clutter
78
78
  def inspect
79
- @filters.map(&:class).to_s
79
+ filter_classes.to_s
80
80
  end
81
81
 
82
82
  # @return [String] {#inspect} for PrettyPrint
@@ -91,5 +91,19 @@ module Airbrake
91
91
  end
92
92
  q.text(']')
93
93
  end
94
+
95
+ # @param [Class] filter_class
96
+ # @return [Boolean] true if the current chain has an instance of the given
97
+ # class, false otherwise
98
+ # @since v4.14.0
99
+ def includes?(filter_class)
100
+ filter_classes.include?(filter_class)
101
+ end
102
+
103
+ private
104
+
105
+ def filter_classes
106
+ @filters.map(&:class)
107
+ end
94
108
  end
95
109
  end
@@ -27,6 +27,7 @@ module Airbrake
27
27
  @git_path = File.join(root_directory, '.git')
28
28
  @weight = 116
29
29
  @last_checkout = nil
30
+ @deploy_username = ENV['AIRBRAKE_DEPLOY_USERNAME']
30
31
  end
31
32
 
32
33
  # @macro call_filter
@@ -59,7 +60,7 @@ module Airbrake
59
60
 
60
61
  author = parts[2..-4]
61
62
  @last_checkout = {
62
- username: author[0..1].join(' '),
63
+ username: @deploy_username || author[0..1].join(' '),
63
64
  email: parts[-3][1..-2],
64
65
  revision: parts[1],
65
66
  time: timestamp(parts[-2].to_i),
@@ -4,7 +4,7 @@ module Airbrake
4
4
  # notice, but specified keys.
5
5
  #
6
6
  # @example
7
- # filter = Airbrake::Filters::KeysBlacklist.new(
7
+ # filter = Airbrake::Filters::KeysAllowlist.new(
8
8
  # [:email, /credit/i, 'password']
9
9
  # )
10
10
  # airbrake.add_filter(filter)
@@ -22,9 +22,9 @@ module Airbrake
22
22
  # # email: 'john@example.com',
23
23
  # # account_id: 42 }
24
24
  #
25
- # @see KeysBlacklist
25
+ # @see KeysBlocklist
26
26
  # @see KeysFilter
27
- class KeysWhitelist
27
+ class KeysAllowlist
28
28
  include KeysFilter
29
29
 
30
30
  def initialize(*)
@@ -4,7 +4,7 @@ module Airbrake
4
4
  # list of parameters in the payload of a notice.
5
5
  #
6
6
  # @example
7
- # filter = Airbrake::Filters::KeysBlacklist.new(
7
+ # filter = Airbrake::Filters::KeysBlocklist.new(
8
8
  # [:email, /credit/i, 'password']
9
9
  # )
10
10
  # airbrake.add_filter(filter)
@@ -22,10 +22,10 @@ module Airbrake
22
22
  # # email: '[Filtered]',
23
23
  # # credit_card: '[Filtered]' }
24
24
  #
25
- # @see KeysWhitelist
25
+ # @see KeysAllowlist
26
26
  # @see KeysFilter
27
27
  # @api private
28
- class KeysBlacklist
28
+ class KeysBlocklist
29
29
  include KeysFilter
30
30
 
31
31
  def initialize(*)
@@ -7,8 +7,8 @@ module Airbrake
7
7
  # class that includes this module must implement.
8
8
  #
9
9
  # @see Notice
10
- # @see KeysWhitelist
11
- # @see KeysBlacklist
10
+ # @see KeysAllowlist
11
+ # @see KeysBlocklist
12
12
  # @api private
13
13
  module KeysFilter
14
14
  # @return [String] The label to replace real values of filtered payload
@@ -19,11 +19,11 @@ module Airbrake
19
19
  VALID_PATTERN_CLASSES = [String, Symbol, Regexp].freeze
20
20
 
21
21
  # @return [Array<Symbol>] parts of a Notice's payload that can be modified
22
- # by blacklist/whitelist filters
22
+ # by blocklist/allowlist filters
23
23
  FILTERABLE_KEYS = %i[environment session params].freeze
24
24
 
25
25
  # @return [Array<Symbol>] parts of a Notice's *context* payload that can
26
- # be modified by blacklist/whitelist filters
26
+ # be modified by blocklist/allowlist filters
27
27
  FILTERABLE_CONTEXT_KEYS = %i[
28
28
  user
29
29
 
@@ -42,7 +42,7 @@ module Airbrake
42
42
  # @return [Integer]
43
43
  attr_reader :weight
44
44
 
45
- # Creates a new KeysBlacklist or KeysWhitelist filter that uses the given
45
+ # Creates a new KeysBlocklist or KeysAllowlist filter that uses the given
46
46
  # +patterns+ for filtering a notice's payload.
47
47
  #
48
48
  # @param [Array<String,Regexp,Symbol>] patterns