sentry-ruby-core 4.8.3 → 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/README.md +2 -0
- data/lib/sentry/background_worker.rb +3 -1
- data/lib/sentry/backtrace.rb +0 -3
- data/lib/sentry/breadcrumb.rb +22 -3
- data/lib/sentry/breadcrumb_buffer.rb +14 -0
- data/lib/sentry/client.rb +35 -2
- data/lib/sentry/configuration.rb +4 -3
- data/lib/sentry/event.rb +54 -18
- data/lib/sentry/hub.rb +3 -0
- data/lib/sentry/interface.rb +1 -10
- data/lib/sentry/interfaces/exception.rb +11 -3
- data/lib/sentry/interfaces/request.rb +34 -18
- data/lib/sentry/interfaces/stacktrace.rb +4 -0
- data/lib/sentry/interfaces/stacktrace_builder.rb +37 -10
- data/lib/sentry/interfaces/threads.rb +10 -2
- data/lib/sentry/net/http.rb +49 -64
- data/lib/sentry/scope.rb +67 -1
- data/lib/sentry/span.rb +83 -8
- data/lib/sentry/transaction.rb +42 -9
- data/lib/sentry/transaction_event.rb +8 -0
- data/lib/sentry/transport/configuration.rb +1 -2
- data/lib/sentry/transport/http_transport.rb +52 -35
- data/lib/sentry/transport.rb +4 -1
- data/lib/sentry/utils/logging_helper.rb +4 -4
- data/lib/sentry/version.rb +1 -1
- data/lib/sentry-ruby.rb +41 -2
- data/sentry-ruby-core.gemspec +0 -1
- data/sentry-ruby.gemspec +0 -1
- metadata +2 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f87f499a85374ffedb9efc48ae758ea007a44276d85af7ca7899f4d30d44cd73
|
4
|
+
data.tar.gz: 613088c3759d726b675992785bcfb76996227af0ac5ee04b196140b4f0d17903
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 95bd72a765827b11e63deeb884057e3365590a96e2417185996e4bac3880c2df26daf9fcff36e1c7eb145fbe481b001e6d0113ea7caad8e0f72d88a7e4eb4446
|
7
|
+
data.tar.gz: 39256b355acf287b49bddb5f2e35c2c2fe761723a738165b0a79bd66927a07d5f170a7d6e5eb66dd6e019af8278dbbf0cc6a52238dafa9a3b3bd90e30b805b9e
|
data/README.md
CHANGED
@@ -78,6 +78,8 @@ end
|
|
78
78
|
|
79
79
|
To learn more about sampling transactions, please visit the [official documentation](https://docs.sentry.io/platforms/ruby/configuration/sampling/#configuring-the-transaction-sample-rate).
|
80
80
|
|
81
|
+
### [Migration Guide](https://docs.sentry.io/platforms/ruby/migration/)
|
82
|
+
|
81
83
|
### Integrations
|
82
84
|
|
83
85
|
- [Rack](https://docs.sentry.io/platforms/ruby/guides/rack/)
|
@@ -8,7 +8,9 @@ module Sentry
|
|
8
8
|
class BackgroundWorker
|
9
9
|
include LoggingHelper
|
10
10
|
|
11
|
-
attr_reader :max_queue, :number_of_threads
|
11
|
+
attr_reader :max_queue, :number_of_threads
|
12
|
+
# @deprecated Use Sentry.logger to retrieve the current logger instead.
|
13
|
+
attr_reader :logger
|
12
14
|
attr_accessor :shutdown_timeout
|
13
15
|
|
14
16
|
def initialize(configuration)
|
data/lib/sentry/backtrace.rb
CHANGED
data/lib/sentry/breadcrumb.rb
CHANGED
@@ -4,9 +4,25 @@ module Sentry
|
|
4
4
|
class Breadcrumb
|
5
5
|
DATA_SERIALIZATION_ERROR_MESSAGE = "[data were removed due to serialization issues]"
|
6
6
|
|
7
|
-
|
7
|
+
# @return [String, nil]
|
8
|
+
attr_accessor :category
|
9
|
+
# @return [Hash, nil]
|
10
|
+
attr_accessor :data
|
11
|
+
# @return [String, nil]
|
12
|
+
attr_accessor :level
|
13
|
+
# @return [Time, Integer, nil]
|
14
|
+
attr_accessor :timestamp
|
15
|
+
# @return [String, nil]
|
16
|
+
attr_accessor :type
|
17
|
+
# @return [String, nil]
|
8
18
|
attr_reader :message
|
9
19
|
|
20
|
+
# @param category [String, nil]
|
21
|
+
# @param data [Hash, nil]
|
22
|
+
# @param message [String, nil]
|
23
|
+
# @param timestamp [Time, Integer, nil]
|
24
|
+
# @param level [String, nil]
|
25
|
+
# @param type [String, nil]
|
10
26
|
def initialize(category: nil, data: nil, message: nil, timestamp: nil, level: nil, type: nil)
|
11
27
|
@category = category
|
12
28
|
@data = data || {}
|
@@ -16,6 +32,7 @@ module Sentry
|
|
16
32
|
self.message = message
|
17
33
|
end
|
18
34
|
|
35
|
+
# @return [Hash]
|
19
36
|
def to_hash
|
20
37
|
{
|
21
38
|
category: @category,
|
@@ -27,8 +44,10 @@ module Sentry
|
|
27
44
|
}
|
28
45
|
end
|
29
46
|
|
30
|
-
|
31
|
-
|
47
|
+
# @param message [String]
|
48
|
+
# @return [void]
|
49
|
+
def message=(message)
|
50
|
+
@message = (message || "").byteslice(0..Event::MAX_MESSAGE_SIZE_IN_BYTES)
|
32
51
|
end
|
33
52
|
|
34
53
|
private
|
@@ -7,40 +7,54 @@ module Sentry
|
|
7
7
|
DEFAULT_SIZE = 100
|
8
8
|
include Enumerable
|
9
9
|
|
10
|
+
# @return [Array]
|
10
11
|
attr_accessor :buffer
|
11
12
|
|
13
|
+
# @param size [Integer, nil] If it's not provided, it'll fallback to DEFAULT_SIZE
|
12
14
|
def initialize(size = nil)
|
13
15
|
@buffer = Array.new(size || DEFAULT_SIZE)
|
14
16
|
end
|
15
17
|
|
18
|
+
# @param crumb [Breadcrumb]
|
19
|
+
# @return [void]
|
16
20
|
def record(crumb)
|
17
21
|
yield(crumb) if block_given?
|
18
22
|
@buffer.slice!(0)
|
19
23
|
@buffer << crumb
|
20
24
|
end
|
21
25
|
|
26
|
+
# @return [Array]
|
22
27
|
def members
|
23
28
|
@buffer.compact
|
24
29
|
end
|
25
30
|
|
31
|
+
# Returns the last breadcrumb stored in the buffer. If the buffer it's empty, it returns nil.
|
32
|
+
# @return [Breadcrumb, nil]
|
26
33
|
def peek
|
27
34
|
members.last
|
28
35
|
end
|
29
36
|
|
37
|
+
# Iterates through all breadcrumbs.
|
38
|
+
# @param block [Proc]
|
39
|
+
# @yieldparam crumb [Breadcrumb]
|
40
|
+
# @return [Array]
|
30
41
|
def each(&block)
|
31
42
|
members.each(&block)
|
32
43
|
end
|
33
44
|
|
45
|
+
# @return [Boolean]
|
34
46
|
def empty?
|
35
47
|
members.none?
|
36
48
|
end
|
37
49
|
|
50
|
+
# @return [Hash]
|
38
51
|
def to_hash
|
39
52
|
{
|
40
53
|
values: members.map(&:to_hash)
|
41
54
|
}
|
42
55
|
end
|
43
56
|
|
57
|
+
# @return [BreadcrumbBuffer]
|
44
58
|
def dup
|
45
59
|
copy = super
|
46
60
|
copy.buffer = buffer.deep_dup
|
data/lib/sentry/client.rb
CHANGED
@@ -6,8 +6,17 @@ module Sentry
|
|
6
6
|
class Client
|
7
7
|
include LoggingHelper
|
8
8
|
|
9
|
-
|
9
|
+
# The Transport object that'll send events for the client.
|
10
|
+
# @return [Transport]
|
11
|
+
attr_reader :transport
|
10
12
|
|
13
|
+
# @!macro configuration
|
14
|
+
attr_reader :configuration
|
15
|
+
|
16
|
+
# @deprecated Use Sentry.logger to retrieve the current logger instead.
|
17
|
+
attr_reader :logger
|
18
|
+
|
19
|
+
# @param configuration [Configuration]
|
11
20
|
def initialize(configuration)
|
12
21
|
@configuration = configuration
|
13
22
|
@logger = configuration.logger
|
@@ -25,6 +34,11 @@ module Sentry
|
|
25
34
|
end
|
26
35
|
end
|
27
36
|
|
37
|
+
# Applies the given scope's data to the event and sends it to Sentry.
|
38
|
+
# @param event [Event] the event to be sent.
|
39
|
+
# @param scope [Scope] the scope with contextual data that'll be applied to the event before it's sent.
|
40
|
+
# @param hint [Hash] the hint data that'll be passed to `before_send` callback and the scope's event processors.
|
41
|
+
# @return [Event, nil]
|
28
42
|
def capture_event(event, scope, hint = {})
|
29
43
|
return unless configuration.sending_allowed?
|
30
44
|
|
@@ -57,9 +71,14 @@ module Sentry
|
|
57
71
|
nil
|
58
72
|
end
|
59
73
|
|
74
|
+
# Initializes an Event object with the given exception. Returns `nil` if the exception's class is excluded from reporting.
|
75
|
+
# @param exception [Exception] the exception to be reported.
|
76
|
+
# @param hint [Hash] the hint data that'll be passed to `before_send` callback and the scope's event processors.
|
77
|
+
# @return [Event, nil]
|
60
78
|
def event_from_exception(exception, hint = {})
|
79
|
+
return unless @configuration.sending_allowed? && @configuration.exception_class_allowed?(exception)
|
80
|
+
|
61
81
|
integration_meta = Sentry.integrations[hint[:integration]]
|
62
|
-
return unless @configuration.exception_class_allowed?(exception)
|
63
82
|
|
64
83
|
Event.new(configuration: configuration, integration_meta: integration_meta).tap do |event|
|
65
84
|
event.add_exception_interface(exception)
|
@@ -67,13 +86,22 @@ module Sentry
|
|
67
86
|
end
|
68
87
|
end
|
69
88
|
|
89
|
+
# Initializes an Event object with the given message.
|
90
|
+
# @param message [String] the message to be reported.
|
91
|
+
# @param hint [Hash] the hint data that'll be passed to `before_send` callback and the scope's event processors.
|
92
|
+
# @return [Event]
|
70
93
|
def event_from_message(message, hint = {}, backtrace: nil)
|
94
|
+
return unless @configuration.sending_allowed?
|
95
|
+
|
71
96
|
integration_meta = Sentry.integrations[hint[:integration]]
|
72
97
|
event = Event.new(configuration: configuration, integration_meta: integration_meta, message: message)
|
73
98
|
event.add_threads_interface(backtrace: backtrace || caller)
|
74
99
|
event
|
75
100
|
end
|
76
101
|
|
102
|
+
# Initializes an Event object with the given Transaction object.
|
103
|
+
# @param transaction [Transaction] the transaction to be recorded.
|
104
|
+
# @return [TransactionEvent]
|
77
105
|
def event_from_transaction(transaction)
|
78
106
|
TransactionEvent.new(configuration: configuration).tap do |event|
|
79
107
|
event.transaction = transaction.name
|
@@ -86,6 +114,7 @@ module Sentry
|
|
86
114
|
end
|
87
115
|
end
|
88
116
|
|
117
|
+
# @!macro send_event
|
89
118
|
def send_event(event, hint = nil)
|
90
119
|
event_type = event.is_a?(Event) ? event.type : event["type"]
|
91
120
|
|
@@ -112,6 +141,10 @@ module Sentry
|
|
112
141
|
raise
|
113
142
|
end
|
114
143
|
|
144
|
+
# Generates a Sentry trace for distribted tracing from the given Span.
|
145
|
+
# Returns `nil` if `config.propagate_traces` is `false`.
|
146
|
+
# @param span [Span] the span to generate trace from.
|
147
|
+
# @return [String, nil]
|
115
148
|
def generate_sentry_trace(span)
|
116
149
|
return unless configuration.propagate_traces
|
117
150
|
|
data/lib/sentry/configuration.rb
CHANGED
@@ -46,7 +46,7 @@ module Sentry
|
|
46
46
|
# Rails.backtrace_cleaner.clean(backtrace)
|
47
47
|
# end
|
48
48
|
#
|
49
|
-
# @return [Proc]
|
49
|
+
# @return [Proc, nil]
|
50
50
|
attr_accessor :backtrace_cleanup_callback
|
51
51
|
|
52
52
|
# Optional Proc, called before adding the breadcrumb to the current scope
|
@@ -127,8 +127,9 @@ module Sentry
|
|
127
127
|
alias inspect_exception_causes_for_exclusion? inspect_exception_causes_for_exclusion
|
128
128
|
|
129
129
|
# You may provide your own LineCache for matching paths with source files.
|
130
|
-
# This may be useful if you need to get source code from places other than
|
131
|
-
#
|
130
|
+
# This may be useful if you need to get source code from places other than the disk.
|
131
|
+
# @see LineCache
|
132
|
+
# @return [LineCache]
|
132
133
|
attr_accessor :linecache
|
133
134
|
|
134
135
|
# Logger used by Sentry. In Rails, this is the Rails logger, otherwise
|
data/lib/sentry/event.rb
CHANGED
@@ -10,31 +10,40 @@ require 'sentry/utils/custom_inspection'
|
|
10
10
|
|
11
11
|
module Sentry
|
12
12
|
class Event
|
13
|
+
# These are readable attributes.
|
13
14
|
SERIALIZEABLE_ATTRIBUTES = %i(
|
14
15
|
event_id level timestamp
|
15
16
|
release environment server_name modules
|
16
17
|
message user tags contexts extra
|
17
|
-
fingerprint breadcrumbs
|
18
|
+
fingerprint breadcrumbs transaction
|
18
19
|
platform sdk type
|
19
20
|
)
|
20
21
|
|
22
|
+
# These are writable attributes.
|
21
23
|
WRITER_ATTRIBUTES = SERIALIZEABLE_ATTRIBUTES - %i(type timestamp level)
|
22
24
|
|
23
25
|
MAX_MESSAGE_SIZE_IN_BYTES = 1024 * 8
|
24
26
|
|
25
|
-
SKIP_INSPECTION_ATTRIBUTES = [:@
|
27
|
+
SKIP_INSPECTION_ATTRIBUTES = [:@modules, :@stacktrace_builder, :@send_default_pii, :@trusted_proxies, :@rack_env_whitelist]
|
26
28
|
|
27
29
|
include CustomInspection
|
28
30
|
|
29
31
|
attr_writer(*WRITER_ATTRIBUTES)
|
30
32
|
attr_reader(*SERIALIZEABLE_ATTRIBUTES)
|
31
33
|
|
32
|
-
|
34
|
+
# @return [RequestInterface]
|
35
|
+
attr_reader :request
|
33
36
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
+
# @return [ExceptionInterface]
|
38
|
+
attr_reader :exception
|
39
|
+
|
40
|
+
# @return [ThreadsInterface]
|
41
|
+
attr_reader :threads
|
37
42
|
|
43
|
+
# @param configuration [Configuration]
|
44
|
+
# @param integration_meta [Hash, nil]
|
45
|
+
# @param message [String, nil]
|
46
|
+
def initialize(configuration:, integration_meta: nil, message: nil)
|
38
47
|
# Set some simple default values
|
39
48
|
@event_id = SecureRandom.uuid.delete("-")
|
40
49
|
@timestamp = Sentry.utc_now.iso8601
|
@@ -48,17 +57,25 @@ module Sentry
|
|
48
57
|
|
49
58
|
@fingerprint = []
|
50
59
|
|
60
|
+
# configuration data that's directly used by events
|
51
61
|
@server_name = configuration.server_name
|
52
62
|
@environment = configuration.environment
|
53
63
|
@release = configuration.release
|
54
64
|
@modules = configuration.gem_specs if configuration.send_modules
|
55
65
|
|
66
|
+
# configuration options to help events process data
|
67
|
+
@send_default_pii = configuration.send_default_pii
|
68
|
+
@trusted_proxies = configuration.trusted_proxies
|
69
|
+
@stacktrace_builder = configuration.stacktrace_builder
|
70
|
+
@rack_env_whitelist = configuration.rack_env_whitelist
|
71
|
+
|
56
72
|
@message = (message || "").byteslice(0..MAX_MESSAGE_SIZE_IN_BYTES)
|
57
73
|
|
58
74
|
self.level = :error
|
59
75
|
end
|
60
76
|
|
61
77
|
class << self
|
78
|
+
# @!visibility private
|
62
79
|
def get_log_message(event_hash)
|
63
80
|
message = event_hash[:message] || event_hash['message']
|
64
81
|
|
@@ -75,6 +92,7 @@ module Sentry
|
|
75
92
|
'<no message value>'
|
76
93
|
end
|
77
94
|
|
95
|
+
# @!visibility private
|
78
96
|
def get_message_from_exception(event_hash)
|
79
97
|
if exception = event_hash.dig(:exception, :values, 0)
|
80
98
|
"#{exception[:type]}: #{exception[:value]}"
|
@@ -84,21 +102,35 @@ module Sentry
|
|
84
102
|
end
|
85
103
|
end
|
86
104
|
|
105
|
+
# @deprecated This method will be removed in v5.0.0. Please just use Sentry.configuration
|
106
|
+
# @return [Configuration]
|
107
|
+
def configuration
|
108
|
+
Sentry.configuration
|
109
|
+
end
|
110
|
+
|
111
|
+
# Sets the event's timestamp.
|
112
|
+
# @param time [Time, Float]
|
113
|
+
# @return [void]
|
87
114
|
def timestamp=(time)
|
88
115
|
@timestamp = time.is_a?(Time) ? time.to_f : time
|
89
116
|
end
|
90
117
|
|
91
|
-
|
92
|
-
|
118
|
+
# Sets the event's level.
|
119
|
+
# @param level [String, Symbol]
|
120
|
+
# @return [void]
|
121
|
+
def level=(level) # needed to meet the Sentry spec
|
122
|
+
@level = level.to_s == "warn" ? :warning : level
|
93
123
|
end
|
94
124
|
|
125
|
+
# Sets the event's request environment data with RequestInterface.
|
126
|
+
# @see RequestInterface
|
127
|
+
# @param env [Hash]
|
128
|
+
# @return [void]
|
95
129
|
def rack_env=(env)
|
96
130
|
unless request || env.empty?
|
97
|
-
env = env.dup
|
98
|
-
|
99
131
|
add_request_interface(env)
|
100
132
|
|
101
|
-
if
|
133
|
+
if @send_default_pii
|
102
134
|
user[:ip_address] = calculate_real_ip_from_rack(env)
|
103
135
|
end
|
104
136
|
|
@@ -108,6 +140,7 @@ module Sentry
|
|
108
140
|
end
|
109
141
|
end
|
110
142
|
|
143
|
+
# @return [Hash]
|
111
144
|
def to_hash
|
112
145
|
data = serialize_attributes
|
113
146
|
data[:breadcrumbs] = breadcrumbs.to_hash if breadcrumbs
|
@@ -118,32 +151,35 @@ module Sentry
|
|
118
151
|
data
|
119
152
|
end
|
120
153
|
|
154
|
+
# @return [Hash]
|
121
155
|
def to_json_compatible
|
122
156
|
JSON.parse(JSON.generate(to_hash))
|
123
157
|
end
|
124
158
|
|
125
|
-
|
126
|
-
@request = Sentry::RequestInterface.build(env: env)
|
127
|
-
end
|
128
|
-
|
159
|
+
# @!visibility private
|
129
160
|
def add_threads_interface(backtrace: nil, **options)
|
130
161
|
@threads = ThreadsInterface.build(
|
131
162
|
backtrace: backtrace,
|
132
|
-
stacktrace_builder:
|
163
|
+
stacktrace_builder: @stacktrace_builder,
|
133
164
|
**options
|
134
165
|
)
|
135
166
|
end
|
136
167
|
|
168
|
+
# @!visibility private
|
137
169
|
def add_exception_interface(exception)
|
138
170
|
if exception.respond_to?(:sentry_context)
|
139
171
|
@extra.merge!(exception.sentry_context)
|
140
172
|
end
|
141
173
|
|
142
|
-
@exception = Sentry::ExceptionInterface.build(exception: exception, stacktrace_builder:
|
174
|
+
@exception = Sentry::ExceptionInterface.build(exception: exception, stacktrace_builder: @stacktrace_builder)
|
143
175
|
end
|
144
176
|
|
145
177
|
private
|
146
178
|
|
179
|
+
def add_request_interface(env)
|
180
|
+
@request = Sentry::RequestInterface.new(env: env, send_default_pii: @send_default_pii, rack_env_whitelist: @rack_env_whitelist)
|
181
|
+
end
|
182
|
+
|
147
183
|
def serialize_attributes
|
148
184
|
self.class::SERIALIZEABLE_ATTRIBUTES.each_with_object({}) do |att, memo|
|
149
185
|
if value = public_send(att)
|
@@ -160,7 +196,7 @@ module Sentry
|
|
160
196
|
:client_ip => env["HTTP_CLIENT_IP"],
|
161
197
|
:real_ip => env["HTTP_X_REAL_IP"],
|
162
198
|
:forwarded_for => env["HTTP_X_FORWARDED_FOR"],
|
163
|
-
:trusted_proxies =>
|
199
|
+
:trusted_proxies => @trusted_proxies
|
164
200
|
).calculate_ip
|
165
201
|
end
|
166
202
|
end
|
data/lib/sentry/hub.rb
CHANGED
@@ -114,6 +114,9 @@ module Sentry
|
|
114
114
|
options[:hint][:message] = message
|
115
115
|
backtrace = options.delete(:backtrace)
|
116
116
|
event = current_client.event_from_message(message, options[:hint], backtrace: backtrace)
|
117
|
+
|
118
|
+
return unless event
|
119
|
+
|
117
120
|
capture_event(event, **options, &block)
|
118
121
|
end
|
119
122
|
|
data/lib/sentry/interface.rb
CHANGED
@@ -2,16 +2,7 @@
|
|
2
2
|
|
3
3
|
module Sentry
|
4
4
|
class Interface
|
5
|
-
|
6
|
-
name = klass.name.split("::").last.downcase.gsub("interface", "")
|
7
|
-
registered[name.to_sym] = klass
|
8
|
-
super
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.registered
|
12
|
-
@@registered ||= {} # rubocop:disable Style/ClassVars
|
13
|
-
end
|
14
|
-
|
5
|
+
# @return [Hash]
|
15
6
|
def to_hash
|
16
7
|
Hash[instance_variables.map { |name| [name[1..-1].to_sym, instance_variable_get(name)] }]
|
17
8
|
end
|
@@ -2,16 +2,24 @@
|
|
2
2
|
|
3
3
|
module Sentry
|
4
4
|
class ExceptionInterface < Interface
|
5
|
-
|
6
|
-
|
5
|
+
# @param exceptions [Array<SingleExceptionInterface>]
|
6
|
+
def initialize(exceptions:)
|
7
|
+
@values = exceptions
|
7
8
|
end
|
8
9
|
|
10
|
+
# @return [Hash]
|
9
11
|
def to_hash
|
10
12
|
data = super
|
11
13
|
data[:values] = data[:values].map(&:to_hash) if data[:values]
|
12
14
|
data
|
13
15
|
end
|
14
16
|
|
17
|
+
# Builds ExceptionInterface with given exception and stacktrace_builder.
|
18
|
+
# @param exception [Exception]
|
19
|
+
# @param stacktrace_builder [StacktraceBuilder]
|
20
|
+
# @see SingleExceptionInterface#build_with_stacktrace
|
21
|
+
# @see SingleExceptionInterface#initialize
|
22
|
+
# @return [ExceptionInterface]
|
15
23
|
def self.build(exception:, stacktrace_builder:)
|
16
24
|
exceptions = Sentry::Utils::ExceptionCauseChain.exception_to_array(exception).reverse
|
17
25
|
processed_backtrace_ids = Set.new
|
@@ -25,7 +33,7 @@ module Sentry
|
|
25
33
|
end
|
26
34
|
end
|
27
35
|
|
28
|
-
new(
|
36
|
+
new(exceptions: exceptions)
|
29
37
|
end
|
30
38
|
end
|
31
39
|
end
|
@@ -15,29 +15,45 @@ module Sentry
|
|
15
15
|
# https://github.com/getsentry/sentry/blob/master/src/sentry/conf/server.py
|
16
16
|
MAX_BODY_LIMIT = 4096 * 4
|
17
17
|
|
18
|
-
|
18
|
+
# @return [String]
|
19
|
+
attr_accessor :url
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
# @return [String]
|
22
|
+
attr_accessor :method
|
23
|
+
|
24
|
+
# @return [Hash]
|
25
|
+
attr_accessor :data
|
26
|
+
|
27
|
+
# @return [String]
|
28
|
+
attr_accessor :query_string
|
29
|
+
|
30
|
+
# @return [String]
|
31
|
+
attr_accessor :cookies
|
32
|
+
|
33
|
+
# @return [Hash]
|
34
|
+
attr_accessor :headers
|
25
35
|
|
26
|
-
|
27
|
-
|
36
|
+
# @return [Hash]
|
37
|
+
attr_accessor :env
|
38
|
+
|
39
|
+
# @param env [Hash]
|
40
|
+
# @param send_default_pii [Boolean]
|
41
|
+
# @param rack_env_whitelist [Array]
|
42
|
+
# @see Configuration#send_default_pii
|
43
|
+
# @see Configuration#rack_env_whitelist
|
44
|
+
def initialize(env:, send_default_pii:, rack_env_whitelist:)
|
45
|
+
env = env.dup
|
46
|
+
|
47
|
+
unless send_default_pii
|
28
48
|
# need to completely wipe out ip addresses
|
29
49
|
RequestInterface::IP_HEADERS.each do |header|
|
30
50
|
env.delete(header)
|
31
51
|
end
|
32
52
|
end
|
33
53
|
|
34
|
-
env
|
35
|
-
end
|
36
|
-
|
37
|
-
def initialize(request:)
|
38
|
-
env = request.env
|
54
|
+
request = ::Rack::Request.new(env)
|
39
55
|
|
40
|
-
if
|
56
|
+
if send_default_pii
|
41
57
|
self.data = read_data_from(request)
|
42
58
|
self.cookies = request.cookies
|
43
59
|
self.query_string = request.query_string
|
@@ -47,7 +63,7 @@ module Sentry
|
|
47
63
|
self.method = request.request_method
|
48
64
|
|
49
65
|
self.headers = filter_and_format_headers(env)
|
50
|
-
self.env = filter_and_format_env(env)
|
66
|
+
self.env = filter_and_format_env(env, rack_env_whitelist)
|
51
67
|
end
|
52
68
|
|
53
69
|
private
|
@@ -116,11 +132,11 @@ module Sentry
|
|
116
132
|
key == 'HTTP_VERSION' && value == protocol_version
|
117
133
|
end
|
118
134
|
|
119
|
-
def filter_and_format_env(env)
|
120
|
-
return env if
|
135
|
+
def filter_and_format_env(env, rack_env_whitelist)
|
136
|
+
return env if rack_env_whitelist.empty?
|
121
137
|
|
122
138
|
env.select do |k, _v|
|
123
|
-
|
139
|
+
rack_env_whitelist.include? k.to_s
|
124
140
|
end
|
125
141
|
end
|
126
142
|
end
|
@@ -2,16 +2,20 @@
|
|
2
2
|
|
3
3
|
module Sentry
|
4
4
|
class StacktraceInterface
|
5
|
+
# @return [<Array[Frame]>]
|
5
6
|
attr_reader :frames
|
6
7
|
|
8
|
+
# @param frames [<Array[Frame]>]
|
7
9
|
def initialize(frames:)
|
8
10
|
@frames = frames
|
9
11
|
end
|
10
12
|
|
13
|
+
# @return [Hash]
|
11
14
|
def to_hash
|
12
15
|
{ frames: @frames.map(&:to_hash) }
|
13
16
|
end
|
14
17
|
|
18
|
+
# @return [String]
|
15
19
|
def inspect
|
16
20
|
@frames.map(&:to_s)
|
17
21
|
end
|
@@ -2,8 +2,31 @@
|
|
2
2
|
|
3
3
|
module Sentry
|
4
4
|
class StacktraceBuilder
|
5
|
-
|
5
|
+
# @return [String]
|
6
|
+
attr_reader :project_root
|
6
7
|
|
8
|
+
# @return [Regexp, nil]
|
9
|
+
attr_reader :app_dirs_pattern
|
10
|
+
|
11
|
+
# @return [LineCache]
|
12
|
+
attr_reader :linecache
|
13
|
+
|
14
|
+
# @return [Integer, nil]
|
15
|
+
attr_reader :context_lines
|
16
|
+
|
17
|
+
# @return [Proc, nil]
|
18
|
+
attr_reader :backtrace_cleanup_callback
|
19
|
+
|
20
|
+
# @param project_root [String]
|
21
|
+
# @param app_dirs_pattern [Regexp, nil]
|
22
|
+
# @param linecache [LineCache]
|
23
|
+
# @param context_lines [Integer, nil]
|
24
|
+
# @param backtrace_cleanup_callback [Proc, nil]
|
25
|
+
# @see Configuration#project_root
|
26
|
+
# @see Configuration#app_dirs_pattern
|
27
|
+
# @see Configuration#linecache
|
28
|
+
# @see Configuration#context_lines
|
29
|
+
# @see Configuration#backtrace_cleanup_callback
|
7
30
|
def initialize(project_root:, app_dirs_pattern:, linecache:, context_lines:, backtrace_cleanup_callback: nil)
|
8
31
|
@project_root = project_root
|
9
32
|
@app_dirs_pattern = app_dirs_pattern
|
@@ -12,17 +35,21 @@ module Sentry
|
|
12
35
|
@backtrace_cleanup_callback = backtrace_cleanup_callback
|
13
36
|
end
|
14
37
|
|
15
|
-
#
|
38
|
+
# Generates a StacktraceInterface with the given backtrace.
|
39
|
+
# You can pass a block to customize/exclude frames:
|
16
40
|
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
41
|
+
# @example
|
42
|
+
# builder.build(backtrace) do |frame|
|
43
|
+
# if frame.module.match?(/a_gem/)
|
44
|
+
# nil
|
45
|
+
# else
|
46
|
+
# frame
|
47
|
+
# end
|
23
48
|
# end
|
24
|
-
#
|
25
|
-
#
|
49
|
+
# @param backtrace [Array<String>]
|
50
|
+
# @param frame_callback [Proc]
|
51
|
+
# @yieldparam frame [StacktraceInterface::Frame]
|
52
|
+
# @return [StacktraceInterface]
|
26
53
|
def build(backtrace:, &frame_callback)
|
27
54
|
parsed_lines = parse_backtrace_lines(backtrace).select(&:file)
|
28
55
|
|