airbrake-ruby 5.0.0.rc.2 → 5.0.0
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.
- checksums.yaml +4 -4
- data/lib/airbrake-ruby/backtrace.rb +6 -5
- data/lib/airbrake-ruby/config.rb +8 -36
- data/lib/airbrake-ruby/config/processor.rb +7 -3
- data/lib/airbrake-ruby/config/validator.rb +2 -0
- data/lib/airbrake-ruby/file_cache.rb +1 -1
- data/lib/airbrake-ruby/filter_chain.rb +1 -0
- data/lib/airbrake-ruby/filters/dependency_filter.rb +1 -0
- data/lib/airbrake-ruby/filters/gem_root_filter.rb +1 -0
- data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +1 -2
- data/lib/airbrake-ruby/filters/git_repository_filter.rb +3 -0
- data/lib/airbrake-ruby/filters/git_revision_filter.rb +2 -0
- data/lib/airbrake-ruby/filters/keys_filter.rb +21 -13
- data/lib/airbrake-ruby/filters/root_directory_filter.rb +1 -0
- data/lib/airbrake-ruby/filters/sql_filter.rb +4 -4
- data/lib/airbrake-ruby/filters/system_exit_filter.rb +1 -0
- data/lib/airbrake-ruby/filters/thread_filter.rb +2 -0
- data/lib/airbrake-ruby/ignorable.rb +1 -0
- data/lib/airbrake-ruby/notice_notifier.rb +1 -0
- data/lib/airbrake-ruby/performance_breakdown.rb +1 -6
- data/lib/airbrake-ruby/performance_notifier.rb +1 -14
- data/lib/airbrake-ruby/promise.rb +1 -0
- data/lib/airbrake-ruby/query.rb +1 -6
- data/lib/airbrake-ruby/queue.rb +1 -8
- data/lib/airbrake-ruby/remote_settings.rb +7 -5
- data/lib/airbrake-ruby/remote_settings/settings_data.rb +13 -9
- data/lib/airbrake-ruby/request.rb +1 -8
- data/lib/airbrake-ruby/stat.rb +1 -12
- data/lib/airbrake-ruby/sync_sender.rb +1 -0
- data/lib/airbrake-ruby/tdigest.rb +2 -0
- data/lib/airbrake-ruby/thread_pool.rb +1 -0
- data/lib/airbrake-ruby/truncator.rb +8 -2
- data/lib/airbrake-ruby/version.rb +2 -2
- data/spec/backtrace_spec.rb +26 -26
- data/spec/code_hunk_spec.rb +2 -2
- data/spec/config/processor_spec.rb +5 -19
- data/spec/config_spec.rb +4 -29
- data/spec/filters/gem_root_filter_spec.rb +4 -4
- data/spec/filters/keys_allowlist_spec.rb +1 -0
- data/spec/filters/keys_blocklist_spec.rb +10 -0
- data/spec/filters/root_directory_filter_spec.rb +4 -4
- data/spec/filters/sql_filter_spec.rb +2 -2
- data/spec/notice_notifier/options_spec.rb +2 -2
- data/spec/notice_notifier_spec.rb +2 -2
- data/spec/notice_spec.rb +1 -1
- data/spec/performance_breakdown_spec.rb +0 -12
- data/spec/performance_notifier_spec.rb +0 -25
- data/spec/query_spec.rb +1 -11
- data/spec/queue_spec.rb +1 -13
- data/spec/remote_settings/settings_data_spec.rb +51 -13
- data/spec/remote_settings_spec.rb +14 -14
- data/spec/request_spec.rb +1 -13
- data/spec/spec_helper.rb +4 -4
- data/spec/stat_spec.rb +0 -9
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e98183a856071ce3d105c36adc9aa22a8ee7071b93958fd70fb673d2735b3977
|
4
|
+
data.tar.gz: 80464931a1362c4d845ffee737ed7aa1e46693136023b1f08006c49de98e62eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c32fc631e3af6348a871094dde31452d4a6fdef834596933e179d2acdbbd4935751715007fa7c4dcfce3639ebbd55f61b15f06428015647e4cbcac590ef7aaf
|
7
|
+
data.tar.gz: 23968940c6f1dfb500be5ab479c1d524cdc9f80e40808b4ff08d7f4b03c97baad603d97504c58a5300ddfa7ec9b1a4b5bd44a24a6a4a15776a82778ef2a0c324
|
@@ -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
|
|
data/lib/airbrake-ruby/config.rb
CHANGED
@@ -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
|
49
|
+
# @since v5.0.0
|
51
50
|
alias error_host host
|
52
|
-
# @since
|
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
|
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,12 @@ 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
|
-
# @
|
135
|
-
#
|
136
|
-
|
137
|
-
# @since ?.?.?
|
138
|
-
attr_accessor :__remote_configuration
|
127
|
+
# @return [String] the host such as which should be used for fetching remote
|
128
|
+
# configuration options (example: "https://bucket-name.s3.amazonaws.com")
|
129
|
+
attr_accessor :remote_config_host
|
139
130
|
|
140
131
|
class << self
|
141
132
|
# @return [Config]
|
@@ -160,6 +151,7 @@ module Airbrake
|
|
160
151
|
self.project_key = user_config[:project_key]
|
161
152
|
self.error_host = 'https://api.airbrake.io'
|
162
153
|
self.apm_host = 'https://api.airbrake.io'
|
154
|
+
self.remote_config_host = 'https://v1-production-notifier-configs.s3.amazonaws.com'
|
163
155
|
|
164
156
|
self.ignore_environments = []
|
165
157
|
|
@@ -179,30 +171,11 @@ module Airbrake
|
|
179
171
|
self.query_stats = true
|
180
172
|
self.job_stats = true
|
181
173
|
self.error_notifications = true
|
182
|
-
self.__remote_configuration = false
|
183
174
|
|
184
175
|
merge(user_config)
|
185
176
|
end
|
186
177
|
# rubocop:enable Metrics/AbcSize
|
187
178
|
|
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
179
|
# The full URL to the Airbrake Notice API. Based on the +:error_host+ option.
|
207
180
|
# @return [URI] the endpoint address
|
208
181
|
def error_endpoint
|
@@ -288,5 +261,4 @@ module Airbrake
|
|
288
261
|
raise Airbrake::Error, "unknown option '#{option}'"
|
289
262
|
end
|
290
263
|
end
|
291
|
-
# rubocop:enable Metrics/ClassLength
|
292
264
|
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
|
6
|
+
# @since 5.0.0
|
7
7
|
# @api private
|
8
8
|
class Processor
|
9
9
|
# @param [Airbrake::Config] config
|
@@ -40,9 +40,13 @@ module Airbrake
|
|
40
40
|
|
41
41
|
# @return [Airbrake::RemoteSettings]
|
42
42
|
def process_remote_configuration
|
43
|
-
return
|
43
|
+
return unless @project_id
|
44
44
|
|
45
|
-
RemoteSettings.poll(
|
45
|
+
RemoteSettings.poll(
|
46
|
+
@project_id,
|
47
|
+
@config.remote_config_host,
|
48
|
+
&method(:poll_callback)
|
49
|
+
)
|
46
50
|
end
|
47
51
|
|
48
52
|
# @param [Airbrake::NoticeNotifier] notifier
|
@@ -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
|
|
@@ -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
|
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
|
-
|
87
|
-
elsif
|
88
|
-
filter_hash(
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
@@ -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
|
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
|
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
|
@@ -56,6 +56,7 @@ module Airbrake
|
|
56
56
|
def thread_variables(th)
|
57
57
|
th.thread_variables.map.with_object({}) do |var, h|
|
58
58
|
next if var.to_s.start_with?(IGNORE_PREFIX)
|
59
|
+
|
59
60
|
h[var] = sanitize_value(th.thread_variable_get(var))
|
60
61
|
end
|
61
62
|
end
|
@@ -63,6 +64,7 @@ module Airbrake
|
|
63
64
|
def fiber_variables(th)
|
64
65
|
th.keys.map.with_object({}) do |key, h|
|
65
66
|
next if key.to_s.start_with?(IGNORE_PREFIX)
|
67
|
+
|
66
68
|
h[key] = sanitize_value(th[key])
|
67
69
|
end
|
68
70
|
end
|