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

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) 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 +9 -35
  5. data/lib/airbrake-ruby/config/processor.rb +7 -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 +2 -0
  19. data/lib/airbrake-ruby/ignorable.rb +1 -0
  20. data/lib/airbrake-ruby/notice.rb +1 -8
  21. data/lib/airbrake-ruby/notice_notifier.rb +1 -0
  22. data/lib/airbrake-ruby/performance_breakdown.rb +1 -6
  23. data/lib/airbrake-ruby/performance_notifier.rb +1 -14
  24. data/lib/airbrake-ruby/promise.rb +1 -0
  25. data/lib/airbrake-ruby/query.rb +1 -6
  26. data/lib/airbrake-ruby/queue.rb +1 -8
  27. data/lib/airbrake-ruby/remote_settings.rb +26 -49
  28. data/lib/airbrake-ruby/remote_settings/callback.rb +44 -0
  29. data/lib/airbrake-ruby/remote_settings/settings_data.rb +14 -14
  30. data/lib/airbrake-ruby/request.rb +1 -8
  31. data/lib/airbrake-ruby/stat.rb +1 -12
  32. data/lib/airbrake-ruby/sync_sender.rb +2 -1
  33. data/lib/airbrake-ruby/tdigest.rb +2 -0
  34. data/lib/airbrake-ruby/thread_pool.rb +1 -0
  35. data/lib/airbrake-ruby/truncator.rb +8 -2
  36. data/lib/airbrake-ruby/version.rb +11 -1
  37. data/spec/backtrace_spec.rb +26 -26
  38. data/spec/code_hunk_spec.rb +2 -2
  39. data/spec/config/processor_spec.rb +13 -102
  40. data/spec/config_spec.rb +4 -29
  41. data/spec/filters/gem_root_filter_spec.rb +4 -4
  42. data/spec/filters/git_last_checkout_filter_spec.rb +1 -1
  43. data/spec/filters/keys_allowlist_spec.rb +1 -0
  44. data/spec/filters/keys_blocklist_spec.rb +10 -0
  45. data/spec/filters/root_directory_filter_spec.rb +4 -4
  46. data/spec/filters/sql_filter_spec.rb +2 -2
  47. data/spec/notice_notifier/options_spec.rb +2 -2
  48. data/spec/notice_notifier_spec.rb +2 -2
  49. data/spec/notice_spec.rb +1 -1
  50. data/spec/performance_breakdown_spec.rb +0 -12
  51. data/spec/performance_notifier_spec.rb +0 -25
  52. data/spec/query_spec.rb +1 -11
  53. data/spec/queue_spec.rb +1 -13
  54. data/spec/remote_settings/callback_spec.rb +143 -0
  55. data/spec/remote_settings/settings_data_spec.rb +34 -13
  56. data/spec/remote_settings_spec.rb +62 -87
  57. data/spec/request_spec.rb +1 -13
  58. data/spec/spec_helper.rb +4 -4
  59. data/spec/stat_spec.rb +0 -9
  60. metadata +11 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6a60c7ee3f35357ecbe72d0bdedb89a61b248101ac58d866166e5daa1e2f79eb
4
- data.tar.gz: 53a68e1f1bab4158d773593ad201dce948a0df60c0fd1b80a27451a96dc5596c
3
+ metadata.gz: bdd90a24dce9e68068a1571f751f6d2e3ff691b7852e0adc37b156d2ae45c38b
4
+ data.tar.gz: '08e6b8f6af0fd1ff980e642d9ce540c6c407844d34249bb921b9a15cd5f74ad7'
5
5
  SHA512:
6
- metadata.gz: 8d14d8843ea3d8c8923b654d5c1110fbefb83b40b63a15c930b5243de81f5ecd594d8e08be64a8242884793a6203f535d16088ebbbef3328d519f8cfd440d19e
7
- data.tar.gz: '08fdf62186815e85696acd66641f60bfeca556c2a3e30c0b7d7c49c3f02bdd208d795aceee9af65a4683773580682f8efa96a61434a716118a8a85346432d41f'
6
+ metadata.gz: 3ede01bf80015a2e9ff9c28377be27ff902bc93f199eeb0fd3e546301510712897c48f797691489ece71ae052950f18fb8ae91ea2a6ed6d4984f50e028b4cad2
7
+ data.tar.gz: c1ebc53b428eca54eb4c85e4fc094819c9c2972308b97069c6234502159d57c2b5977203fb8a60dd3865e7f8dca2f0430dd0f1500ef2df89f8f059a881433740
@@ -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,14 @@ 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 5.0.0
132
125
  attr_accessor :error_notifications
