airbrake-ruby 4.13.3-java → 5.0.0.rc.1-java

Sign up to get free protection for your applications and to get access to all the features.
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