airbrake-ruby 5.0.0.rc.2-java → 5.2.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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/lib/airbrake-ruby.rb +1 -0
  3. data/lib/airbrake-ruby/backtrace.rb +6 -5
  4. data/lib/airbrake-ruby/config.rb +19 -38
  5. data/lib/airbrake-ruby/config/processor.rb +8 -17
  6. data/lib/airbrake-ruby/config/validator.rb +2 -0
  7. data/lib/airbrake-ruby/file_cache.rb +1 -1
  8. data/lib/airbrake-ruby/filter_chain.rb +1 -0
  9. data/lib/airbrake-ruby/filters/dependency_filter.rb +1 -0
  10. data/lib/airbrake-ruby/filters/gem_root_filter.rb +1 -0
  11. data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +1 -2
  12. data/lib/airbrake-ruby/filters/git_repository_filter.rb +3 -0
  13. data/lib/airbrake-ruby/filters/git_revision_filter.rb +2 -0
  14. data/lib/airbrake-ruby/filters/keys_filter.rb +21 -13
  15. data/lib/airbrake-ruby/filters/root_directory_filter.rb +1 -0
  16. data/lib/airbrake-ruby/filters/sql_filter.rb +4 -4
  17. data/lib/airbrake-ruby/filters/system_exit_filter.rb +1 -0
  18. data/lib/airbrake-ruby/filters/thread_filter.rb +3 -2
  19. data/lib/airbrake-ruby/grouppable.rb +1 -1
  20. data/lib/airbrake-ruby/ignorable.rb +1 -0
  21. data/lib/airbrake-ruby/mergeable.rb +1 -1
  22. data/lib/airbrake-ruby/notice_notifier.rb +1 -0
  23. data/lib/airbrake-ruby/performance_breakdown.rb +1 -6
  24. data/lib/airbrake-ruby/performance_notifier.rb +1 -14
  25. data/lib/airbrake-ruby/promise.rb +1 -0
  26. data/lib/airbrake-ruby/query.rb +1 -6
  27. data/lib/airbrake-ruby/queue.rb +1 -8
  28. data/lib/airbrake-ruby/remote_settings.rb +16 -54
  29. data/lib/airbrake-ruby/remote_settings/callback.rb +44 -0
  30. data/lib/airbrake-ruby/remote_settings/settings_data.rb +14 -14
  31. data/lib/airbrake-ruby/request.rb +1 -8
  32. data/lib/airbrake-ruby/stat.rb +1 -12
  33. data/lib/airbrake-ruby/sync_sender.rb +1 -0
  34. data/lib/airbrake-ruby/tdigest.rb +2 -0
  35. data/lib/airbrake-ruby/thread_pool.rb +1 -0
  36. data/lib/airbrake-ruby/truncator.rb +8 -2
  37. data/lib/airbrake-ruby/version.rb +2 -2
  38. data/spec/backtrace_spec.rb +26 -26
  39. data/spec/code_hunk_spec.rb +2 -2
  40. data/spec/config/processor_spec.rb +21 -101
  41. data/spec/config_spec.rb +5 -29
  42. data/spec/filters/gem_root_filter_spec.rb +4 -4
  43. data/spec/filters/git_last_checkout_filter_spec.rb +1 -1
  44. data/spec/filters/keys_allowlist_spec.rb +1 -0
  45. data/spec/filters/keys_blocklist_spec.rb +10 -0
  46. data/spec/filters/root_directory_filter_spec.rb +4 -4
  47. data/spec/filters/sql_filter_spec.rb +2 -2
  48. data/spec/filters/thread_filter_spec.rb +1 -1
  49. data/spec/notice_notifier/options_spec.rb +2 -2
  50. data/spec/notice_notifier_spec.rb +2 -2
  51. data/spec/notice_spec.rb +1 -1
  52. data/spec/performance_breakdown_spec.rb +0 -12
  53. data/spec/performance_notifier_spec.rb +0 -25
  54. data/spec/query_spec.rb +1 -11
  55. data/spec/queue_spec.rb +1 -13
  56. data/spec/remote_settings/callback_spec.rb +143 -0
  57. data/spec/remote_settings/settings_data_spec.rb +34 -13
  58. data/spec/remote_settings_spec.rb +40 -83
  59. data/spec/request_spec.rb +1 -13
  60. data/spec/spec_helper.rb +4 -4
  61. data/spec/stat_spec.rb +0 -9
  62. data/spec/tdigest_spec.rb +1 -1
  63. metadata +8 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c5c1a171bc9b89ed604ee96683863915d95d13823f004234902d95036576d101
