sentry-raven 3.0.4 → 3.1.2
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/.craft.yml +9 -5
- data/.scripts/bump-version.rb +5 -0
- data/CHANGELOG.md +145 -1
- data/Gemfile +5 -1
- data/Makefile +3 -0
- data/README.md +26 -8
- data/lib/raven/backtrace.rb +2 -0
- data/lib/raven/base.rb +2 -0
- data/lib/raven/breadcrumbs/active_support_logger.rb +25 -0
- data/lib/raven/breadcrumbs/logger.rb +2 -92
- data/lib/raven/breadcrumbs/sentry_logger.rb +73 -0
- data/lib/raven/cli.rb +1 -1
- data/lib/raven/client.rb +1 -1
- data/lib/raven/configuration.rb +75 -4
- data/lib/raven/context.rb +13 -8
- data/lib/raven/event.rb +27 -13
- data/lib/raven/helpers/deprecation_helper.rb +17 -0
- data/lib/raven/instance.rb +15 -2
- data/lib/raven/integrations/delayed_job.rb +2 -1
- data/lib/raven/integrations/rack-timeout.rb +5 -1
- data/lib/raven/integrations/rack.rb +5 -4
- data/lib/raven/integrations/rails.rb +12 -3
- data/lib/raven/integrations/rails/active_job.rb +2 -1
- data/lib/raven/integrations/rails/backtrace_cleaner.rb +29 -0
- data/lib/raven/integrations/sidekiq.rb +4 -78
- data/lib/raven/integrations/sidekiq/cleanup_middleware.rb +13 -0
- data/lib/raven/integrations/sidekiq/error_handler.rb +38 -0
- data/lib/raven/transports/http.rb +2 -3
- data/lib/raven/utils/context_filter.rb +42 -0
- data/lib/raven/utils/request_id.rb +16 -0
- data/lib/raven/version.rb +1 -1
- data/lib/sentry-raven-without-integrations.rb +6 -1
- data/lib/sentry_raven_without_integrations.rb +1 -0
- data/sentry-raven.gemspec +7 -0
- metadata +18 -12
- data/.github/workflows/test.yml +0 -87
- data/.github/workflows/zeus_upload.yml +0 -32
- data/.gitignore +0 -15
- data/.gitmodules +0 -0
- data/.rspec +0 -1
- data/.rubocop.yml +0 -109
- data/.scripts/bump-version.sh +0 -9
- data/CONTRIUTING.md +0 -26
- data/lib/raven/breadcrumbs/activesupport.rb +0 -19
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module Raven
|
4
|
+
module Breadcrumbs
|
5
|
+
module SentryLogger
|
6
|
+
LEVELS = {
|
7
|
+
::Logger::DEBUG => 'debug',
|
8
|
+
::Logger::INFO => 'info',
|
9
|
+
::Logger::WARN => 'warn',
|
10
|
+
::Logger::ERROR => 'error',
|
11
|
+
::Logger::FATAL => 'fatal'
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
def add(*args)
|
15
|
+
add_breadcrumb(*args)
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def add_breadcrumb(severity, message = nil, progname = nil)
|
20
|
+
message = progname if message.nil? # see Ruby's Logger docs for why
|
21
|
+
return if ignored_logger?(progname)
|
22
|
+
return if message.nil? || message == ""
|
23
|
+
|
24
|
+
# some loggers will add leading/trailing space as they (incorrectly, mind you)
|
25
|
+
# think of logging as a shortcut to std{out,err}
|
26
|
+
message = message.to_s.strip
|
27
|
+
|
28
|
+
last_crumb = Raven.breadcrumbs.peek
|
29
|
+
# try to avoid dupes from logger broadcasts
|
30
|
+
if last_crumb.nil? || last_crumb.message != message
|
31
|
+
Raven.breadcrumbs.record do |crumb|
|
32
|
+
crumb.level = Raven::Breadcrumbs::SentryLogger::LEVELS.fetch(severity, nil)
|
33
|
+
crumb.category = progname || 'logger'
|
34
|
+
crumb.message = message
|
35
|
+
crumb.type =
|
36
|
+
if severity >= 3
|
37
|
+
"error"
|
38
|
+
else
|
39
|
+
crumb.level
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def ignored_logger?(progname)
|
48
|
+
progname == "sentry" ||
|
49
|
+
Raven.configuration.exclude_loggers.include?(progname)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
module OldBreadcrumbsSentryLogger
|
53
|
+
def self.included(base)
|
54
|
+
base.class_eval do
|
55
|
+
include Raven::Breadcrumbs::SentryLogger
|
56
|
+
alias_method :add_without_raven, :add
|
57
|
+
alias_method :add, :add_with_raven
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def add_with_raven(*args)
|
62
|
+
add_breadcrumb(*args)
|
63
|
+
add_without_raven(*args)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
Raven.safely_prepend(
|
70
|
+
"Breadcrumbs::SentryLogger",
|
71
|
+
:from => Raven,
|
72
|
+
:to => ::Logger
|
73
|
+
)
|
data/lib/raven/cli.rb
CHANGED
data/lib/raven/client.rb
CHANGED
@@ -125,7 +125,7 @@ module Raven
|
|
125
125
|
configuration.logger.warn("Failed to submit event: #{get_log_message(event)}")
|
126
126
|
|
127
127
|
# configuration.transport_failure_callback can be false & nil
|
128
|
-
configuration.transport_failure_callback.call(event) if configuration.transport_failure_callback # rubocop:disable Style/SafeNavigation
|
128
|
+
configuration.transport_failure_callback.call(event, e) if configuration.transport_failure_callback # rubocop:disable Style/SafeNavigation
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
data/lib/raven/configuration.rb
CHANGED
@@ -12,6 +12,11 @@ module Raven
|
|
12
12
|
attr_reader :async
|
13
13
|
alias async? async
|
14
14
|
|
15
|
+
# An array of breadcrumbs loggers to be used. Available options are:
|
16
|
+
# - :sentry_logger
|
17
|
+
# - :active_support_logger
|
18
|
+
attr_reader :breadcrumbs_logger
|
19
|
+
|
15
20
|
# Number of lines of code context to capture, or nil for none
|
16
21
|
attr_accessor :context_lines
|
17
22
|
|
@@ -83,7 +88,7 @@ module Raven
|
|
83
88
|
attr_accessor :public_key
|
84
89
|
|
85
90
|
# Turns on ActiveSupport breadcrumbs integration
|
86
|
-
|
91
|
+
attr_reader :rails_activesupport_breadcrumbs
|
87
92
|
|
88
93
|
# Rails catches exceptions in the ActionDispatch::ShowExceptions or
|
89
94
|
# ActionDispatch::DebugExceptions middlewares, depending on the environment.
|
@@ -118,6 +123,19 @@ module Raven
|
|
118
123
|
# Otherwise, can be one of "http", "https", or "dummy"
|
119
124
|
attr_accessor :scheme
|
120
125
|
|
126
|
+
# a proc/lambda that takes an array of stack traces
|
127
|
+
# it'll be used to silence (reduce) backtrace of the exception
|
128
|
+
#
|
129
|
+
# for example:
|
130
|
+
#
|
131
|
+
# ```ruby
|
132
|
+
# Raven.configuration.backtrace_cleanup_callback = lambda do |backtrace|
|
133
|
+
# Rails.backtrace_cleaner.clean(backtrace)
|
134
|
+
# end
|
135
|
+
# ```
|
136
|
+
#
|
137
|
+
attr_accessor :backtrace_cleanup_callback
|
138
|
+
|
121
139
|
# Secret key for authentication with the Sentry server
|
122
140
|
# If you provide a DSN, this will be set automatically.
|
123
141
|
#
|
@@ -172,16 +190,34 @@ module Raven
|
|
172
190
|
# Errors object - an Array that contains error messages. See #
|
173
191
|
attr_reader :errors
|
174
192
|
|
193
|
+
# the dsn value, whether it's set via `config.dsn=` or `ENV["SENTRY_DSN"]`
|
194
|
+
attr_reader :dsn
|
195
|
+
|
196
|
+
# Array of rack env parameters to be included in the event sent to sentry.
|
197
|
+
attr_accessor :rack_env_whitelist
|
198
|
+
|
199
|
+
# Most of these errors generate 4XX responses. In general, Sentry clients
|
200
|
+
# only automatically report 5xx responses.
|
175
201
|
IGNORE_DEFAULT = [
|
176
202
|
'AbstractController::ActionNotFound',
|
203
|
+
'ActionController::BadRequest',
|
177
204
|
'ActionController::InvalidAuthenticityToken',
|
205
|
+
'ActionController::InvalidCrossOriginRequest',
|
206
|
+
'ActionController::MethodNotAllowed',
|
207
|
+
'ActionController::NotImplemented',
|
208
|
+
'ActionController::ParameterMissing',
|
178
209
|
'ActionController::RoutingError',
|
179
210
|
'ActionController::UnknownAction',
|
211
|
+
'ActionController::UnknownFormat',
|
212
|
+
'ActionController::UnknownHttpMethod',
|
213
|
+
'ActionDispatch::Http::Parameters::ParseError',
|
214
|
+
'ActiveJob::DeserializationError', # Can cause infinite loops
|
180
215
|
'ActiveRecord::RecordNotFound',
|
181
216
|
'CGI::Session::CookieStore::TamperedWithCookie',
|
182
217
|
'Mongoid::Errors::DocumentNotFound',
|
183
|
-
'
|
184
|
-
'
|
218
|
+
'Rack::QueryParser::InvalidParameterError',
|
219
|
+
'Rack::QueryParser::ParameterTypeError',
|
220
|
+
'Sinatra::NotFound'
|
185
221
|
].freeze
|
186
222
|
|
187
223
|
# Note the order - we have to remove circular references and bad characters
|
@@ -198,11 +234,20 @@ module Raven
|
|
198
234
|
HEROKU_DYNO_METADATA_MESSAGE = "You are running on Heroku but haven't enabled Dyno Metadata. For Sentry's "\
|
199
235
|
"release detection to work correctly, please run `heroku labs:enable runtime-dyno-metadata`".freeze
|
200
236
|
|
237
|
+
RACK_ENV_WHITELIST_DEFAULT = %w(
|
238
|
+
REMOTE_ADDR
|
239
|
+
SERVER_NAME
|
240
|
+
SERVER_PORT
|
241
|
+
).freeze
|
242
|
+
|
201
243
|
LOG_PREFIX = "** [Raven] ".freeze
|
202
244
|
MODULE_SEPARATOR = "::".freeze
|
203
245
|
|
246
|
+
AVAILABLE_BREADCRUMBS_LOGGERS = [:sentry_logger, :active_support_logger].freeze
|
247
|
+
|
204
248
|
def initialize
|
205
249
|
self.async = false
|
250
|
+
self.breadcrumbs_logger = []
|
206
251
|
self.context_lines = 3
|
207
252
|
self.current_environment = current_environment_from_env
|
208
253
|
self.encoding = 'gzip'
|
@@ -215,7 +260,8 @@ module Raven
|
|
215
260
|
self.open_timeout = 1
|
216
261
|
self.processors = DEFAULT_PROCESSORS.dup
|
217
262
|
self.project_root = detect_project_root
|
218
|
-
|
263
|
+
@rails_activesupport_breadcrumbs = false
|
264
|
+
|
219
265
|
self.rails_report_rescued_exceptions = true
|
220
266
|
self.release = detect_release
|
221
267
|
self.sample_rate = 1.0
|
@@ -232,11 +278,14 @@ module Raven
|
|
232
278
|
self.timeout = 2
|
233
279
|
self.transport_failure_callback = false
|
234
280
|
self.before_send = false
|
281
|
+
self.rack_env_whitelist = RACK_ENV_WHITELIST_DEFAULT
|
235
282
|
end
|
236
283
|
|
237
284
|
def server=(value)
|
238
285
|
return if value.nil?
|
239
286
|
|
287
|
+
@dsn = value
|
288
|
+
|
240
289
|
uri = URI.parse(value)
|
241
290
|
uri_path = uri.path.split('/')
|
242
291
|
|
@@ -273,6 +322,23 @@ module Raven
|
|
273
322
|
@async = value
|
274
323
|
end
|
275
324
|
|
325
|
+
def breadcrumbs_logger=(logger)
|
326
|
+
loggers =
|
327
|
+
if logger.is_a?(Array)
|
328
|
+
logger
|
329
|
+
else
|
330
|
+
unless AVAILABLE_BREADCRUMBS_LOGGERS.include?(logger)
|
331
|
+
raise Raven::Error, "Unsupported breadcrumbs logger. Supported loggers: #{AVAILABLE_BREADCRUMBS_LOGGERS}"
|
332
|
+
end
|
333
|
+
|
334
|
+
Array(logger)
|
335
|
+
end
|
336
|
+
|
337
|
+
require "raven/breadcrumbs/sentry_logger" if loggers.include?(:sentry_logger)
|
338
|
+
|
339
|
+
@breadcrumbs_logger = logger
|
340
|
+
end
|
341
|
+
|
276
342
|
def transport_failure_callback=(value)
|
277
343
|
unless value == false || value.respond_to?(:call)
|
278
344
|
raise(ArgumentError, "transport_failure_callback must be callable (or false to disable)")
|
@@ -329,6 +395,11 @@ module Raven
|
|
329
395
|
Backtrace::Line.instance_variable_set(:@in_app_pattern, nil) # blow away cache
|
330
396
|
end
|
331
397
|
|
398
|
+
def rails_activesupport_breadcrumbs=(val)
|
399
|
+
DeprecationHelper.deprecate_old_breadcrumbs_configuration(:active_support_logger)
|
400
|
+
@rails_activesupport_breadcrumbs = val
|
401
|
+
end
|
402
|
+
|
332
403
|
def exception_class_allowed?(exc)
|
333
404
|
if exc.is_a?(Raven::Error)
|
334
405
|
# Try to prevent error reporting loops
|
data/lib/raven/context.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'rbconfig'
|
2
|
+
require 'etc'
|
2
3
|
|
3
4
|
module Raven
|
4
5
|
class Context
|
@@ -24,18 +25,22 @@ module Raven
|
|
24
25
|
|
25
26
|
class << self
|
26
27
|
def os_context
|
27
|
-
@os_context ||=
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
28
|
+
@os_context ||=
|
29
|
+
begin
|
30
|
+
uname = Etc.uname
|
31
|
+
{
|
32
|
+
name: uname[:sysname] || RbConfig::CONFIG["host_os"],
|
33
|
+
version: uname[:version],
|
34
|
+
build: uname[:release],
|
35
|
+
kernel_version: uname[:version]
|
36
|
+
}
|
37
|
+
end
|
33
38
|
end
|
34
39
|
|
35
40
|
def runtime_context
|
36
41
|
@runtime_context ||= {
|
37
|
-
:
|
38
|
-
:
|
42
|
+
name: RbConfig::CONFIG["ruby_install_name"],
|
43
|
+
version: RUBY_DESCRIPTION || Raven.sys_command("ruby -v")
|
39
44
|
}
|
40
45
|
end
|
41
46
|
end
|
data/lib/raven/event.rb
CHANGED
@@ -8,6 +8,7 @@ module Raven
|
|
8
8
|
# See Sentry server default limits at
|
9
9
|
# https://github.com/getsentry/sentry/blob/master/src/sentry/conf/server.py
|
10
10
|
MAX_MESSAGE_SIZE_IN_BYTES = 1024 * 8
|
11
|
+
REQUIRED_OPTION_KEYS = [:configuration, :context, :breadcrumbs].freeze
|
11
12
|
|
12
13
|
SDK = { "name" => "raven-ruby", "version" => Raven::VERSION }.freeze
|
13
14
|
|
@@ -19,7 +20,7 @@ module Raven
|
|
19
20
|
|
20
21
|
attr_reader :level, :timestamp, :time_spent
|
21
22
|
|
22
|
-
def initialize(
|
23
|
+
def initialize(options)
|
23
24
|
# Set some simple default values
|
24
25
|
self.id = SecureRandom.uuid.delete("-")
|
25
26
|
self.timestamp = Time.now.utc
|
@@ -36,11 +37,17 @@ module Raven
|
|
36
37
|
self.runtime = {} # TODO: contexts
|
37
38
|
self.tags = {} # TODO: contexts
|
38
39
|
|
39
|
-
|
40
|
+
unless REQUIRED_OPTION_KEYS.all? { |key| options.key?(key) }
|
41
|
+
raise "you must provide configuration, context, and breadcrumbs when initializing a Raven::Event"
|
42
|
+
end
|
43
|
+
|
44
|
+
self.configuration = options[:configuration]
|
45
|
+
self.context = options[:context]
|
46
|
+
self.breadcrumbs = options[:breadcrumbs]
|
40
47
|
|
41
48
|
# Allow attributes to be set on the event at initialization
|
42
49
|
yield self if block_given?
|
43
|
-
|
50
|
+
options.each_pair { |key, val| public_send("#{key}=", val) unless val.nil? }
|
44
51
|
|
45
52
|
set_core_attributes_from_configuration
|
46
53
|
set_core_attributes_from_context
|
@@ -56,8 +63,7 @@ module Raven
|
|
56
63
|
end
|
57
64
|
options = Raven::Utils::DeepMergeHash.deep_merge(exception_context, options)
|
58
65
|
|
59
|
-
|
60
|
-
return unless configuration.exception_class_allowed?(exc)
|
66
|
+
return unless options[:configuration].exception_class_allowed?(exc)
|
61
67
|
|
62
68
|
new(options) do |evt|
|
63
69
|
evt.add_exception_interface(exc)
|
@@ -81,7 +87,17 @@ module Raven
|
|
81
87
|
end
|
82
88
|
|
83
89
|
def message=(args)
|
84
|
-
|
90
|
+
if args.is_a?(Array)
|
91
|
+
message, params = args[0], args[0..-1]
|
92
|
+
else
|
93
|
+
message = args
|
94
|
+
end
|
95
|
+
|
96
|
+
unless message.is_a?(String)
|
97
|
+
configuration.logger.debug("You're passing a non-string message")
|
98
|
+
message = message.to_s
|
99
|
+
end
|
100
|
+
|
85
101
|
interface(:message) do |int|
|
86
102
|
int.message = message.byteslice(0...MAX_MESSAGE_SIZE_IN_BYTES) # Messages limited to 10kb
|
87
103
|
int.params = params
|
@@ -159,7 +175,7 @@ module Raven
|
|
159
175
|
end
|
160
176
|
|
161
177
|
def stacktrace_interface_from(backtrace)
|
162
|
-
Backtrace.parse(backtrace).lines.reverse.each_with_object([]) do |line, memo|
|
178
|
+
Backtrace.parse(backtrace, { configuration: configuration }).lines.reverse.each_with_object([]) do |line, memo|
|
163
179
|
frame = StacktraceInterface::Frame.new
|
164
180
|
frame.abs_path = line.file if line.file
|
165
181
|
frame.function = line.method if line.method
|
@@ -186,12 +202,6 @@ module Raven
|
|
186
202
|
|
187
203
|
private
|
188
204
|
|
189
|
-
def copy_initial_state
|
190
|
-
self.configuration = Raven.configuration
|
191
|
-
self.breadcrumbs = Raven.breadcrumbs
|
192
|
-
self.context = Raven.context
|
193
|
-
end
|
194
|
-
|
195
205
|
def set_core_attributes_from_configuration
|
196
206
|
self.server_name ||= configuration.server_name
|
197
207
|
self.release ||= configuration.release
|
@@ -216,6 +226,10 @@ module Raven
|
|
216
226
|
int.from_rack(context.rack_env)
|
217
227
|
end
|
218
228
|
context.user[:ip_address] = calculate_real_ip_from_rack
|
229
|
+
|
230
|
+
if request_id = Utils::RequestId.read_from(context.rack_env)
|
231
|
+
context.tags[:request_id] = request_id
|
232
|
+
end
|
219
233
|
end
|
220
234
|
|
221
235
|
# When behind a proxy (or if the user is using a proxy), we can't use
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module DeprecationHelper
|
2
|
+
def self.deprecate_dasherized_filename(correct_filename)
|
3
|
+
warn "[Deprecation Warning] Dasherized filename \"#{correct_filename.gsub('_', '-')}\" is deprecated and will be removed in 4.0; use \"#{correct_filename}\" instead" # rubocop:disable Style/LineLength
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.deprecate_old_breadcrumbs_configuration(logger)
|
7
|
+
deprecated_usage =
|
8
|
+
if logger == :sentry_logger
|
9
|
+
"require \"raven/breadcrumbs/logger\""
|
10
|
+
else
|
11
|
+
"Raven.configuration.rails_activesupport_breadcrumbs = true"
|
12
|
+
end
|
13
|
+
recommended_usage = "Raven.configuration.breadcrumbs_logger = :#{logger}"
|
14
|
+
|
15
|
+
warn "[Deprecation Warning] The way you enable breadcrumbs logger (#{deprecated_usage}) is deprecated and will be removed in 4.0; use '#{recommended_usage}' instead" # rubocop:disable Style/LineLength
|
16
|
+
end
|
17
|
+
end
|
data/lib/raven/instance.rb
CHANGED
@@ -77,7 +77,7 @@ module Raven
|
|
77
77
|
# Send an event to the configured Sentry server
|
78
78
|
#
|
79
79
|
# @example
|
80
|
-
# evt = Raven::Event.new(:message => "An
|
80
|
+
# evt = Raven::Event.new(:message => "An errore)
|
81
81
|
# Raven.send_event(evt)
|
82
82
|
def send_event(event, hint = nil)
|
83
83
|
client.send_event(event, hint)
|
@@ -114,6 +114,8 @@ module Raven
|
|
114
114
|
options = options.deep_dup
|
115
115
|
options[:configuration] = configuration
|
116
116
|
options[:context] = context
|
117
|
+
options[:breadcrumbs] = breadcrumbs
|
118
|
+
|
117
119
|
if evt = Event.send("from_" + message_or_exc, obj, options)
|
118
120
|
yield evt if block_given?
|
119
121
|
if configuration.async?
|
@@ -174,7 +176,18 @@ module Raven
|
|
174
176
|
# @example
|
175
177
|
# Raven.user_context('id' => 1, 'email' => 'foo@example.com')
|
176
178
|
def user_context(options = nil)
|
177
|
-
context.user
|
179
|
+
original_user_context = context.user
|
180
|
+
|
181
|
+
if options
|
182
|
+
context.user.merge!(options)
|
183
|
+
else
|
184
|
+
context.user = {}
|
185
|
+
end
|
186
|
+
|
187
|
+
yield if block_given?
|
188
|
+
context.user
|
189
|
+
ensure
|
190
|
+
context.user = original_user_context if block_given?
|
178
191
|
end
|
179
192
|
|
180
193
|
# Bind tags context. Merges with existing context (if any).
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'delayed_job'
|
2
|
+
require 'raven/utils/context_filter'
|
2
3
|
|
3
4
|
module Delayed
|
4
5
|
module Plugins
|
@@ -29,7 +30,7 @@ module Delayed
|
|
29
30
|
extra[:handler] = job.handler[0...1000] if job.handler
|
30
31
|
|
31
32
|
if job.respond_to?('payload_object') && job.payload_object.respond_to?('job_data')
|
32
|
-
extra[:active_job] = job.payload_object.job_data
|
33
|
+
extra[:active_job] = ::Raven::Utils::ContextFilter.filter_context(job.payload_object.job_data)
|
33
34
|
end
|
34
35
|
::Raven.capture_exception(e,
|
35
36
|
:logger => 'delayed_job',
|