sentry-raven 1.1.0 → 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 +5 -5
- data/.craft.yml +19 -0
- data/.scripts/bump-version.rb +5 -0
- data/CHANGELOG.md +703 -0
- data/Gemfile +37 -0
- data/Makefile +3 -0
- data/README.md +116 -18
- data/Rakefile +30 -0
- data/exe/raven +32 -0
- data/lib/raven/backtrace.rb +17 -8
- data/lib/raven/base.rb +45 -194
- data/lib/raven/breadcrumbs/active_support_logger.rb +25 -0
- data/lib/raven/breadcrumbs/logger.rb +3 -0
- data/lib/raven/breadcrumbs/sentry_logger.rb +73 -0
- data/lib/raven/breadcrumbs.rb +76 -0
- data/lib/raven/cli.rb +31 -39
- data/lib/raven/client.rb +45 -32
- data/lib/raven/configuration.rb +427 -130
- data/lib/raven/context.rb +33 -6
- data/lib/raven/core_ext/object/deep_dup.rb +57 -0
- data/lib/raven/core_ext/object/duplicable.rb +153 -0
- data/lib/raven/event.rb +194 -206
- data/lib/raven/helpers/deprecation_helper.rb +17 -0
- data/lib/raven/instance.rb +249 -0
- data/lib/raven/integrations/delayed_job.rb +25 -23
- data/lib/raven/integrations/rack-timeout.rb +22 -0
- data/lib/raven/integrations/rack.rb +40 -24
- data/lib/raven/integrations/rails/active_job.rb +52 -20
- data/lib/raven/integrations/rails/backtrace_cleaner.rb +29 -0
- data/lib/raven/integrations/rails/controller_transaction.rb +13 -0
- data/lib/raven/integrations/rails/overrides/debug_exceptions_catcher.rb +2 -2
- data/lib/raven/integrations/rails.rb +39 -7
- data/lib/raven/integrations/rake.rb +7 -2
- data/lib/raven/integrations/sidekiq/cleanup_middleware.rb +13 -0
- data/lib/raven/integrations/sidekiq/error_handler.rb +38 -0
- data/lib/raven/integrations/sidekiq.rb +6 -48
- data/lib/raven/integrations/tasks.rb +1 -1
- data/lib/raven/interface.rb +25 -0
- data/lib/raven/interfaces/exception.rb +5 -8
- data/lib/raven/interfaces/http.rb +5 -12
- data/lib/raven/interfaces/message.rb +10 -6
- data/lib/raven/interfaces/single_exception.rb +1 -5
- data/lib/raven/interfaces/stack_trace.rb +23 -30
- data/lib/raven/linecache.rb +35 -23
- data/lib/raven/logger.rb +13 -16
- data/lib/raven/processor/cookies.rb +27 -7
- data/lib/raven/processor/http_headers.rb +55 -0
- data/lib/raven/processor/post_data.rb +16 -3
- data/lib/raven/processor/removecircularreferences.rb +12 -8
- data/lib/raven/processor/removestacktrace.rb +17 -6
- data/lib/raven/processor/sanitizedata.rb +92 -37
- data/lib/raven/processor/utf8conversion.rb +39 -14
- data/lib/raven/processor.rb +5 -1
- data/lib/raven/transports/http.rb +31 -22
- data/lib/raven/transports/stdout.rb +20 -0
- data/lib/raven/transports.rb +6 -10
- data/lib/raven/utils/context_filter.rb +42 -0
- data/lib/raven/utils/deep_merge.rb +6 -12
- data/lib/raven/utils/exception_cause_chain.rb +20 -0
- data/lib/raven/utils/real_ip.rb +62 -0
- data/lib/raven/utils/request_id.rb +16 -0
- data/lib/raven/version.rb +2 -1
- data/lib/sentry-raven-without-integrations.rb +6 -1
- data/lib/sentry_raven_without_integrations.rb +1 -0
- data/sentry-raven.gemspec +28 -0
- metadata +44 -127
- data/lib/raven/error.rb +0 -4
- data/lib/raven/interfaces.rb +0 -34
- data/lib/raven/okjson.rb +0 -614
|
@@ -4,6 +4,9 @@ module Raven
|
|
|
4
4
|
class Rails < ::Rails::Railtie
|
|
5
5
|
require 'raven/integrations/rails/overrides/streaming_reporter'
|
|
6
6
|
require 'raven/integrations/rails/controller_methods'
|
|
7
|
+
require 'raven/integrations/rails/controller_transaction'
|
|
8
|
+
require 'raven/integrations/rails/backtrace_cleaner'
|
|
9
|
+
require 'raven/integrations/rack'
|
|
7
10
|
|
|
8
11
|
initializer "raven.use_rack_middleware" do |app|
|
|
9
12
|
app.config.middleware.insert 0, Raven::Rack
|
|
@@ -12,27 +15,45 @@ module Raven
|
|
|
12
15
|
initializer 'raven.action_controller' do
|
|
13
16
|
ActiveSupport.on_load :action_controller do
|
|
14
17
|
include Raven::Rails::ControllerMethods
|
|
18
|
+
include Raven::Rails::ControllerTransaction
|
|
15
19
|
if ::Rails::VERSION::STRING >= "4.0.0"
|
|
16
|
-
Raven.
|
|
20
|
+
Raven.safely_prepend(
|
|
21
|
+
"StreamingReporter",
|
|
22
|
+
:from => Raven::Rails::Overrides,
|
|
23
|
+
:to => ActionController::Live
|
|
24
|
+
)
|
|
17
25
|
end
|
|
18
26
|
end
|
|
19
27
|
end
|
|
20
28
|
|
|
21
29
|
initializer 'raven.action_view' do
|
|
22
30
|
ActiveSupport.on_load :action_view do
|
|
23
|
-
Raven.
|
|
31
|
+
Raven.safely_prepend(
|
|
32
|
+
"StreamingReporter",
|
|
33
|
+
:from => Raven::Rails::Overrides,
|
|
34
|
+
:to => ActionView::StreamingTemplateRenderer::Body
|
|
35
|
+
)
|
|
24
36
|
end
|
|
25
37
|
end
|
|
26
38
|
|
|
27
39
|
config.before_initialize do
|
|
28
|
-
Raven.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
40
|
+
Raven.configuration.logger = ::Rails.logger
|
|
41
|
+
|
|
42
|
+
backtrace_cleaner = Raven::Rails::BacktraceCleaner.new
|
|
43
|
+
|
|
44
|
+
Raven.configuration.backtrace_cleanup_callback = lambda do |backtrace|
|
|
45
|
+
backtrace_cleaner.clean(backtrace)
|
|
32
46
|
end
|
|
33
47
|
end
|
|
34
48
|
|
|
35
49
|
config.after_initialize do
|
|
50
|
+
if Raven.configuration.breadcrumbs_logger.include?(:active_support_logger) ||
|
|
51
|
+
Raven.configuration.rails_activesupport_breadcrumbs
|
|
52
|
+
|
|
53
|
+
require 'raven/breadcrumbs/active_support_logger'
|
|
54
|
+
Raven::Breadcrumbs::ActiveSupportLogger.inject
|
|
55
|
+
end
|
|
56
|
+
|
|
36
57
|
if Raven.configuration.rails_report_rescued_exceptions
|
|
37
58
|
require 'raven/integrations/rails/overrides/debug_exceptions_catcher'
|
|
38
59
|
if defined?(::ActionDispatch::DebugExceptions)
|
|
@@ -40,7 +61,18 @@ module Raven
|
|
|
40
61
|
elsif defined?(::ActionDispatch::ShowExceptions)
|
|
41
62
|
exceptions_class = ::ActionDispatch::ShowExceptions
|
|
42
63
|
end
|
|
43
|
-
|
|
64
|
+
|
|
65
|
+
Raven.safely_prepend(
|
|
66
|
+
"DebugExceptionsCatcher",
|
|
67
|
+
:from => Raven::Rails::Overrides,
|
|
68
|
+
:to => exceptions_class
|
|
69
|
+
)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
initializer 'raven.active_job' do
|
|
74
|
+
ActiveSupport.on_load :active_job do
|
|
75
|
+
require 'raven/integrations/rails/active_job'
|
|
44
76
|
end
|
|
45
77
|
end
|
|
46
78
|
|
|
@@ -4,9 +4,14 @@ require 'raven/integrations/tasks'
|
|
|
4
4
|
|
|
5
5
|
module Rake
|
|
6
6
|
class Application
|
|
7
|
-
alias
|
|
7
|
+
alias orig_display_error_messsage display_error_message
|
|
8
8
|
def display_error_message(ex)
|
|
9
|
-
Raven.capture_exception
|
|
9
|
+
Raven.capture_exception(
|
|
10
|
+
ex,
|
|
11
|
+
:transaction => top_level_tasks.join(' '),
|
|
12
|
+
:logger => 'rake',
|
|
13
|
+
:tags => { 'rake_task' => top_level_tasks.join(' ') }
|
|
14
|
+
)
|
|
10
15
|
orig_display_error_messsage(ex)
|
|
11
16
|
end
|
|
12
17
|
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Raven
|
|
2
|
+
module Sidekiq
|
|
3
|
+
class CleanupMiddleware
|
|
4
|
+
def call(_worker, job, queue)
|
|
5
|
+
Raven.context.transaction.push "Sidekiq/#{job['class']}"
|
|
6
|
+
Raven.extra_context(:sidekiq => job.merge("queue" => queue))
|
|
7
|
+
yield
|
|
8
|
+
Context.clear!
|
|
9
|
+
BreadcrumbBuffer.clear!
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'raven/utils/context_filter'
|
|
2
|
+
|
|
3
|
+
module Raven
|
|
4
|
+
module Sidekiq
|
|
5
|
+
class ErrorHandler
|
|
6
|
+
SIDEKIQ_NAME = "Sidekiq".freeze
|
|
7
|
+
|
|
8
|
+
def call(ex, context)
|
|
9
|
+
context = Utils::ContextFilter.filter_context(context)
|
|
10
|
+
Raven.context.transaction.push transaction_from_context(context)
|
|
11
|
+
Raven.capture_exception(
|
|
12
|
+
ex,
|
|
13
|
+
:message => ex.message,
|
|
14
|
+
:extra => { :sidekiq => context }
|
|
15
|
+
)
|
|
16
|
+
Context.clear!
|
|
17
|
+
BreadcrumbBuffer.clear!
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
# this will change in the future:
|
|
23
|
+
# https://github.com/mperham/sidekiq/pull/3161
|
|
24
|
+
def transaction_from_context(context)
|
|
25
|
+
classname = (context["wrapped"] || context["class"] ||
|
|
26
|
+
(context[:job] && (context[:job]["wrapped"] || context[:job]["class"]))
|
|
27
|
+
)
|
|
28
|
+
if classname
|
|
29
|
+
"#{SIDEKIQ_NAME}/#{classname}"
|
|
30
|
+
elsif context[:event]
|
|
31
|
+
"#{SIDEKIQ_NAME}/#{context[:event]}"
|
|
32
|
+
else
|
|
33
|
+
SIDEKIQ_NAME
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -1,55 +1,13 @@
|
|
|
1
1
|
require 'time'
|
|
2
2
|
require 'sidekiq'
|
|
3
|
+
require 'raven/integrations/sidekiq/cleanup_middleware'
|
|
4
|
+
require 'raven/integrations/sidekiq/error_handler'
|
|
3
5
|
|
|
4
|
-
|
|
5
|
-
class Sidekiq
|
|
6
|
-
def call(_worker, msg, _queue)
|
|
7
|
-
started_at = Time.now
|
|
8
|
-
yield
|
|
9
|
-
rescue Exception => ex
|
|
10
|
-
Raven.capture_exception(ex, :extra => { :sidekiq => msg },
|
|
11
|
-
:time_spent => Time.now-started_at)
|
|
12
|
-
raise
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
if Sidekiq::VERSION < '3'
|
|
18
|
-
# old behavior
|
|
19
|
-
::Sidekiq.configure_server do |config|
|
|
20
|
-
config.server_middleware do |chain|
|
|
21
|
-
chain.add ::Raven::Sidekiq
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
else
|
|
6
|
+
if Sidekiq::VERSION > '3'
|
|
25
7
|
Sidekiq.configure_server do |config|
|
|
26
|
-
config.error_handlers <<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
})
|
|
8
|
+
config.error_handlers << Raven::Sidekiq::ErrorHandler.new
|
|
9
|
+
config.server_middleware do |chain|
|
|
10
|
+
chain.add Raven::Sidekiq::CleanupMiddleware
|
|
30
11
|
end
|
|
31
12
|
end
|
|
32
13
|
end
|
|
33
|
-
|
|
34
|
-
def filter_context(context)
|
|
35
|
-
case context
|
|
36
|
-
when Array
|
|
37
|
-
context.map { |arg| filter_context(arg) }
|
|
38
|
-
when Hash
|
|
39
|
-
Hash[context.map { |key, value| filter_context_hash(key, value) }]
|
|
40
|
-
else
|
|
41
|
-
context
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def filter_context_hash(key, value)
|
|
46
|
-
# Strip any `_aj` prefixes from keys.
|
|
47
|
-
# These keys come from an internal serialized object from ActiveJob.
|
|
48
|
-
# Internally, there are a subset of keys that ActiveJob references, but
|
|
49
|
-
# these are declared as private, and I don't think it's wise
|
|
50
|
-
# to keep chasing what this list is. But they all use a common prefix, so
|
|
51
|
-
# we want to strip this becuase ActiveJob will complain.
|
|
52
|
-
# e.g.: _aj_globalid -> _globalid
|
|
53
|
-
(key = key[3..-1]) if key [0..3] == "_aj_"
|
|
54
|
-
[key, filter_context(value)]
|
|
55
|
-
end
|
|
@@ -4,7 +4,7 @@ require 'raven/cli'
|
|
|
4
4
|
namespace :raven do
|
|
5
5
|
desc "Send a test event to the remote Sentry server"
|
|
6
6
|
task :test, [:dsn] do |_t, args|
|
|
7
|
-
Rake::Task["environment"].invoke if
|
|
7
|
+
Rake::Task["environment"].invoke if Rake::Task.tasks.map(&:to_s).include?("environment")
|
|
8
8
|
|
|
9
9
|
Raven::CLI.test(args.dsn)
|
|
10
10
|
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Raven
|
|
2
|
+
class Interface
|
|
3
|
+
def initialize(attributes = nil)
|
|
4
|
+
attributes&.each do |attr, value|
|
|
5
|
+
public_send "#{attr}=", value
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
yield self if block_given?
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.inherited(klass)
|
|
12
|
+
name = klass.name.split("::").last.downcase.gsub("interface", "")
|
|
13
|
+
registered[name.to_sym] = klass
|
|
14
|
+
super
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.registered
|
|
18
|
+
@@registered ||= {} # rubocop:disable Style/ClassVars
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def to_hash
|
|
22
|
+
Hash[instance_variables.map { |name| [name[1..-1].to_sym, instance_variable_get(name)] }]
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
require 'raven/interfaces'
|
|
2
|
-
|
|
3
1
|
module Raven
|
|
4
2
|
class ExceptionInterface < Interface
|
|
5
|
-
name 'exception'
|
|
6
3
|
attr_accessor :values
|
|
7
4
|
|
|
5
|
+
def self.sentry_alias
|
|
6
|
+
:exception
|
|
7
|
+
end
|
|
8
|
+
|
|
8
9
|
def to_hash(*args)
|
|
9
10
|
data = super(*args)
|
|
10
|
-
if data[:values]
|
|
11
|
-
data[:values] = data[:values].map(&:to_hash)
|
|
12
|
-
end
|
|
11
|
+
data[:values] = data[:values].map(&:to_hash) if data[:values]
|
|
13
12
|
data
|
|
14
13
|
end
|
|
15
14
|
end
|
|
16
|
-
|
|
17
|
-
register_interface :exception => ExceptionInterface
|
|
18
15
|
end
|
|
@@ -1,15 +1,6 @@
|
|
|
1
|
-
require 'raven/interfaces'
|
|
2
|
-
|
|
3
1
|
module Raven
|
|
4
2
|
class HttpInterface < Interface
|
|
5
|
-
|
|
6
|
-
attr_accessor :url
|
|
7
|
-
attr_accessor :method
|
|
8
|
-
attr_accessor :data
|
|
9
|
-
attr_accessor :query_string
|
|
10
|
-
attr_accessor :cookies
|
|
11
|
-
attr_accessor :headers
|
|
12
|
-
attr_accessor :env
|
|
3
|
+
attr_accessor :url, :method, :data, :query_string, :cookies, :headers, :env
|
|
13
4
|
|
|
14
5
|
def initialize(*arguments)
|
|
15
6
|
self.headers = {}
|
|
@@ -17,7 +8,9 @@ module Raven
|
|
|
17
8
|
self.cookies = nil
|
|
18
9
|
super(*arguments)
|
|
19
10
|
end
|
|
20
|
-
end
|
|
21
11
|
|
|
22
|
-
|
|
12
|
+
def self.sentry_alias
|
|
13
|
+
:request
|
|
14
|
+
end
|
|
15
|
+
end
|
|
23
16
|
end
|
|
@@ -1,16 +1,20 @@
|
|
|
1
|
-
require 'raven/
|
|
1
|
+
require 'raven/interface'
|
|
2
2
|
|
|
3
3
|
module Raven
|
|
4
4
|
class MessageInterface < Interface
|
|
5
|
-
|
|
6
|
-
attr_accessor :message
|
|
7
|
-
attr_accessor :params
|
|
5
|
+
attr_accessor :message, :params
|
|
8
6
|
|
|
9
7
|
def initialize(*arguments)
|
|
10
8
|
self.params = []
|
|
11
9
|
super(*arguments)
|
|
12
10
|
end
|
|
13
|
-
end
|
|
14
11
|
|
|
15
|
-
|
|
12
|
+
def unformatted_message
|
|
13
|
+
Array(params).empty? ? message : message % params
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.sentry_alias
|
|
17
|
+
:logentry
|
|
18
|
+
end
|
|
19
|
+
end
|
|
16
20
|
end
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'raven/interfaces'
|
|
2
|
-
|
|
3
1
|
module Raven
|
|
4
2
|
class SingleExceptionInterface < Interface
|
|
5
3
|
attr_accessor :type
|
|
@@ -9,9 +7,7 @@ module Raven
|
|
|
9
7
|
|
|
10
8
|
def to_hash(*args)
|
|
11
9
|
data = super(*args)
|
|
12
|
-
if data[:stacktrace]
|
|
13
|
-
data[:stacktrace] = data[:stacktrace].to_hash
|
|
14
|
-
end
|
|
10
|
+
data[:stacktrace] = data[:stacktrace].to_hash if data[:stacktrace]
|
|
15
11
|
data
|
|
16
12
|
end
|
|
17
13
|
end
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
require 'raven/interfaces'
|
|
2
|
-
|
|
3
1
|
module Raven
|
|
4
2
|
class StacktraceInterface < Interface
|
|
5
|
-
name 'stacktrace'
|
|
6
3
|
attr_accessor :frames
|
|
7
4
|
|
|
8
5
|
def initialize(*arguments)
|
|
9
|
-
self.frames = []
|
|
10
6
|
super(*arguments)
|
|
11
7
|
end
|
|
12
8
|
|
|
9
|
+
def self.sentry_alias
|
|
10
|
+
:stacktrace
|
|
11
|
+
end
|
|
12
|
+
|
|
13
13
|
def to_hash(*args)
|
|
14
14
|
data = super(*args)
|
|
15
15
|
data[:frames] = data[:frames].map(&:to_hash)
|
|
@@ -18,23 +18,16 @@ module Raven
|
|
|
18
18
|
|
|
19
19
|
# Not actually an interface, but I want to use the same style
|
|
20
20
|
class Frame < Interface
|
|
21
|
-
attr_accessor :abs_path
|
|
22
|
-
|
|
23
|
-
attr_accessor :vars
|
|
24
|
-
attr_accessor :pre_context
|
|
25
|
-
attr_accessor :post_context
|
|
26
|
-
attr_accessor :context_line
|
|
27
|
-
attr_accessor :module
|
|
28
|
-
attr_accessor :lineno
|
|
29
|
-
attr_accessor :in_app
|
|
21
|
+
attr_accessor :abs_path, :context_line, :function, :in_app,
|
|
22
|
+
:lineno, :module, :pre_context, :post_context, :vars
|
|
30
23
|
|
|
31
24
|
def initialize(*arguments)
|
|
32
|
-
self.vars, self.pre_context, self.post_context = [], [], []
|
|
33
25
|
super(*arguments)
|
|
34
26
|
end
|
|
35
27
|
|
|
36
28
|
def filename
|
|
37
|
-
return
|
|
29
|
+
return if abs_path.nil?
|
|
30
|
+
return @filename if instance_variable_defined?(:@filename)
|
|
38
31
|
|
|
39
32
|
prefix =
|
|
40
33
|
if under_project_root? && in_app
|
|
@@ -45,32 +38,32 @@ module Raven
|
|
|
45
38
|
longest_load_path
|
|
46
39
|
end
|
|
47
40
|
|
|
48
|
-
prefix ?
|
|
41
|
+
@filename = prefix ? abs_path[prefix.to_s.chomp(File::SEPARATOR).length + 1..-1] : abs_path
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def to_hash(*args)
|
|
45
|
+
data = super(*args)
|
|
46
|
+
data[:filename] = filename
|
|
47
|
+
data.delete(:vars) unless vars && !vars.empty?
|
|
48
|
+
data.delete(:pre_context) unless pre_context && !pre_context.empty?
|
|
49
|
+
data.delete(:post_context) unless post_context && !post_context.empty?
|
|
50
|
+
data.delete(:context_line) unless context_line && !context_line.empty?
|
|
51
|
+
data
|
|
49
52
|
end
|
|
50
53
|
|
|
54
|
+
private
|
|
55
|
+
|
|
51
56
|
def under_project_root?
|
|
52
57
|
project_root && abs_path.start_with?(project_root)
|
|
53
58
|
end
|
|
54
59
|
|
|
55
60
|
def project_root
|
|
56
|
-
@project_root ||= Raven.configuration.project_root
|
|
61
|
+
@project_root ||= Raven.configuration.project_root&.to_s
|
|
57
62
|
end
|
|
58
63
|
|
|
59
64
|
def longest_load_path
|
|
60
|
-
$LOAD_PATH.select { |
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def to_hash(*args)
|
|
64
|
-
data = super(*args)
|
|
65
|
-
data[:filename] = self.filename
|
|
66
|
-
data.delete(:vars) unless self.vars && !self.vars.empty?
|
|
67
|
-
data.delete(:pre_context) unless self.pre_context && !self.pre_context.empty?
|
|
68
|
-
data.delete(:post_context) unless self.post_context && !self.post_context.empty?
|
|
69
|
-
data.delete(:context_line) unless self.context_line && !self.context_line.empty?
|
|
70
|
-
data
|
|
65
|
+
$LOAD_PATH.select { |path| abs_path.start_with?(path.to_s) }.max_by(&:size)
|
|
71
66
|
end
|
|
72
67
|
end
|
|
73
68
|
end
|
|
74
|
-
|
|
75
|
-
register_interface :stack_trace => StacktraceInterface
|
|
76
69
|
end
|
data/lib/raven/linecache.rb
CHANGED
|
@@ -1,32 +1,44 @@
|
|
|
1
|
-
# A much simpler source line cacher because linecache sucks at platform compat
|
|
2
|
-
|
|
3
1
|
module Raven
|
|
4
2
|
class LineCache
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
# variable?
|
|
9
|
-
CACHE = {} # rubocop:disable Style/MutableConstant
|
|
10
|
-
|
|
11
|
-
def is_valid_file(path)
|
|
12
|
-
lines = getlines(path)
|
|
13
|
-
!lines.nil?
|
|
14
|
-
end
|
|
3
|
+
def initialize
|
|
4
|
+
@cache = {}
|
|
5
|
+
end
|
|
15
6
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
7
|
+
# Any linecache you provide to Raven must implement this method.
|
|
8
|
+
# Returns an Array of Strings representing the lines in the source
|
|
9
|
+
# file. The number of lines retrieved is (2 * context) + 1, the middle
|
|
10
|
+
# line should be the line requested by lineno. See specs for more information.
|
|
11
|
+
def get_file_context(filename, lineno, context)
|
|
12
|
+
return nil, nil, nil unless valid_path?(filename)
|
|
13
|
+
|
|
14
|
+
lines = Array.new(2 * context + 1) do |i|
|
|
15
|
+
getline(filename, lineno - context + i)
|
|
22
16
|
end
|
|
17
|
+
[lines[0..(context - 1)], lines[context], lines[(context + 1)..-1]]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
def valid_path?(path)
|
|
23
|
+
lines = getlines(path)
|
|
24
|
+
!lines.nil?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def getlines(path)
|
|
28
|
+
@cache[path] ||= begin
|
|
29
|
+
IO.readlines(path)
|
|
30
|
+
rescue
|
|
31
|
+
nil
|
|
29
32
|
end
|
|
30
33
|
end
|
|
34
|
+
|
|
35
|
+
def getline(path, n)
|
|
36
|
+
return nil if n < 1
|
|
37
|
+
|
|
38
|
+
lines = getlines(path)
|
|
39
|
+
return nil if lines.nil?
|
|
40
|
+
|
|
41
|
+
lines[n - 1]
|
|
42
|
+
end
|
|
31
43
|
end
|
|
32
44
|
end
|
data/lib/raven/logger.rb
CHANGED
|
@@ -1,22 +1,19 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
module Raven
|
|
3
|
-
class Logger
|
|
4
|
-
LOG_PREFIX = "** [Raven] ".freeze
|
|
5
2
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
].each do |level|
|
|
13
|
-
define_method level do |*args, &block|
|
|
14
|
-
msg = args[0] # Block-level default args is a 1.9 feature
|
|
15
|
-
msg ||= block.call if block
|
|
16
|
-
logger = Raven.configuration[:logger]
|
|
17
|
-
logger = ::Logger.new(STDOUT) if logger.nil?
|
|
3
|
+
require 'logger'
|
|
4
|
+
|
|
5
|
+
module Raven
|
|
6
|
+
class Logger < ::Logger
|
|
7
|
+
LOG_PREFIX = "** [Raven] "
|
|
8
|
+
PROGNAME = "sentry"
|
|
18
9
|
|
|
19
|
-
|
|
10
|
+
def initialize(*)
|
|
11
|
+
super
|
|
12
|
+
@level = ::Logger::INFO
|
|
13
|
+
original_formatter = ::Logger::Formatter.new
|
|
14
|
+
@default_formatter = proc do |severity, datetime, _progname, msg|
|
|
15
|
+
msg = "#{LOG_PREFIX}#{msg}"
|
|
16
|
+
original_formatter.call(severity, datetime, PROGNAME, msg)
|
|
20
17
|
end
|
|
21
18
|
end
|
|
22
19
|
end
|
|
@@ -1,16 +1,36 @@
|
|
|
1
1
|
module Raven
|
|
2
2
|
class Processor::Cookies < Processor
|
|
3
3
|
def process(data)
|
|
4
|
-
if data[:request]
|
|
5
|
-
|
|
6
|
-
data[:request][:cookies] = nil if data[:request][:cookies]
|
|
4
|
+
process_if_symbol_keys(data) if data[:request]
|
|
5
|
+
process_if_string_keys(data) if data["request"]
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
data
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def process_if_symbol_keys(data)
|
|
13
|
+
if cookies = data.dig(:request, :cookies)
|
|
14
|
+
data[:request][:cookies] = generate_masked_cookies(cookies)
|
|
11
15
|
end
|
|
12
16
|
|
|
13
|
-
data
|
|
17
|
+
if cookies_header = data[:request][:headers]["Cookie"]
|
|
18
|
+
data[:request][:headers]["Cookie"] = generate_masked_cookies(cookies_header)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def process_if_string_keys(data)
|
|
23
|
+
if cookies = data.dig("request", "cookies")
|
|
24
|
+
data["request"]["cookies"] = generate_masked_cookies(cookies)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
if cookies_header = data.dig("request", "headers", "Cookie")
|
|
28
|
+
data["request"]["headers"]["Cookie"] = generate_masked_cookies(cookies_header)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def generate_masked_cookies(cookies)
|
|
33
|
+
cookies.merge(cookies) { STRING_MASK } if cookies.respond_to?(:merge)
|
|
14
34
|
end
|
|
15
35
|
end
|
|
16
36
|
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module Raven
|
|
2
|
+
class Processor::HTTPHeaders < Processor
|
|
3
|
+
DEFAULT_FIELDS = ["Authorization"].freeze
|
|
4
|
+
|
|
5
|
+
attr_accessor :sanitize_http_headers
|
|
6
|
+
|
|
7
|
+
def initialize(client)
|
|
8
|
+
super
|
|
9
|
+
self.sanitize_http_headers = client.configuration.sanitize_http_headers
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def process(data)
|
|
13
|
+
process_if_symbol_keys(data) if data[:request]
|
|
14
|
+
process_if_string_keys(data) if data["request"]
|
|
15
|
+
|
|
16
|
+
data
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def process_if_symbol_keys(data)
|
|
22
|
+
return unless data[:request][:headers]
|
|
23
|
+
|
|
24
|
+
data[:request][:headers].keys.select { |k| fields_re.match(k.to_s) }.each do |k|
|
|
25
|
+
data[:request][:headers][k] = STRING_MASK
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def process_if_string_keys(data)
|
|
30
|
+
return unless data["request"]["headers"]
|
|
31
|
+
|
|
32
|
+
data["request"]["headers"].keys.select { |k| fields_re.match(k) }.each do |k|
|
|
33
|
+
data["request"]["headers"][k] = STRING_MASK
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def matches_regexes?(k)
|
|
38
|
+
fields_re.match(k.to_s)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def fields_re
|
|
42
|
+
@fields_re ||= /#{(DEFAULT_FIELDS | sanitize_http_headers).map do |f|
|
|
43
|
+
use_boundary?(f) ? "\\b#{f}\\b" : f
|
|
44
|
+
end.join("|")}/i
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def use_boundary?(string)
|
|
48
|
+
!DEFAULT_FIELDS.include?(string) && !special_characters?(string)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def special_characters?(string)
|
|
52
|
+
REGEX_SPECIAL_CHARACTERS.select { |r| string.include?(r) }.any?
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
module Raven
|
|
2
2
|
class Processor::PostData < Processor
|
|
3
3
|
def process(data)
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
end
|
|
4
|
+
process_if_symbol_keys(data) if data[:request]
|
|
5
|
+
process_if_string_keys(data) if data["request"]
|
|
7
6
|
|
|
8
7
|
data
|
|
9
8
|
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def process_if_symbol_keys(data)
|
|
13
|
+
return unless data[:request][:method] == "POST"
|
|
14
|
+
|
|
15
|
+
data[:request][:data] = STRING_MASK
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def process_if_string_keys(data)
|
|
19
|
+
return unless data["request"]["method"] == "POST"
|
|
20
|
+
|
|
21
|
+
data["request"]["data"] = STRING_MASK
|
|
22
|
+
end
|
|
10
23
|
end
|
|
11
24
|
end
|