4
- data.tar.gz: bcc5563ebce4151570184bf9ed9248eb21684fbc4cf5911fbea687f47e4587e4
3
+ metadata.gz: f03821ae0b7ff2d1e1e0b7e1122e2fc8368c4cabd4fac5d623530dd7eafac33c
4
+ data.tar.gz: cf2234bd6fc61e439796b0f664163a12fdd4c39c4256a1c469f06dd1f8132de3
5
5
  SHA512:
6
- metadata.gz: eb1e4f7df43de3905ebe1fdded4066009043fc5f82a6f47aa7ea827ced8a0ba77432eb5413c8481456e5348a7ea673e1a880ecbf15aefb5a94d37eb0df7b91a2
7
- data.tar.gz: 9967e9fa9ddef2d7a3be67aa0fc1cc44eca5a0c89945b0fa69bf4510733e827f164a70c7a12e36426d4a5b6f239fdd072a64de886aca42d93355ad18b5d96b66
6
+ metadata.gz: 9980a80ea62fe7602ae7d689e3b35f439370d781b4d4001e4960b18705465fc3bed7f7a49b67eeb7249253c55c58a1ba9b87485979fd9cdb4c320c2a7e1aa67a
7
+ data.tar.gz: d13b77d0f959ff3a5326f054b8df67c9402b216038afd25672df8b6803623ac135bb5366739687fc5c234ae2e127d075828f747bb945d9ba4d48f3f354775f17
@@ -13,6 +13,7 @@ require 'airbrake-ruby/grouppable'
13
13
  require 'airbrake-ruby/config'
14
14
  require 'airbrake-ruby/config/validator'
15
15
  require 'airbrake-ruby/config/processor'
16
+ require 'airbrake-ruby/remote_settings/callback'
16
17
  require 'airbrake-ruby/remote_settings/settings_data'
17
18
  require 'airbrake-ruby/remote_settings'
18
19
  require 'airbrake-ruby/promise'
@@ -22,7 +22,7 @@ module Airbrake
22
22
  (?<line>\d+) # Matches '43'
23
23
  :in\s
24
24
  `(?<function>.*)' # Matches "`block (3 levels) in <top (required)>'"
25
- \z}x
25
+ \z}x.freeze
26
26
 
27
27
  # @return [Regexp] the pattern that matches JRuby Java stack frames, such
28
28
  # as org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
@@ -39,7 +39,7 @@ module Airbrake
39
39
  :?
40
40
  (?<line>\d+)? # Matches '105'
41
41
  \)
42
- \z}x
42
+ \z}x.freeze
43
43
 
44
44
  # @return [Regexp] the pattern that tries to assume what a generic stack
45
45
  # frame might look like, when exception's backtrace is set manually.
@@ -53,7 +53,7 @@ module Airbrake
53
53
  |
54
54
  :in\s(?<function>.+) # Matches ":in func"
55
55
  )? # ... or nothing
56
- \z}x
56
+ \z}x.freeze
57
57
 
58
58
  # @return [Regexp] the pattern that matches exceptions from PL/SQL such as
59
59
  # ORA-06512: at "STORE.LI_LICENSES_PACK", line 1945
@@ -67,7 +67,7 @@ module Airbrake
67
67
  |
68
68
  #{GENERIC}
69
69
  )
70
- \z/x
70
+ \z/x.freeze
71
71
 
72
72
  # @return [Regexp] the pattern that matches CoffeeScript backtraces
73
73
  # usually coming from Rails & ExecJS
@@ -82,7 +82,7 @@ module Airbrake
82
82
  # Matches the Ruby part of the backtrace
83
83
  #{RUBY}
84
84
  )
85
- \z/x
85
+ \z/x.freeze
86
86
  end
87
87
 
88
88
  # @return [Integer] how many first frames should include code hunks
@@ -95,6 +95,7 @@ module Airbrake
95
95
  # @return [Array<Hash{Symbol=>String,Integer}>] the parsed backtrace
96
96
  def self.parse(exception)
97
97
  return [] if exception.backtrace.nil? || exception.backtrace.none?
98
+
98
99
  parse_backtrace(exception)
99
100
  end
100
101
 
