sentry-raven 2.1.3 → 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 +16 -6
- data/lib/raven/base.rb +17 -4
- data/lib/raven/breadcrumbs/{activesupport.rb → active_support_logger.rb} +9 -3
- data/lib/raven/breadcrumbs/logger.rb +2 -92
- data/lib/raven/breadcrumbs/sentry_logger.rb +73 -0
- data/lib/raven/breadcrumbs.rb +3 -1
- data/lib/raven/cli.rb +31 -43
- data/lib/raven/client.rb +39 -17
- data/lib/raven/configuration.rb +277 -37
- data/lib/raven/context.rb +17 -11
- 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 +172 -233
- data/lib/raven/helpers/deprecation_helper.rb +17 -0
- data/lib/raven/instance.rb +51 -25
- data/lib/raven/integrations/delayed_job.rb +18 -18
- data/lib/raven/integrations/rack-timeout.rb +11 -5
- data/lib/raven/integrations/rack.rb +36 -19
- 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 +24 -8
- data/lib/raven/integrations/rake.rb +6 -1
- 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 -57
- data/lib/raven/interface.rb +2 -2
- data/lib/raven/interfaces/exception.rb +0 -2
- data/lib/raven/interfaces/http.rb +0 -2
- data/lib/raven/interfaces/message.rb +1 -1
- data/lib/raven/interfaces/single_exception.rb +0 -2
- data/lib/raven/interfaces/stack_trace.rb +19 -27
- data/lib/raven/linecache.rb +34 -17
- data/lib/raven/logger.rb +11 -18
- data/lib/raven/processor/cookies.rb +27 -7
- data/lib/raven/processor/http_headers.rb +18 -5
- 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 +88 -29
- data/lib/raven/processor/utf8conversion.rb +39 -14
- data/lib/raven/processor.rb +1 -1
- data/lib/raven/transports/http.rb +29 -21
- data/lib/raven/transports/stdout.rb +20 -0
- data/lib/raven/transports.rb +4 -8
- 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 +1 -1
- data/lib/raven/utils/request_id.rb +16 -0
- data/lib/raven/version.rb +2 -2
- 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 +37 -103
- data/lib/raven/error.rb +0 -4
data/lib/raven/instance.rb
CHANGED
@@ -19,16 +19,15 @@ module Raven
|
|
19
19
|
# end
|
20
20
|
# end
|
21
21
|
class Instance
|
22
|
-
#
|
23
|
-
# Sentry server. Must respond to #send. See Raven::Client.
|
22
|
+
# See Raven::Client.
|
24
23
|
attr_writer :client
|
25
24
|
|
26
|
-
#
|
27
|
-
|
28
|
-
attr_writer :configuration
|
25
|
+
# See Raven::Configuration.
|
26
|
+
attr_accessor :configuration
|
29
27
|
|
30
|
-
def initialize(context = nil)
|
28
|
+
def initialize(context = nil, config = nil)
|
31
29
|
@context = @explicit_context = context
|
30
|
+
self.configuration = config || Configuration.new
|
32
31
|
end
|
33
32
|
|
34
33
|
def context
|
@@ -40,13 +39,7 @@ module Raven
|
|
40
39
|
end
|
41
40
|
|
42
41
|
def logger
|
43
|
-
|
44
|
-
end
|
45
|
-
|
46
|
-
# The configuration object.
|
47
|
-
# @see Raven.configure
|
48
|
-
def configuration
|
49
|
-
@configuration ||= Configuration.new
|
42
|
+
configuration.logger
|
50
43
|
end
|
51
44
|
|
52
45
|
# The client object is responsible for delivering formatted data to the
|
@@ -57,11 +50,13 @@ module Raven
|
|
57
50
|
|
58
51
|
# Tell the log that the client is good to go
|
59
52
|
def report_status
|
53
|
+
return unless configuration.enabled_in_current_env?
|
60
54
|
return if configuration.silence_ready
|
55
|
+
|
61
56
|
if configuration.capture_allowed?
|
62
57
|
logger.info "Raven #{VERSION} ready to catch errors"
|
63
58
|
else
|
64
|
-
logger.info "Raven #{VERSION} configured not to capture errors."
|
59
|
+
logger.info "Raven #{VERSION} configured not to capture errors: #{configuration.error_messages}"
|
65
60
|
end
|
66
61
|
end
|
67
62
|
|
@@ -82,10 +77,10 @@ module Raven
|
|
82
77
|
# Send an event to the configured Sentry server
|
83
78
|
#
|
84
79
|
# @example
|
85
|
-
# evt = Raven::Event.new(:message => "An
|
80
|
+
# evt = Raven::Event.new(:message => "An errore)
|
86
81
|
# Raven.send_event(evt)
|
87
|
-
def send_event(event)
|
88
|
-
client.send_event(event)
|
82
|
+
def send_event(event, hint = nil)
|
83
|
+
client.send_event(event, hint)
|
89
84
|
end
|
90
85
|
|
91
86
|
# Capture and process any exceptions from the given block.
|
@@ -111,30 +106,38 @@ module Raven
|
|
111
106
|
|
112
107
|
def capture_type(obj, options = {})
|
113
108
|
unless configuration.capture_allowed?(obj)
|
114
|
-
|
109
|
+
logger.debug("#{obj} excluded from capture: #{configuration.error_messages}")
|
115
110
|
return false
|
116
111
|
end
|
117
112
|
|
118
113
|
message_or_exc = obj.is_a?(String) ? "message" : "exception"
|
119
|
-
|
114
|
+
options = options.deep_dup
|
115
|
+
options[:configuration] = configuration
|
116
|
+
options[:context] = context
|
117
|
+
options[:breadcrumbs] = breadcrumbs
|
118
|
+
|
119
|
+
if evt = Event.send("from_" + message_or_exc, obj, options)
|
120
120
|
yield evt if block_given?
|
121
121
|
if configuration.async?
|
122
122
|
begin
|
123
123
|
# We have to convert to a JSON-like hash, because background job
|
124
124
|
# processors (esp ActiveJob) may not like weird types in the event hash
|
125
125
|
configuration.async.call(evt.to_json_compatible)
|
126
|
-
rescue =>
|
127
|
-
|
128
|
-
send_event(evt)
|
126
|
+
rescue => e
|
127
|
+
logger.error("async event sending failed: #{e.message}")
|
128
|
+
send_event(evt, make_hint(obj))
|
129
129
|
end
|
130
130
|
else
|
131
|
-
send_event(evt)
|
131
|
+
send_event(evt, make_hint(obj))
|
132
132
|
end
|
133
133
|
Thread.current["sentry_#{object_id}_last_event_id".to_sym] = evt.id
|
134
134
|
evt
|
135
135
|
end
|
136
136
|
end
|
137
137
|
|
138
|
+
alias capture_message capture_type
|
139
|
+
alias capture_exception capture_type
|
140
|
+
|
138
141
|
def last_event_id
|
139
142
|
Thread.current["sentry_#{object_id}_last_event_id".to_sym]
|
140
143
|
end
|
@@ -160,7 +163,7 @@ module Raven
|
|
160
163
|
# end
|
161
164
|
def annotate_exception(exc, options = {})
|
162
165
|
notes = (exc.instance_variable_defined?(:@__raven_context) && exc.instance_variable_get(:@__raven_context)) || {}
|
163
|
-
|
166
|
+
Raven::Utils::DeepMergeHash.deep_merge!(notes, options)
|
164
167
|
exc.instance_variable_set(:@__raven_context, notes)
|
165
168
|
exc
|
166
169
|
end
|
@@ -173,7 +176,18 @@ module Raven
|
|
173
176
|
# @example
|
174
177
|
# Raven.user_context('id' => 1, 'email' => 'foo@example.com')
|
175
178
|
def user_context(options = nil)
|
176
|
-
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?
|
177
191
|
end
|
178
192
|
|
179
193
|
# Bind tags context. Merges with existing context (if any).
|
@@ -185,6 +199,10 @@ module Raven
|
|
185
199
|
# Raven.tags_context('my_custom_tag' => 'tag_value')
|
186
200
|
def tags_context(options = nil)
|
187
201
|
context.tags.merge!(options || {})
|
202
|
+
yield if block_given?
|
203
|
+
context.tags
|
204
|
+
ensure
|
205
|
+
context.tags.delete_if { |k, _| options.keys.include? k } if block_given?
|
188
206
|
end
|
189
207
|
|
190
208
|
# Bind extra context. Merges with existing context (if any).
|
@@ -196,6 +214,10 @@ module Raven
|
|
196
214
|
# Raven.extra_context('my_custom_data' => 'value')
|
197
215
|
def extra_context(options = nil)
|
198
216
|
context.extra.merge!(options || {})
|
217
|
+
yield if block_given?
|
218
|
+
context.extra
|
219
|
+
ensure
|
220
|
+
context.extra.delete_if { |k, _| options.keys.include? k } if block_given?
|
199
221
|
end
|
200
222
|
|
201
223
|
def rack_context(env)
|
@@ -219,5 +241,9 @@ module Raven
|
|
219
241
|
end
|
220
242
|
end
|
221
243
|
end
|
244
|
+
|
245
|
+
def make_hint(obj)
|
246
|
+
obj.is_a?(String) ? { :exception => nil, :message => obj } : { :exception => obj, :message => nil }
|
247
|
+
end
|
222
248
|
end
|
223
249
|
end
|
@@ -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
|
@@ -8,40 +9,39 @@ module Delayed
|
|
8
9
|
begin
|
9
10
|
# Forward the call to the next callback in the callback chain
|
10
11
|
block.call(job, *args)
|
11
|
-
|
12
|
-
rescue Exception => exception
|
12
|
+
rescue Exception => e
|
13
13
|
# Log error to Sentry
|
14
14
|
extra = {
|
15
15
|
:delayed_job => {
|
16
|
-
:id
|
17
|
-
:priority
|
18
|
-
:attempts
|
19
|
-
:run_at
|
20
|
-
:locked_at
|
21
|
-
:locked_by
|
22
|
-
:queue
|
23
|
-
:created_at
|
16
|
+
:id => job.id.to_s,
|
17
|
+
:priority => job.priority,
|
18
|
+
:attempts => job.attempts,
|
19
|
+
:run_at => job.run_at,
|
20
|
+
:locked_at => job.locked_at,
|
21
|
+
:locked_by => job.locked_by,
|
22
|
+
:queue => job.queue,
|
23
|
+
:created_at => job.created_at
|
24
24
|
}
|
25
25
|
}
|
26
26
|
# last_error can be nil
|
27
|
-
extra[:last_error] = job.last_error[0...
|
27
|
+
extra[:last_error] = job.last_error[0...1000] if job.last_error
|
28
28
|
# handlers are YAML objects in strings, we definitely can't
|
29
29
|
# report all of that or the event will get truncated randomly
|
30
|
-
extra[:handler] = job.handler[0...
|
30
|
+
extra[:handler] = job.handler[0...1000] if job.handler
|
31
31
|
|
32
32
|
if job.respond_to?('payload_object') && job.payload_object.respond_to?('job_data')
|
33
|
-
extra[:active_job] = job.payload_object.job_data
|
33
|
+
extra[:active_job] = ::Raven::Utils::ContextFilter.filter_context(job.payload_object.job_data)
|
34
34
|
end
|
35
|
-
::Raven.capture_exception(
|
36
|
-
:logger
|
37
|
-
:tags
|
35
|
+
::Raven.capture_exception(e,
|
36
|
+
:logger => 'delayed_job',
|
37
|
+
:tags => {
|
38
38
|
:delayed_job_queue => job.queue,
|
39
|
-
:delayed_job_id => job.id
|
39
|
+
:delayed_job_id => job.id.to_s
|
40
40
|
},
|
41
41
|
:extra => extra)
|
42
42
|
|
43
43
|
# Make sure we propagate the failure!
|
44
|
-
raise
|
44
|
+
raise e
|
45
45
|
ensure
|
46
46
|
::Raven::Context.clear!
|
47
47
|
::Raven::BreadcrumbBuffer.clear!
|
@@ -1,6 +1,5 @@
|
|
1
|
-
# rubocop:disable Style/FileName
|
2
1
|
# We need to do this because of the way integration loading works
|
3
|
-
require "rack/timeout/base"
|
2
|
+
require "rack/timeout/base" unless defined?(Rack::Timeout)
|
4
3
|
|
5
4
|
# This integration is a good example of how to change how exceptions
|
6
5
|
# get grouped by Sentry's UI. Simply override #raven_context in
|
@@ -8,9 +7,16 @@ require "rack/timeout/base"
|
|
8
7
|
# that will distinguish exceptions in the way you desire.
|
9
8
|
module RackTimeoutExtensions
|
10
9
|
def raven_context
|
11
|
-
|
10
|
+
# Only rack-timeout 0.3.0+ provides the request environment, but we can't
|
11
|
+
# gate this based on a gem version constant because rack-timeout does
|
12
|
+
# not provide one.
|
13
|
+
if defined?(env)
|
14
|
+
{ :fingerprint => ["{{ default }}", env["REQUEST_URI"]] }
|
15
|
+
else
|
16
|
+
{}
|
17
|
+
end
|
12
18
|
end
|
13
19
|
end
|
14
20
|
|
15
|
-
Rack::Timeout::Error.include
|
16
|
-
Rack::Timeout::RequestTimeoutException.include
|
21
|
+
Rack::Timeout::Error.include(RackTimeoutExtensions)
|
22
|
+
Rack::Timeout::RequestTimeoutException.include(RackTimeoutExtensions)
|
@@ -45,6 +45,7 @@ module Raven
|
|
45
45
|
# callers
|
46
46
|
env['raven.requested_at'] = Time.now
|
47
47
|
Raven.rack_context(env)
|
48
|
+
Raven.context.transaction.push(env["PATH_INFO"]) if env["PATH_INFO"]
|
48
49
|
|
49
50
|
begin
|
50
51
|
response = @app.call(env)
|
@@ -73,47 +74,63 @@ module Raven
|
|
73
74
|
self.method = req.request_method
|
74
75
|
self.query_string = req.query_string
|
75
76
|
self.data = read_data_from(req)
|
77
|
+
self.cookies = req.cookies
|
76
78
|
|
77
79
|
self.headers = format_headers_for_sentry(env_hash)
|
78
|
-
self.env
|
80
|
+
self.env = format_env_for_sentry(env_hash)
|
79
81
|
end
|
80
82
|
|
81
83
|
private
|
82
84
|
|
85
|
+
# See Sentry server default limits at
|
86
|
+
# https://github.com/getsentry/sentry/blob/master/src/sentry/conf/server.py
|
83
87
|
def read_data_from(request)
|
84
88
|
if request.form_data?
|
85
89
|
request.POST
|
86
90
|
elsif request.body # JSON requests, etc
|
87
|
-
data = request.body.read(
|
91
|
+
data = request.body.read(4096 * 4) # Sentry server limit
|
88
92
|
request.body.rewind
|
89
93
|
data
|
90
94
|
end
|
95
|
+
rescue IOError => e
|
96
|
+
e.message
|
91
97
|
end
|
92
98
|
|
93
99
|
def format_headers_for_sentry(env_hash)
|
94
100
|
env_hash.each_with_object({}) do |(key, value), memo|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
101
|
+
begin
|
102
|
+
key = key.to_s # rack env can contain symbols
|
103
|
+
next memo['X-Request-Id'] ||= Utils::RequestId.read_from(env_hash) if Utils::RequestId::REQUEST_ID_HEADERS.include?(key)
|
104
|
+
next unless key.upcase == key # Non-upper case stuff isn't either
|
105
|
+
|
106
|
+
# Rack adds in an incorrect HTTP_VERSION key, which causes downstream
|
107
|
+
# to think this is a Version header. Instead, this is mapped to
|
108
|
+
# env['SERVER_PROTOCOL']. But we don't want to ignore a valid header
|
109
|
+
# if the request has legitimately sent a Version header themselves.
|
110
|
+
# See: https://github.com/rack/rack/blob/028438f/lib/rack/handler/cgi.rb#L29
|
111
|
+
next if key == 'HTTP_VERSION' && value == env_hash['SERVER_PROTOCOL']
|
112
|
+
next if key == 'HTTP_COOKIE' # Cookies don't go here, they go somewhere else
|
113
|
+
next unless key.start_with?('HTTP_') || %w(CONTENT_TYPE CONTENT_LENGTH).include?(key)
|
114
|
+
|
115
|
+
# Rack stores headers as HTTP_WHAT_EVER, we need What-Ever
|
116
|
+
key = key.sub(/^HTTP_/, "")
|
117
|
+
key = key.split('_').map(&:capitalize).join('-')
|
118
|
+
memo[key] = value.to_s
|
119
|
+
rescue StandardError => e
|
120
|
+
# Rails adds objects to the Rack env that can sometimes raise exceptions
|
121
|
+
# when `to_s` is called.
|
122
|
+
# See: https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/remote_ip.rb#L134
|
123
|
+
Raven.logger.warn("Error raised while formatting headers: #{e.message}")
|
124
|
+
next
|
125
|
+
end
|
111
126
|
end
|
112
127
|
end
|
113
128
|
|
114
129
|
def format_env_for_sentry(env_hash)
|
130
|
+
return env_hash if Raven.configuration.rack_env_whitelist.empty?
|
131
|
+
|
115
132
|
env_hash.select do |k, _v|
|
116
|
-
|
133
|
+
Raven.configuration.rack_env_whitelist.include? k.to_s
|
117
134
|
end
|
118
135
|
end
|
119
136
|
end
|
@@ -1,31 +1,63 @@
|
|
1
1
|
module Raven
|
2
2
|
class Rails
|
3
|
-
module
|
3
|
+
module ActiveJobExtensions
|
4
|
+
ALREADY_SUPPORTED_SENTRY_ADAPTERS = %w(
|
5
|
+
ActiveJob::QueueAdapters::SidekiqAdapter
|
6
|
+
ActiveJob::QueueAdapters::DelayedJobAdapter
|
7
|
+
).freeze
|
8
|
+
|
4
9
|
def self.included(base)
|
5
10
|
base.class_eval do
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
:active_job => self.class.name,
|
12
|
-
:arguments => arguments,
|
13
|
-
:scheduled_at => scheduled_at,
|
14
|
-
:job_id => job_id,
|
15
|
-
:locale => locale
|
16
|
-
}
|
17
|
-
|
18
|
-
# Add provider_job_id details if Rails 5
|
19
|
-
if defined?(provider_job_id)
|
20
|
-
active_job_details[:provider_job_id] = provider_job_id
|
21
|
-
end
|
22
|
-
|
23
|
-
Raven.capture_exception(exception, :extra => active_job_details)
|
24
|
-
raise exception
|
11
|
+
around_perform do |job, block|
|
12
|
+
if already_supported_by_specific_integration?(job)
|
13
|
+
block.call
|
14
|
+
else
|
15
|
+
capture_and_reraise_with_sentry(job, block)
|
25
16
|
end
|
26
17
|
end
|
27
18
|
end
|
28
19
|
end
|
20
|
+
|
21
|
+
def capture_and_reraise_with_sentry(job, block)
|
22
|
+
block.call
|
23
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
24
|
+
rescue_handler_result = rescue_with_handler(e)
|
25
|
+
return rescue_handler_result if rescue_handler_result
|
26
|
+
|
27
|
+
Raven.capture_exception(e, :extra => raven_context(job))
|
28
|
+
raise e
|
29
|
+
ensure
|
30
|
+
Context.clear!
|
31
|
+
BreadcrumbBuffer.clear!
|
32
|
+
end
|
33
|
+
|
34
|
+
def already_supported_by_specific_integration?(job)
|
35
|
+
if ::Rails.version.to_f < 5.0
|
36
|
+
ALREADY_SUPPORTED_SENTRY_ADAPTERS.include?(job.class.queue_adapter.to_s)
|
37
|
+
else
|
38
|
+
ALREADY_SUPPORTED_SENTRY_ADAPTERS.include?(job.class.queue_adapter.class.to_s)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def raven_context(job)
|
43
|
+
ctx = {
|
44
|
+
:active_job => job.class.name,
|
45
|
+
:arguments => job.arguments,
|
46
|
+
:scheduled_at => job.scheduled_at,
|
47
|
+
:job_id => job.job_id,
|
48
|
+
:locale => job.locale
|
49
|
+
}
|
50
|
+
# Add provider_job_id details if Rails 5
|
51
|
+
if job.respond_to?(:provider_job_id)
|
52
|
+
ctx[:provider_job_id] = job.provider_job_id
|
53
|
+
end
|
54
|
+
|
55
|
+
ctx
|
56
|
+
end
|
29
57
|
end
|
30
58
|
end
|
31
59
|
end
|
60
|
+
|
61
|
+
class ActiveJob::Base
|
62
|
+
include Raven::Rails::ActiveJobExtensions
|
63
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "active_support/backtrace_cleaner"
|
2
|
+
require "active_support/core_ext/string/access"
|
3
|
+
|
4
|
+
module Raven
|
5
|
+
class Rails
|
6
|
+
class BacktraceCleaner < ActiveSupport::BacktraceCleaner
|
7
|
+
APP_DIRS_PATTERN = /\A(?:\.\/)?(?:app|config|lib|test|\(\w*\))/.freeze
|
8
|
+
RENDER_TEMPLATE_PATTERN = /:in `.*_\w+_{2,3}\d+_\d+'/.freeze
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
super
|
12
|
+
# we don't want any default silencers because they're too aggressive
|
13
|
+
remove_silencers!
|
14
|
+
|
15
|
+
@root = "#{Raven.configuration.project_root}/"
|
16
|
+
add_filter do |line|
|
17
|
+
line.start_with?(@root) ? line.from(@root.size) : line
|
18
|
+
end
|
19
|
+
add_filter do |line|
|
20
|
+
if line =~ RENDER_TEMPLATE_PATTERN
|
21
|
+
line.sub(RENDER_TEMPLATE_PATTERN, "")
|
22
|
+
else
|
23
|
+
line
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Raven
|
2
|
+
class Rails
|
3
|
+
module ControllerTransaction
|
4
|
+
def self.included(base)
|
5
|
+
base.prepend_around_action do |controller, block|
|
6
|
+
Raven.context.transaction.push "#{controller.class}##{controller.action_name}"
|
7
|
+
block.call
|
8
|
+
Raven.context.transaction.pop
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -6,7 +6,7 @@ module Raven
|
|
6
6
|
begin
|
7
7
|
env = env_or_request.respond_to?(:env) ? env_or_request.env : env_or_request
|
8
8
|
Raven::Rack.capture_exception(exception, env)
|
9
|
-
rescue
|
9
|
+
rescue
|
10
10
|
end
|
11
11
|
super
|
12
12
|
end
|
@@ -21,7 +21,7 @@ module Raven
|
|
21
21
|
begin
|
22
22
|
env = env_or_request.respond_to?(:env) ? env_or_request.env : env_or_request
|
23
23
|
Raven::Rack.capture_exception(exception, env)
|
24
|
-
rescue
|
24
|
+
rescue
|
25
25
|
end
|
26
26
|
render_exception_without_raven(env_or_request, exception)
|
27
27
|
end
|
@@ -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,6 +15,7 @@ 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
20
|
Raven.safely_prepend(
|
17
21
|
"StreamingReporter",
|
@@ -32,16 +36,22 @@ module Raven
|
|
32
36
|
end
|
33
37
|
end
|
34
38
|
|
35
|
-
config.
|
36
|
-
Raven.
|
37
|
-
|
38
|
-
|
39
|
-
|
39
|
+
config.before_initialize do
|
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)
|
40
46
|
end
|
47
|
+
end
|
41
48
|
|
42
|
-
|
43
|
-
|
44
|
-
|
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
|
45
55
|
end
|
46
56
|
|
47
57
|
if Raven.configuration.rails_report_rescued_exceptions
|
@@ -60,6 +70,12 @@ module Raven
|
|
60
70
|
end
|
61
71
|
end
|
62
72
|
|
73
|
+
initializer 'raven.active_job' do
|
74
|
+
ActiveSupport.on_load :active_job do
|
75
|
+
require 'raven/integrations/rails/active_job'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
63
79
|
rake_tasks do
|
64
80
|
require 'raven/integrations/tasks'
|
65
81
|
end
|
@@ -6,7 +6,12 @@ module Rake
|
|
6
6
|
class Application
|
7
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
|