133
126
 
134
- # @note Not for public use!
135
- # @return [Boolean]
127
+ # @return [String] the host such as which should be used for fetching remote
128
+ # configuration options (example: "https://bucket-name.s3.amazonaws.com")
136
129
  # @api private
137
- # @since ?.?.?
138
- attr_accessor :__remote_configuration
130
+ # @since 5.0.0
131
+ attr_accessor :remote_config_host
139
132
 
140
133
  class << self
141
134
  # @return [Config]
@@ -160,6 +153,7 @@ module Airbrake
160
153
  self.project_key = user_config[:project_key]
161
154
  self.error_host = 'https://api.airbrake.io'
162
155
  self.apm_host = 'https://api.airbrake.io'
156
+ self.remote_config_host = 'https://notifier-configs.airbrake.io'
163
157
 
164
158
  self.ignore_environments = []
165
159
 
@@ -179,30 +173,11 @@ module Airbrake
179
173
  self.query_stats = true
180
174
  self.job_stats = true
181
175
  self.error_notifications = true
182
- self.__remote_configuration = false
183
176
 
184
177
  merge(user_config)
185
178
  end
186
179
  # rubocop:enable Metrics/AbcSize
187
180
 
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
181
  # The full URL to the Airbrake Notice API. Based on the +:error_host+ option.
207
182
  # @return [URI] the endpoint address
208
183
  def error_endpoint
@@ -288,5 +263,4 @@ module Airbrake
288
263
  raise Airbrake::Error, "unknown option '#{option}'"
289
264
  end
290
265
  end
291
- # rubocop:enable Metrics/ClassLength
292
266
  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 5.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,12 @@ 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 @project_id
45
+ return if @config.environment == 'test'
44
46
 
45
- RemoteSettings.poll(@project_id, &method(:poll_callback))
47
+ RemoteSettings.poll(@project_id, @config.remote_config_host) do |data|
48
+ @poll_callback.call(data)
49
+ end
46
50
  end
47
51
 
48
52
  # @param [Airbrake::NoticeNotifier] notifier
@@ -61,20 +65,6 @@ module Airbrake
61
65
  notifier.add_filter(filter.new(@config.root_directory))
62
66
  end
63
67
  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
68
  end
79
69
  end
80
70
  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 4.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
@@ -23,7 +23,7 @@ module Airbrake
23
23
 
24
24
  # @return [Hash{Symbol=>Regexp}] matchers for certain features of SQL
25
25
  ALL_FEATURES = {
26
- # rubocop:disable Metrics/LineLength
26
+ # rubocop:disable Layout/LineLength
27
27
  single_quotes: /'(?:[^']|'')*?(?:\\'.*|'(?!'))/,
28
28
  double_quotes: /"(?:[^"]|"")*?(?:\\".*|"(?!"))/,
29
29
  dollar_quotes: /(\$(?!\d)[^$]*?\$).*?(?:\1|$)/,
@@ -33,13 +33,13 @@ module Airbrake
33
33
  hexadecimal_literals: /0x[0-9a-fA-F]+/,
34
34
  comments: /(?:#|--).*?(?=\r|\n|$)/i,
35
35
  multi_line_comments: %r{/\*(?:[^/]|/[^*])*?(?:\*/|/\*.*)},
36
- oracle_quoted_strings: /q'\[.*?(?:\]'|$)|q'\{.*?(?:\}'|$)|q'\<.*?(?:\>'|$)|q'\(.*?(?:\)'|$)/
37
- # rubocop:enable Metrics/LineLength
36
+ oracle_quoted_strings: /q'\[.*?(?:\]'|$)|q'\{.*?(?:\}'|$)|q'\<.*?(?:\>'|$)|q'\(.*?(?:\)'|$)/,
37
+ # rubocop:enable Layout/LineLength
38
38
  }.freeze
39
39
 
40
40
  # @return [Regexp] the regexp that is applied after the feature regexps
41
41
  # were used
42
- POST_FILTER = /(?<=[values|in ]\().+(?=\))/i
42
+ POST_FILTER = /(?<=[values|in ]\().+(?=\))/i.freeze
43
43
 
44
44
  # @return [Hash{Symbol=>Array<Symbol>}] a set of features that corresponds
45
45
  # to a certain dialect