airbrake-ruby 5.0.0.rc.2-java → 5.2.0-java

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