@@ -4,7 +4,6 @@ module Airbrake
4
4
  #
5
5
  # @api public
6
6
  # @since v1.0.0
7
- # rubocop:disable Metrics/ClassLength
8
7
  class Config
9
8
  # @return [Integer] the project identificator. This value *must* be set.
10
9
  # @api public
@@ -47,15 +46,15 @@ module Airbrake
47
46
  # @api public
48
47
  attr_accessor :host
49
48
 
50
- # @since v?.?.?
49
+ # @since v5.0.0
51
50
  alias error_host host
52
- # @since v?.?.?
51
+ # @since v5.0.0
53
52
  alias error_host= host=
54
53
 
55
54
  # @return [String] the host, which provides the API endpoint to which
56
55
  # APM data should be sent
57
56
  # @api public
58
- # @since v?.?.?
57
+ # @since v5.0.0
59
58
  attr_accessor :apm_host
60
59
 
61
60
  # @return [String, Pathname] the working directory of your project
@@ -83,18 +82,12 @@ module Airbrake
83
82
  # @since v4.15.0
84
83
  attr_accessor :allowlist_keys
85
84
 
86
- # @deprecated Use allowlist_keys instead
87
- alias whitelist_keys allowlist_keys
88
-
89
85
  # @return [Array<String, Symbol, Regexp>] the keys, which should be
90
86
  # filtered
91
87
  # @api public
92
88
  # @since v4.15.0
93
89
  attr_accessor :blocklist_keys
94
90
 
95
- # @deprecated Use blocklist_keys instead
96
- alias blacklist_keys blocklist_keys
97
-
98
91
  # @return [Boolean] true if the library should attach code hunks to each
99
92
  # frame in a backtrace, false otherwise
100
93
  # @api public
@@ -128,14 +121,20 @@ module Airbrake
128
121
  # @return [Boolean] true if the library should send error reports to
129
122
  # Airbrake, false otherwise
130
123
  # @api public
131
- # @since ?.?.?
124
+ # @since v5.0.0
132
125
  attr_accessor :error_notifications
133
126
 
134
- # @note Not for public use!
135
- # @return [Boolean]
136
- # @api private
137
- # @since ?.?.?
138
- attr_accessor :__remote_configuration
127
+ # @return [String] the host which should be used for fetching remote
128
+ # configuration options
129
+ # @api public
130
+ # @since v5.0.0
131
+ attr_accessor :remote_config_host
132
+
133
+ # @return [String] true if notifier should periodically fetch remote
134
+ # configuration, false otherwise
135
+ # @api public
136
+ # @since v5.2.0
137
+ attr_accessor :remote_config
139
138
 
140
139
  class << self
141
140
  # @return [Config]
@@ -149,7 +148,7 @@ module Airbrake
149
148
 
150
149
  # @param [Hash{Symbol=>Object}] user_config the hash to be used to build the
151
150
  # config
152
- # rubocop:disable Metrics/AbcSize
151
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
153
152
  def initialize(user_config = {})
154
153
  self.proxy = {}
155
154
  self.queue_size = 100
@@ -160,6 +159,7 @@ module Airbrake
160
159
  self.project_key = user_config[:project_key]
161
160
  self.error_host = 'https://api.airbrake.io'
162
161
  self.apm_host = 'https://api.airbrake.io'
162
+ self.remote_config_host = 'https://notifier-configs.airbrake.io'
163
163
 
164
164
  self.ignore_environments = []
165
165
 
@@ -179,29 +179,11 @@ module Airbrake
179
179
  self.query_stats = true
180
180
  self.job_stats = true
181
181
  self.error_notifications = true
182
- self.__remote_configuration = false
182
+ self.remote_config = true
183
183
 
184
184
  merge(user_config)
185
185
  end
186
- # rubocop:enable Metrics/AbcSize
187
-
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
186
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
205
187
 
206
188
  # The full URL to the Airbrake Notice API. Based on the +:error_host+ option.
207
189
  # @return [URI] the endpoint address
@@ -288,5 +270,4 @@ module Airbrake
288
270
  raise Airbrake::Error, "unknown option '#{option}'"
289
271
  end
290
272
  end
291
- # rubocop:enable Metrics/ClassLength
292
273
  end
@@ -3,7 +3,7 @@ module Airbrake
3
3
  # Processor is a helper class, which is responsible for setting default
4
4
  # config values, default notifier filters and remote configuration changes.
