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
|
@@ -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
|
+
)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
module Raven
|
|
2
|
+
class Breadcrumb
|
|
3
|
+
attr_accessor :category, :data, :message, :level, :timestamp, :type
|
|
4
|
+
|
|
5
|
+
def initialize
|
|
6
|
+
@category = nil
|
|
7
|
+
@data = {}
|
|
8
|
+
@level = nil
|
|
9
|
+
@message = nil
|
|
10
|
+
@timestamp = Time.now.to_i
|
|
11
|
+
@type = nil
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def to_hash
|
|
15
|
+
{
|
|
16
|
+
:category => @category,
|
|
17
|
+
:data => @data,
|
|
18
|
+
:level => @level,
|
|
19
|
+
:message => @message,
|
|
20
|
+
:timestamp => @timestamp,
|
|
21
|
+
:type => @type
|
|
22
|
+
}
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
module Raven
|
|
28
|
+
class BreadcrumbBuffer
|
|
29
|
+
include Enumerable
|
|
30
|
+
|
|
31
|
+
attr_accessor :buffer
|
|
32
|
+
|
|
33
|
+
def self.current
|
|
34
|
+
Thread.current[:sentry_breadcrumbs] ||= new
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.clear!
|
|
38
|
+
Thread.current[:sentry_breadcrumbs] = nil
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def initialize(size = 100)
|
|
42
|
+
@buffer = Array.new(size)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def record(crumb = nil)
|
|
46
|
+
if block_given?
|
|
47
|
+
crumb = Breadcrumb.new if crumb.nil?
|
|
48
|
+
yield(crumb)
|
|
49
|
+
end
|
|
50
|
+
@buffer.slice!(0)
|
|
51
|
+
@buffer << crumb
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def members
|
|
55
|
+
@buffer.compact
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def peek
|
|
59
|
+
members.last
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def each(&block)
|
|
63
|
+
members.each(&block)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def empty?
|
|
67
|
+
members.none?
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def to_hash
|
|
71
|
+
{
|
|
72
|
+
:values => members.map(&:to_hash)
|
|
73
|
+
}
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
data/lib/raven/cli.rb
CHANGED
|
@@ -1,56 +1,48 @@
|
|
|
1
1
|
module Raven
|
|
2
2
|
class CLI
|
|
3
|
-
def self.test(dsn = nil)
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
logger =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
3
|
+
def self.test(dsn = nil, silent = false, config = nil)
|
|
4
|
+
config ||= Raven.configuration
|
|
5
|
+
|
|
6
|
+
config.logger = if silent
|
|
7
|
+
::Logger.new(nil)
|
|
8
|
+
else
|
|
9
|
+
logger = ::Logger.new(STDOUT)
|
|
10
|
+
logger.formatter = proc do |_severity, _datetime, _progname, msg|
|
|
11
|
+
"-> #{msg}\n"
|
|
12
|
+
end
|
|
13
|
+
logger
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
config.timeout = 5
|
|
17
|
+
config.dsn = dsn if dsn
|
|
15
18
|
|
|
16
19
|
# wipe out env settings to ensure we send the event
|
|
17
|
-
unless
|
|
18
|
-
env_name =
|
|
19
|
-
|
|
20
|
-
Raven.configuration.current_environment = env_name
|
|
20
|
+
unless config.capture_allowed?
|
|
21
|
+
env_name = config.environments.last || 'production'
|
|
22
|
+
config.current_environment = env_name
|
|
21
23
|
end
|
|
22
24
|
|
|
23
|
-
Raven.
|
|
25
|
+
instance = Raven::Instance.new(nil, config)
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
instance.logger.debug "Sending a test event:"
|
|
28
|
+
instance.logger.debug ""
|
|
27
29
|
|
|
28
30
|
begin
|
|
29
31
|
1 / 0
|
|
30
|
-
rescue ZeroDivisionError =>
|
|
31
|
-
evt =
|
|
32
|
+
rescue ZeroDivisionError => e
|
|
33
|
+
evt = instance.capture_exception(e)
|
|
32
34
|
end
|
|
33
35
|
|
|
34
|
-
if evt
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
end
|
|
40
|
-
elsif evt #async configuration
|
|
41
|
-
if evt.value.is_a? Hash
|
|
42
|
-
puts "-> event ID: #{evt.value[:event_id]}"
|
|
43
|
-
else
|
|
44
|
-
puts "-> event ID: #{evt.value.id}"
|
|
45
|
-
end
|
|
36
|
+
if evt
|
|
37
|
+
instance.logger.debug "-> event ID: #{evt.id}"
|
|
38
|
+
instance.logger.debug ""
|
|
39
|
+
instance.logger.debug "Done!"
|
|
40
|
+
evt
|
|
46
41
|
else
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
42
|
+
instance.logger.debug ""
|
|
43
|
+
instance.logger.debug "An error occurred while attempting to send the event."
|
|
44
|
+
false
|
|
50
45
|
end
|
|
51
|
-
|
|
52
|
-
puts ""
|
|
53
|
-
puts "Done!"
|
|
54
46
|
end
|
|
55
47
|
end
|
|
56
48
|
end
|
data/lib/raven/client.rb
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
require 'base64'
|
|
4
|
+
require 'json'
|
|
5
|
+
require 'zlib'
|
|
4
6
|
|
|
5
|
-
require
|
|
6
|
-
require 'raven/okjson'
|
|
7
|
-
require 'raven/transports/http'
|
|
7
|
+
require "raven/transports"
|
|
8
8
|
|
|
9
9
|
module Raven
|
|
10
10
|
# Encodes events and sends them to the Sentry server.
|
|
11
11
|
class Client
|
|
12
|
-
PROTOCOL_VERSION = '5'
|
|
13
|
-
USER_AGENT = "raven-ruby/#{Raven::VERSION}"
|
|
14
|
-
CONTENT_TYPE = 'application/json'
|
|
12
|
+
PROTOCOL_VERSION = '5'
|
|
13
|
+
USER_AGENT = "raven-ruby/#{Raven::VERSION}"
|
|
14
|
+
CONTENT_TYPE = 'application/json'
|
|
15
15
|
|
|
16
16
|
attr_accessor :configuration
|
|
17
17
|
|
|
@@ -21,8 +21,14 @@ module Raven
|
|
|
21
21
|
@state = ClientState.new
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
def send_event(event)
|
|
25
|
-
return false unless
|
|
24
|
+
def send_event(event, hint = nil)
|
|
25
|
+
return false unless configuration.sending_allowed?(event)
|
|
26
|
+
|
|
27
|
+
event = configuration.before_send.call(event, hint) if configuration.before_send
|
|
28
|
+
if event.nil?
|
|
29
|
+
configuration.logger.info "Discarded event because before_send returned nil"
|
|
30
|
+
return
|
|
31
|
+
end
|
|
26
32
|
|
|
27
33
|
# Convert to hash
|
|
28
34
|
event = event.to_hash
|
|
@@ -32,13 +38,14 @@ module Raven
|
|
|
32
38
|
return
|
|
33
39
|
end
|
|
34
40
|
|
|
35
|
-
|
|
41
|
+
event_id = event[:event_id] || event['event_id']
|
|
42
|
+
configuration.logger.info "Sending event #{event_id} to Sentry"
|
|
36
43
|
|
|
37
44
|
content_type, encoded_data = encode(event)
|
|
38
45
|
|
|
39
46
|
begin
|
|
40
47
|
transport.send_event(generate_auth_header, encoded_data,
|
|
41
|
-
|
|
48
|
+
:content_type => content_type)
|
|
42
49
|
successful_send
|
|
43
50
|
rescue => e
|
|
44
51
|
failed_send(e, event)
|
|
@@ -53,6 +60,8 @@ module Raven
|
|
|
53
60
|
case configuration.scheme
|
|
54
61
|
when 'http', 'https'
|
|
55
62
|
Transports::HTTP.new(configuration)
|
|
63
|
+
when 'stdout'
|
|
64
|
+
Transports::Stdout.new(configuration)
|
|
56
65
|
when 'dummy'
|
|
57
66
|
Transports::Dummy.new(configuration)
|
|
58
67
|
else
|
|
@@ -62,18 +71,9 @@ module Raven
|
|
|
62
71
|
|
|
63
72
|
private
|
|
64
73
|
|
|
65
|
-
def configuration_allows_sending
|
|
66
|
-
if configuration.send_in_current_environment?
|
|
67
|
-
true
|
|
68
|
-
else
|
|
69
|
-
configuration.log_excluded_environment_message
|
|
70
|
-
false
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
|
|
74
74
|
def encode(event)
|
|
75
|
-
hash = @processors.reduce(event.to_hash) { |
|
|
76
|
-
encoded =
|
|
75
|
+
hash = @processors.reduce(event.to_hash) { |a, e| e.process(a) }
|
|
76
|
+
encoded = JSON.fast_generate(hash)
|
|
77
77
|
|
|
78
78
|
case configuration.encoding
|
|
79
79
|
when 'gzip'
|
|
@@ -83,8 +83,20 @@ module Raven
|
|
|
83
83
|
end
|
|
84
84
|
end
|
|
85
85
|
|
|
86
|
+
def get_message_from_exception(event)
|
|
87
|
+
(
|
|
88
|
+
event &&
|
|
89
|
+
event[:exception] &&
|
|
90
|
+
event[:exception][:values] &&
|
|
91
|
+
event[:exception][:values][0] &&
|
|
92
|
+
event[:exception][:values][0][:type] &&
|
|
93
|
+
event[:exception][:values][0][:value] &&
|
|
94
|
+
"#{event[:exception][:values][0][:type]}: #{event[:exception][:values][0][:value]}"
|
|
95
|
+
)
|
|
96
|
+
end
|
|
97
|
+
|
|
86
98
|
def get_log_message(event)
|
|
87
|
-
(event && event[:message]) || '<no message value>'
|
|
99
|
+
(event && event[:message]) || (event && event['message']) || get_message_from_exception(event) || '<no message value>'
|
|
88
100
|
end
|
|
89
101
|
|
|
90
102
|
def generate_auth_header
|
|
@@ -93,9 +105,9 @@ module Raven
|
|
|
93
105
|
'sentry_version' => PROTOCOL_VERSION,
|
|
94
106
|
'sentry_client' => USER_AGENT,
|
|
95
107
|
'sentry_timestamp' => now,
|
|
96
|
-
'sentry_key' => configuration.public_key
|
|
97
|
-
'sentry_secret' => configuration.secret_key
|
|
108
|
+
'sentry_key' => configuration.public_key
|
|
98
109
|
}
|
|
110
|
+
fields['sentry_secret'] = configuration.secret_key unless configuration.secret_key.nil?
|
|
99
111
|
'Sentry ' + fields.map { |key, value| "#{key}=#{value}" }.join(', ')
|
|
100
112
|
end
|
|
101
113
|
|
|
@@ -104,15 +116,16 @@ module Raven
|
|
|
104
116
|
end
|
|
105
117
|
|
|
106
118
|
def failed_send(e, event)
|
|
107
|
-
@state.failure
|
|
108
119
|
if e # exception was raised
|
|
109
|
-
|
|
110
|
-
e.backtrace[0..10].
|
|
120
|
+
@state.failure
|
|
121
|
+
configuration.logger.warn "Unable to record event with remote Sentry server (#{e.class} - #{e.message}):\n#{e.backtrace[0..10].join("\n")}"
|
|
111
122
|
else
|
|
112
|
-
|
|
123
|
+
configuration.logger.warn "Not sending event due to previous failure(s)."
|
|
113
124
|
end
|
|
114
|
-
|
|
115
|
-
|
|
125
|
+
configuration.logger.warn("Failed to submit event: #{get_log_message(event)}")
|
|
126
|
+
|
|
127
|
+
# configuration.transport_failure_callback can be false & nil
|
|
128
|
+
configuration.transport_failure_callback.call(event, e) if configuration.transport_failure_callback # rubocop:disable Style/SafeNavigation
|
|
116
129
|
end
|
|
117
130
|
end
|
|
118
131
|
|
|
@@ -124,7 +137,7 @@ module Raven
|
|
|
124
137
|
def should_try?
|
|
125
138
|
return true if @status == :online
|
|
126
139
|
|
|
127
|
-
interval = @retry_after || [@retry_number, 6].min
|
|
140
|
+
interval = @retry_after || [@retry_number, 6].min**2
|
|
128
141
|
return true if Time.now - @last_check >= interval
|
|
129
142
|
|
|
130
143
|
false
|