sentry-ruby-core 5.17.2 → 5.17.3
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/lib/sentry/client.rb +38 -6
- data/lib/sentry/envelope.rb +17 -0
- data/lib/sentry/metrics/aggregator.rb +27 -11
- data/lib/sentry/session_flusher.rb +1 -5
- data/lib/sentry/transport.rb +7 -20
- data/lib/sentry/version.rb +1 -1
- data/lib/sentry-ruby.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe82a2b6001d48448ad45cfdfcf6eca4c99708b33ca289afc1777dac54dcd851
|
4
|
+
data.tar.gz: db84b44742d0e847b6fd66dac5a3338e63d4497723979b7c71fbbea46eb50480
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0b5cd84206fa239965fdfddc7a9570c2ca8c490f61055ec7c4b919d5e9ab299accbb6b8588a939101e4c3605a043f2e33392baa14f11a8bf1868ed78bf0f8fb7
|
7
|
+
data.tar.gz: 1348bd6636f8283af3d85934ffe414606072758939cc0027c70730f8711f933ab72d9ee23d49cd921ca3562dcd4a034f93255fe5f3eb257a0e4288815be840e5
|
data/lib/sentry/client.rb
CHANGED
@@ -49,16 +49,17 @@ module Sentry
|
|
49
49
|
return unless configuration.sending_allowed?
|
50
50
|
|
51
51
|
if event.is_a?(ErrorEvent) && !configuration.sample_allowed?
|
52
|
-
transport.record_lost_event(:sample_rate, '
|
52
|
+
transport.record_lost_event(:sample_rate, 'error')
|
53
53
|
return
|
54
54
|
end
|
55
55
|
|
56
56
|
event_type = event.is_a?(Event) ? event.type : event["type"]
|
57
|
+
data_category = Envelope::Item.data_category(event_type)
|
57
58
|
event = scope.apply_to_event(event, hint)
|
58
59
|
|
59
60
|
if event.nil?
|
60
61
|
log_debug("Discarded event because one of the event processors returned nil")
|
61
|
-
transport.record_lost_event(:event_processor,
|
62
|
+
transport.record_lost_event(:event_processor, data_category)
|
62
63
|
return
|
63
64
|
end
|
64
65
|
|
@@ -66,7 +67,7 @@ module Sentry
|
|
66
67
|
dispatch_async_event(async_block, event, hint)
|
67
68
|
elsif configuration.background_worker_threads != 0 && hint.fetch(:background, true)
|
68
69
|
queued = dispatch_background_event(event, hint)
|
69
|
-
transport.record_lost_event(:queue_overflow,
|
70
|
+
transport.record_lost_event(:queue_overflow, data_category) unless queued
|
70
71
|
else
|
71
72
|
send_event(event, hint)
|
72
73
|
end
|
@@ -77,6 +78,20 @@ module Sentry
|
|
77
78
|
nil
|
78
79
|
end
|
79
80
|
|
81
|
+
# Capture an envelope directly.
|
82
|
+
# @param envelope [Envelope] the envelope to be captured.
|
83
|
+
# @return [void]
|
84
|
+
def capture_envelope(envelope)
|
85
|
+
Sentry.background_worker.perform { send_envelope(envelope) }
|
86
|
+
end
|
87
|
+
|
88
|
+
# Flush pending events to Sentry.
|
89
|
+
# @return [void]
|
90
|
+
def flush
|
91
|
+
transport.flush if configuration.sending_to_dsn_allowed?
|
92
|
+
spotlight_transport.flush if spotlight_transport
|
93
|
+
end
|
94
|
+
|
80
95
|
# Initializes an Event object with the given exception. Returns `nil` if the exception's class is excluded from reporting.
|
81
96
|
# @param exception [Exception] the exception to be reported.
|
82
97
|
# @param hint [Hash] the hint data that'll be passed to `before_send` callback and the scope's event processors.
|
@@ -152,13 +167,14 @@ module Sentry
|
|
152
167
|
# @!macro send_event
|
153
168
|
def send_event(event, hint = nil)
|
154
169
|
event_type = event.is_a?(Event) ? event.type : event["type"]
|
170
|
+
data_category = Envelope::Item.data_category(event_type)
|
155
171
|
|
156
172
|
if event_type != TransactionEvent::TYPE && configuration.before_send
|
157
173
|
event = configuration.before_send.call(event, hint)
|
158
174
|
|
159
175
|
if event.nil?
|
160
176
|
log_debug("Discarded event because before_send returned nil")
|
161
|
-
transport.record_lost_event(:before_send,
|
177
|
+
transport.record_lost_event(:before_send, data_category)
|
162
178
|
return
|
163
179
|
end
|
164
180
|
end
|
@@ -168,7 +184,7 @@ module Sentry
|
|
168
184
|
|
169
185
|
if event.nil?
|
170
186
|
log_debug("Discarded event because before_send_transaction returned nil")
|
171
|
-
transport.record_lost_event(:before_send,
|
187
|
+
transport.record_lost_event(:before_send, data_category)
|
172
188
|
return
|
173
189
|
end
|
174
190
|
end
|
@@ -179,7 +195,23 @@ module Sentry
|
|
179
195
|
event
|
180
196
|
rescue => e
|
181
197
|
log_error("Event sending failed", e, debug: configuration.debug)
|
182
|
-
transport.record_lost_event(:network_error,
|
198
|
+
transport.record_lost_event(:network_error, data_category)
|
199
|
+
raise
|
200
|
+
end
|
201
|
+
|
202
|
+
# Send an envelope directly to Sentry.
|
203
|
+
# @param envelope [Envelope] the envelope to be sent.
|
204
|
+
# @return [void]
|
205
|
+
def send_envelope(envelope)
|
206
|
+
transport.send_envelope(envelope) if configuration.sending_to_dsn_allowed?
|
207
|
+
spotlight_transport.send_envelope(envelope) if spotlight_transport
|
208
|
+
rescue => e
|
209
|
+
log_error("Envelope sending failed", e, debug: configuration.debug)
|
210
|
+
|
211
|
+
envelope.items.map(&:data_category).each do |data_category|
|
212
|
+
transport.record_lost_event(:network_error, data_category)
|
213
|
+
end
|
214
|
+
|
183
215
|
raise
|
184
216
|
end
|
185
217
|
|
data/lib/sentry/envelope.rb
CHANGED
@@ -18,6 +18,23 @@ module Sentry
|
|
18
18
|
@headers[:type] || 'event'
|
19
19
|
end
|
20
20
|
|
21
|
+
# rate limits and client reports use the data_category rather than envelope item type
|
22
|
+
def self.data_category(type)
|
23
|
+
case type
|
24
|
+
when 'session', 'attachment', 'transaction', 'profile' then type
|
25
|
+
when 'sessions' then 'session'
|
26
|
+
when 'check_in' then 'monitor'
|
27
|
+
when 'statsd', 'metric_meta' then 'metric_bucket'
|
28
|
+
when 'event' then 'error'
|
29
|
+
when 'client_report' then 'internal'
|
30
|
+
else 'default'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def data_category
|
35
|
+
self.class.data_category(type)
|
36
|
+
end
|
37
|
+
|
21
38
|
def to_s
|
22
39
|
[JSON.generate(@headers), @payload.is_a?(String) ? @payload : JSON.generate(@payload)].join("\n")
|
23
40
|
end
|
@@ -12,8 +12,18 @@ module Sentry
|
|
12
12
|
# when we record code locations
|
13
13
|
DEFAULT_STACKLEVEL = 4
|
14
14
|
|
15
|
-
KEY_SANITIZATION_REGEX = /[^a-zA-Z0-9_
|
16
|
-
|
15
|
+
KEY_SANITIZATION_REGEX = /[^a-zA-Z0-9_\-.]+/
|
16
|
+
UNIT_SANITIZATION_REGEX = /[^a-zA-Z0-9_]+/
|
17
|
+
TAG_KEY_SANITIZATION_REGEX = /[^a-zA-Z0-9_\-.\/]+/
|
18
|
+
|
19
|
+
TAG_VALUE_SANITIZATION_MAP = {
|
20
|
+
"\n" => "\\n",
|
21
|
+
"\r" => "\\r",
|
22
|
+
"\t" => "\\t",
|
23
|
+
"\\" => "\\\\",
|
24
|
+
"|" => "\\u{7c}",
|
25
|
+
"," => "\\u{2c}"
|
26
|
+
}
|
17
27
|
|
18
28
|
METRIC_TYPES = {
|
19
29
|
c: CounterMetric,
|
@@ -23,7 +33,7 @@ module Sentry
|
|
23
33
|
}
|
24
34
|
|
25
35
|
# exposed only for testing
|
26
|
-
attr_reader :thread, :buckets, :flush_shift, :code_locations
|
36
|
+
attr_reader :client, :thread, :buckets, :flush_shift, :code_locations
|
27
37
|
|
28
38
|
def initialize(configuration, client)
|
29
39
|
@client = client
|
@@ -107,9 +117,7 @@ module Sentry
|
|
107
117
|
end
|
108
118
|
end
|
109
119
|
|
110
|
-
|
111
|
-
@client.transport.send_envelope(envelope)
|
112
|
-
end
|
120
|
+
@client.capture_envelope(envelope)
|
113
121
|
end
|
114
122
|
|
115
123
|
def kill
|
@@ -182,9 +190,9 @@ module Sentry
|
|
182
190
|
timestamp_buckets.map do |metric_key, metric|
|
183
191
|
type, key, unit, tags = metric_key
|
184
192
|
values = metric.serialize.join(':')
|
185
|
-
sanitized_tags = tags.map { |k, v| "#{
|
193
|
+
sanitized_tags = tags.map { |k, v| "#{sanitize_tag_key(k)}:#{sanitize_tag_value(v)}" }.join(',')
|
186
194
|
|
187
|
-
"#{sanitize_key(key)}@#{unit}:#{values}|#{type}|\##{sanitized_tags}|T#{timestamp}"
|
195
|
+
"#{sanitize_key(key)}@#{sanitize_unit(unit)}:#{values}|#{type}|\##{sanitized_tags}|T#{timestamp}"
|
188
196
|
end
|
189
197
|
end.flatten.join("\n")
|
190
198
|
end
|
@@ -192,7 +200,7 @@ module Sentry
|
|
192
200
|
def serialize_locations(timestamp, locations)
|
193
201
|
mapping = locations.map do |meta_key, location|
|
194
202
|
type, key, unit = meta_key
|
195
|
-
mri = "#{type}:#{sanitize_key(key)}@#{unit}"
|
203
|
+
mri = "#{type}:#{sanitize_key(key)}@#{sanitize_unit(unit)}"
|
196
204
|
|
197
205
|
# note this needs to be an array but it really doesn't serve a purpose right now
|
198
206
|
[mri, [location.merge(type: 'location')]]
|
@@ -205,8 +213,16 @@ module Sentry
|
|
205
213
|
key.gsub(KEY_SANITIZATION_REGEX, '_')
|
206
214
|
end
|
207
215
|
|
208
|
-
def
|
209
|
-
|
216
|
+
def sanitize_unit(unit)
|
217
|
+
unit.gsub(UNIT_SANITIZATION_REGEX, '')
|
218
|
+
end
|
219
|
+
|
220
|
+
def sanitize_tag_key(key)
|
221
|
+
key.gsub(TAG_KEY_SANITIZATION_REGEX, '')
|
222
|
+
end
|
223
|
+
|
224
|
+
def sanitize_tag_value(value)
|
225
|
+
value.chars.map { |c| TAG_VALUE_SANITIZATION_MAP[c] || c }.join
|
210
226
|
end
|
211
227
|
|
212
228
|
def get_transaction_name
|
@@ -20,12 +20,8 @@ module Sentry
|
|
20
20
|
|
21
21
|
def flush
|
22
22
|
return if @pending_aggregates.empty?
|
23
|
-
envelope = pending_envelope
|
24
|
-
|
25
|
-
Sentry.background_worker.perform do
|
26
|
-
@client.transport.send_envelope(envelope)
|
27
|
-
end
|
28
23
|
|
24
|
+
@client.capture_envelope(pending_envelope)
|
29
25
|
@pending_aggregates = {}
|
30
26
|
end
|
31
27
|
|
data/lib/sentry/transport.rb
CHANGED
@@ -88,18 +88,9 @@ module Sentry
|
|
88
88
|
[data, serialized_items]
|
89
89
|
end
|
90
90
|
|
91
|
-
def is_rate_limited?(
|
91
|
+
def is_rate_limited?(data_category)
|
92
92
|
# check category-specific limit
|
93
|
-
category_delay =
|
94
|
-
case item_type
|
95
|
-
when "transaction"
|
96
|
-
@rate_limits["transaction"]
|
97
|
-
when "sessions"
|
98
|
-
@rate_limits["session"]
|
99
|
-
else
|
100
|
-
@rate_limits["error"]
|
101
|
-
end
|
102
|
-
|
93
|
+
category_delay = @rate_limits[data_category]
|
103
94
|
# check universal limit if not category limit
|
104
95
|
universal_delay = @rate_limits[nil]
|
105
96
|
|
@@ -160,11 +151,11 @@ module Sentry
|
|
160
151
|
envelope
|
161
152
|
end
|
162
153
|
|
163
|
-
def record_lost_event(reason,
|
154
|
+
def record_lost_event(reason, data_category)
|
164
155
|
return unless @send_client_reports
|
165
156
|
return unless CLIENT_REPORT_REASONS.include?(reason)
|
166
157
|
|
167
|
-
@discarded_events[[reason,
|
158
|
+
@discarded_events[[reason, data_category]] += 1
|
168
159
|
end
|
169
160
|
|
170
161
|
def flush
|
@@ -184,11 +175,7 @@ module Sentry
|
|
184
175
|
return nil if @discarded_events.empty?
|
185
176
|
|
186
177
|
discarded_events_hash = @discarded_events.map do |key, val|
|
187
|
-
reason,
|
188
|
-
|
189
|
-
# 'event' has to be mapped to 'error'
|
190
|
-
category = type == 'event' ? 'error' : type
|
191
|
-
|
178
|
+
reason, category = key
|
192
179
|
{ reason: reason, category: category, quantity: val }
|
193
180
|
end
|
194
181
|
|
@@ -206,9 +193,9 @@ module Sentry
|
|
206
193
|
|
207
194
|
def reject_rate_limited_items(envelope)
|
208
195
|
envelope.items.reject! do |item|
|
209
|
-
if is_rate_limited?(item.
|
196
|
+
if is_rate_limited?(item.data_category)
|
210
197
|
log_debug("[Transport] Envelope item [#{item.type}] not sent: rate limiting")
|
211
|
-
record_lost_event(:ratelimit_backoff, item.
|
198
|
+
record_lost_event(:ratelimit_backoff, item.data_category)
|
212
199
|
|
213
200
|
true
|
214
201
|
else
|
data/lib/sentry/version.rb
CHANGED
data/lib/sentry-ruby.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sentry-ruby-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.17.
|
4
|
+
version: 5.17.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sentry Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-04-
|
11
|
+
date: 2024-04-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sentry-ruby
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 5.17.
|
19
|
+
version: 5.17.3
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 5.17.
|
26
|
+
version: 5.17.3
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: concurrent-ruby
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|