5
5
  #
6
- # @since v?.?.?
6
+ # @since v5.0.0
7
7
  # @api private
8
8
  class Processor
9
9
  # @param [Airbrake::Config] config
@@ -18,6 +18,7 @@ module Airbrake
18
18
  @blocklist_keys = @config.blocklist_keys
19
19
  @allowlist_keys = @config.allowlist_keys
20
20
  @project_id = @config.project_id
21
+ @poll_callback = Airbrake::RemoteSettings::Callback.new(config)
21
22
  end
22
23
 
23
24
  # @param [Airbrake::NoticeNotifier] notifier
@@ -40,9 +41,13 @@ module Airbrake
40
41
 
41
42
  # @return [Airbrake::RemoteSettings]
42
43
  def process_remote_configuration
43
- return if !@project_id || !@config.__remote_configuration
44
+ return unless @config.remote_config
45
+ return unless @project_id
46
+ return if @config.environment == 'test'
44
47
 
45
- RemoteSettings.poll(@project_id, &method(:poll_callback))
48
+ RemoteSettings.poll(@project_id, @config.remote_config_host) do |data|
49
+ @poll_callback.call(data)
50
+ end
46
51
  end
47
52
 
48
53
  # @param [Airbrake::NoticeNotifier] notifier
@@ -61,20 +66,6 @@ module Airbrake
61
66
  notifier.add_filter(filter.new(@config.root_directory))
62
67
  end
63
68
  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
69
  end
79
70
  end
80
71
  end
@@ -61,12 +61,14 @@ module Airbrake
61
61
 
62
62
  def valid_project_id?(config)
63
63
  return true if config.project_id.to_i > 0
64
+
64
65
  false
65
66
  end
66
67
 
67
68
  def valid_project_key?(config)
68
69
  return false unless config.project_key.is_a?(String)
69
70
  return false if config.project_key.empty?
71
+
70
72
  true
71
73
  end
72
74
 
@@ -40,7 +40,7 @@ module Airbrake
40
40
  data.empty?
41
41
  end
42
42
 
43
- # @since ?.?.?
43
+ # @since v4.7.0
44
44
  # @return [void]
45
45
  def self.reset
46
46
  @data = {}
@@ -70,6 +70,7 @@ module Airbrake
70
70
  def refine(notice)
71
71
  @filters.each do |filter|
72
72
  break if notice.ignored?
73
+
73
74
  filter.call(notice)
74
75
  end
75
76
  end
@@ -24,6 +24,7 @@ module Airbrake
24
24
 
25
25
  def git_version(spec)
26
26
  return unless spec.respond_to?(:git_version) || spec.git_version
27
+
27
28
  spec.git_version.to_s
28
29
  end
29
30
  end
@@ -23,6 +23,7 @@ module Airbrake
23
23
  # If the frame is unparseable, then 'file' is nil, thus nothing to
24
24
  # filter (all frame's data is in 'function' instead).
25
25
  next unless (file = frame[:file])
26
+
26
27
  frame[:file] = file.sub(/\A#{gem_path}/, GEM_ROOT_LABEL)
27
28
  end
28
29
  end
@@ -41,12 +41,12 @@ module Airbrake
41
41
 
42
42
  return unless File.exist?(@git_path)
43
43
  return unless (checkout = last_checkout)
44
+
44
45
  notice[:context][:lastCheckout] = checkout
45
46
  end
46
47
 
47
48
  private
48
49
 
49
- # rubocop:disable Metrics/AbcSize
50
50
  def last_checkout
51
51
  return unless (line = last_checkout_line)
52
52
 
@@ -66,7 +66,6 @@ module Airbrake
66
66
  time: timestamp(parts[-2].to_i),
67
67
  }
68
68
  end
69
- # rubocop:enable Metrics/AbcSize
70
69
 
71
70
  def last_checkout_line
72
71
  head_path = File.join(@git_path, 'logs', 'HEAD')
@@ -18,6 +18,7 @@ module Airbrake
18
18
  # @macro call_filter
19
19
  def call(notice)
20
20
  return if notice[:context].key?(:repository)
21
+
21
22
  attach_repository(notice)
22
23
  end
23
24
 
@@ -39,6 +40,7 @@ module Airbrake
39
40
  end
40
41
 
41
42
  return unless @repository
43
+
42
44
  notice[:context][:repository] = @repository
43
45
  end
44
46
 
@@ -46,6 +48,7 @@ module Airbrake
46
48
 
47
49
  def detect_git_version
48
50
  return unless which('git')
51
+
49
52
  Gem::Version.new(`git --version`.split[2])
50
53
  end
51
54
 
@@ -30,6 +30,7 @@ module Airbrake
30
30
 
31
31
  @revision = find_revision
32
32
  return unless @revision
33
+
33
34
  notice[:context][:revision] = @revision
34
35
  end
35
36
 
@@ -41,6 +42,7 @@ module Airbrake
41
42
 
42
43
  head = File.read(head_path)
43
44
  return head unless head.start_with?(PREFIX)
45
+
44
46
  head = head.chomp[PREFIX.size..-1]
45
47
 
46
48
  ref_path = File.join(@git_path, head)
@@ -64,10 +64,14 @@ module Airbrake
64
64
  validate_patterns
65
65
  end
66
66
 
67
- FILTERABLE_KEYS.each { |key| filter_hash(notice[key]) }
67
+ FILTERABLE_KEYS.each do |key|
68
+ notice[key] = filter_hash(notice[key])
69
+ end
70
+
68
71
  FILTERABLE_CONTEXT_KEYS.each { |key| filter_context_key(notice, key) }
69
72
 
70
73
  return unless notice[:context][:url]
74
+
71
75
  filter_url(notice)
72
76
  end
73
77
 
@@ -81,26 +85,26 @@ module Airbrake
81
85
  def filter_hash(hash)
82
86
  return hash unless hash.is_a?(Hash)
83
87
 
88
+ hash_copy = hash.dup
89
+
84
90
  hash.each_key do |key|
85
91
  if should_filter?(key.to_s)
86
- hash[key] = FILTERED
87
- elsif hash[key].is_a?(Hash)
88
- filter_hash(hash[key])
92
+ hash_copy[key] = FILTERED
93
+ elsif hash_copy[key].is_a?(Hash)
94
+ hash_copy[key] = filter_hash(hash_copy[key])
89
95
  elsif hash[key].is_a?(Array)
90
- hash[key].each { |h| filter_hash(h) }
96
+ hash_copy[key].each_with_index do |h, i|
97
+ hash_copy[key][i] = filter_hash(h)
98
+ end
91
99
  end
92
100
  end
101
+
102
+ hash_copy
93
103
  end
94
104
 
95
105
  def filter_url_params(url)
96
106
  url.query = Hash[URI.decode_www_form(url.query)].map do |key, val|
97
- # Ruby < 2.2 raises InvalidComponentError if the query contains
98
- # invalid characters, so be sure to escape individual components.
99
- if should_filter?(key)
100
- "#{URI.encode_www_form_component(key)}=[Filtered]"
101
- else
102
- "#{URI.encode_www_form_component(key)}=#{URI.encode_www_form_component(val)}"
103
- end
107
+ should_filter?(key) ? "#{key}=[Filtered]" : "#{key}=#{val}"
104
108
  end.join('&')
105
109
 
106
110
  url.to_s
@@ -114,6 +118,7 @@ module Airbrake
114
118
  end
115
119
 
116
120
  return unless url.query
121
+
117
122
  notice[:context][:url] = filter_url_params(url)
118
123
  end
119
124
 
@@ -122,6 +127,7 @@ module Airbrake
122
127
 
123
128
  @patterns = @patterns.flat_map do |pattern|
124
129
  next(pattern) unless pattern.respond_to?(:call)
130
+
125
131
  pattern.call
126
132
  end
127
133
  end
@@ -142,7 +148,9 @@ module Airbrake
142
148
  def filter_context_key(notice, key)
143
149
  return unless notice[:context][key]
144
150
  return if notice[:context][key] == FILTERED
145
- return filter_hash(notice[:context][key]) unless should_filter?(key)
151
+ unless should_filter?(key)
152
+ return notice[:context][key] = filter_hash(notice[:context][key])
153
+ end
146
154
 
147
155
  notice[:context][key] = FILTERED
148
156
  end
@@ -19,6 +19,7 @@ module Airbrake
19
19
  notice[:errors].each do |error|
20
20
  error[:backtrace].each do |frame|
21
21
  next unless (file = frame[:file])
22
+
22
23
  file.sub!(/\A#{@root_directory}/, PROJECT_ROOT_LABEL)
23
24
  end
24
25
  end