sentry-ruby 5.16.1 → 5.17.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/Rakefile +1 -1
- data/lib/sentry/background_worker.rb +1 -1
- data/lib/sentry/backtrace.rb +7 -3
- data/lib/sentry/check_in_event.rb +1 -1
- data/lib/sentry/client.rb +42 -9
- data/lib/sentry/configuration.rb +19 -11
- data/lib/sentry/cron/monitor_schedule.rb +1 -1
- data/lib/sentry/dsn.rb +1 -1
- data/lib/sentry/envelope.rb +18 -1
- data/lib/sentry/error_event.rb +2 -2
- data/lib/sentry/event.rb +8 -8
- data/lib/sentry/hub.rb +1 -1
- data/lib/sentry/integrable.rb +4 -0
- data/lib/sentry/interface.rb +1 -0
- data/lib/sentry/interfaces/exception.rb +5 -3
- data/lib/sentry/interfaces/mechanism.rb +20 -0
- data/lib/sentry/interfaces/request.rb +2 -2
- data/lib/sentry/interfaces/single_exception.rb +6 -4
- data/lib/sentry/interfaces/stacktrace_builder.rb +8 -0
- data/lib/sentry/metrics/aggregator.rb +276 -0
- data/lib/sentry/metrics/configuration.rb +47 -0
- data/lib/sentry/metrics/counter_metric.rb +25 -0
- data/lib/sentry/metrics/distribution_metric.rb +25 -0
- data/lib/sentry/metrics/gauge_metric.rb +35 -0
- data/lib/sentry/metrics/local_aggregator.rb +53 -0
- data/lib/sentry/metrics/metric.rb +19 -0
- data/lib/sentry/metrics/set_metric.rb +28 -0
- data/lib/sentry/metrics/timing.rb +43 -0
- data/lib/sentry/metrics.rb +55 -0
- data/lib/sentry/propagation_context.rb +9 -8
- data/lib/sentry/puma.rb +1 -1
- data/lib/sentry/rack/capture_exceptions.rb +6 -1
- data/lib/sentry/rake.rb +3 -1
- data/lib/sentry/scope.rb +7 -2
- data/lib/sentry/session.rb +2 -2
- data/lib/sentry/session_flusher.rb +1 -6
- data/lib/sentry/span.rb +16 -2
- data/lib/sentry/transaction.rb +15 -14
- data/lib/sentry/transaction_event.rb +5 -0
- data/lib/sentry/transport/configuration.rb +0 -1
- data/lib/sentry/transport.rb +7 -21
- data/lib/sentry/utils/argument_checking_helper.rb +6 -0
- data/lib/sentry/utils/real_ip.rb +1 -1
- data/lib/sentry/utils/request_id.rb +1 -1
- data/lib/sentry/version.rb +1 -1
- data/lib/sentry-ruby.rb +15 -3
- data/sentry-ruby.gemspec +1 -0
- metadata +27 -2
data/lib/sentry/scope.rb
CHANGED
@@ -252,6 +252,12 @@ module Sentry
|
|
252
252
|
@transaction_sources.last
|
253
253
|
end
|
254
254
|
|
255
|
+
# These are high cardinality and thus bad.
|
256
|
+
# @return [Boolean]
|
257
|
+
def transaction_source_low_quality?
|
258
|
+
transaction_source == :url
|
259
|
+
end
|
260
|
+
|
255
261
|
# Returns the associated Transaction object.
|
256
262
|
# @return [Transaction, nil]
|
257
263
|
def get_transaction
|
@@ -295,7 +301,7 @@ module Sentry
|
|
295
301
|
private
|
296
302
|
|
297
303
|
def set_default_value
|
298
|
-
@contexts = { :
|
304
|
+
@contexts = { os: self.class.os_context, runtime: self.class.runtime_context }
|
299
305
|
@extra = {}
|
300
306
|
@tags = {}
|
301
307
|
@user = {}
|
@@ -355,6 +361,5 @@ module Sentry
|
|
355
361
|
global_event_processors << block
|
356
362
|
end
|
357
363
|
end
|
358
|
-
|
359
364
|
end
|
360
365
|
end
|
data/lib/sentry/session.rb
CHANGED
@@ -5,8 +5,8 @@ module Sentry
|
|
5
5
|
attr_reader :started, :status, :aggregation_key
|
6
6
|
|
7
7
|
# TODO-neel add :crashed after adding handled mechanism
|
8
|
-
STATUSES = %i
|
9
|
-
AGGREGATE_STATUSES = %i
|
8
|
+
STATUSES = %i[ok errored exited]
|
9
|
+
AGGREGATE_STATUSES = %i[errored exited]
|
10
10
|
|
11
11
|
def initialize
|
12
12
|
@started = Sentry.utc_now
|
@@ -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
|
|
@@ -85,6 +81,5 @@ module Sentry
|
|
85
81
|
end
|
86
82
|
end
|
87
83
|
end
|
88
|
-
|
89
84
|
end
|
90
85
|
end
|
data/lib/sentry/span.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "securerandom"
|
4
|
+
require "sentry/metrics/local_aggregator"
|
4
5
|
|
5
6
|
module Sentry
|
6
7
|
class Span
|
7
|
-
|
8
8
|
# We will try to be consistent with OpenTelemetry on this front going forward.
|
9
9
|
# https://develop.sentry.dev/sdk/performance/span-data-conventions/
|
10
10
|
module DataConventions
|
@@ -150,7 +150,7 @@ module Sentry
|
|
150
150
|
|
151
151
|
# @return [Hash]
|
152
152
|
def to_hash
|
153
|
-
{
|
153
|
+
hash = {
|
154
154
|
trace_id: @trace_id,
|
155
155
|
span_id: @span_id,
|
156
156
|
parent_span_id: @parent_span_id,
|
@@ -162,6 +162,11 @@ module Sentry
|
|
162
162
|
tags: @tags,
|
163
163
|
data: @data
|
164
164
|
}
|
165
|
+
|
166
|
+
summary = metrics_summary
|
167
|
+
hash[:_metrics_summary] = summary if summary
|
168
|
+
|
169
|
+
hash
|
165
170
|
end
|
166
171
|
|
167
172
|
# Returns the span's context that can be used to embed in an Event.
|
@@ -269,5 +274,14 @@ module Sentry
|
|
269
274
|
def set_tag(key, value)
|
270
275
|
@tags[key] = value
|
271
276
|
end
|
277
|
+
|
278
|
+
# Collects gauge metrics on the span for metric summaries.
|
279
|
+
def metrics_local_aggregator
|
280
|
+
@metrics_local_aggregator ||= Sentry::Metrics::LocalAggregator.new
|
281
|
+
end
|
282
|
+
|
283
|
+
def metrics_summary
|
284
|
+
@metrics_local_aggregator&.to_hash
|
285
|
+
end
|
272
286
|
end
|
273
287
|
end
|
data/lib/sentry/transaction.rb
CHANGED
@@ -13,7 +13,7 @@ module Sentry
|
|
13
13
|
MESSAGE_PREFIX = "[Tracing]"
|
14
14
|
|
15
15
|
# https://develop.sentry.dev/sdk/event-payloads/transaction/#transaction-annotations
|
16
|
-
SOURCES = %i
|
16
|
+
SOURCES = %i[custom url route view component task]
|
17
17
|
|
18
18
|
include LoggingHelper
|
19
19
|
|
@@ -110,14 +110,15 @@ module Sentry
|
|
110
110
|
|
111
111
|
trace_id, parent_span_id, parent_sampled = sentry_trace_data
|
112
112
|
|
113
|
-
baggage =
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
113
|
+
baggage =
|
114
|
+
if baggage && !baggage.empty?
|
115
|
+
Baggage.from_incoming_header(baggage)
|
116
|
+
else
|
117
|
+
# If there's an incoming sentry-trace but no incoming baggage header,
|
118
|
+
# for instance in traces coming from older SDKs,
|
119
|
+
# baggage will be empty and frozen and won't be populated as head SDK.
|
120
|
+
Baggage.new({})
|
121
|
+
end
|
121
122
|
|
122
123
|
baggage.freeze!
|
123
124
|
|
@@ -301,6 +302,11 @@ module Sentry
|
|
301
302
|
profiler.start
|
302
303
|
end
|
303
304
|
|
305
|
+
# These are high cardinality and thus bad
|
306
|
+
def source_low_quality?
|
307
|
+
source == :url
|
308
|
+
end
|
309
|
+
|
304
310
|
protected
|
305
311
|
|
306
312
|
def init_span_recorder(limit = 1000)
|
@@ -336,11 +342,6 @@ module Sentry
|
|
336
342
|
@baggage = Baggage.new(items, mutable: false)
|
337
343
|
end
|
338
344
|
|
339
|
-
# These are high cardinality and thus bad
|
340
|
-
def source_low_quality?
|
341
|
-
source == :url
|
342
|
-
end
|
343
|
-
|
344
345
|
class SpanRecorder
|
345
346
|
attr_reader :max_length, :spans
|
346
347
|
|
@@ -17,6 +17,9 @@ module Sentry
|
|
17
17
|
# @return [Hash, nil]
|
18
18
|
attr_accessor :profile
|
19
19
|
|
20
|
+
# @return [Hash, nil]
|
21
|
+
attr_accessor :metrics_summary
|
22
|
+
|
20
23
|
def initialize(transaction:, **options)
|
21
24
|
super(**options)
|
22
25
|
|
@@ -29,6 +32,7 @@ module Sentry
|
|
29
32
|
self.tags = transaction.tags
|
30
33
|
self.dynamic_sampling_context = transaction.get_baggage.dynamic_sampling_context
|
31
34
|
self.measurements = transaction.measurements
|
35
|
+
self.metrics_summary = transaction.metrics_summary
|
32
36
|
|
33
37
|
finished_spans = transaction.span_recorder.spans.select { |span| span.timestamp && span != transaction }
|
34
38
|
self.spans = finished_spans.map(&:to_hash)
|
@@ -49,6 +53,7 @@ module Sentry
|
|
49
53
|
data[:spans] = @spans.map(&:to_hash) if @spans
|
50
54
|
data[:start_timestamp] = @start_timestamp
|
51
55
|
data[:measurements] = @measurements
|
56
|
+
data[:_metrics_summary] = @metrics_summary if @metrics_summary
|
52
57
|
data
|
53
58
|
end
|
54
59
|
|
data/lib/sentry/transport.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "json"
|
4
|
-
require "base64"
|
5
4
|
require "sentry/envelope"
|
6
5
|
|
7
6
|
module Sentry
|
@@ -89,18 +88,9 @@ module Sentry
|
|
89
88
|
[data, serialized_items]
|
90
89
|
end
|
91
90
|
|
92
|
-
def is_rate_limited?(
|
91
|
+
def is_rate_limited?(data_category)
|
93
92
|
# check category-specific limit
|
94
|
-
category_delay =
|
95
|
-
case item_type
|
96
|
-
when "transaction"
|
97
|
-
@rate_limits["transaction"]
|
98
|
-
when "sessions"
|
99
|
-
@rate_limits["session"]
|
100
|
-
else
|
101
|
-
@rate_limits["error"]
|
102
|
-
end
|
103
|
-
|
93
|
+
category_delay = @rate_limits[data_category]
|
104
94
|
# check universal limit if not category limit
|
105
95
|
universal_delay = @rate_limits[nil]
|
106
96
|
|
@@ -161,11 +151,11 @@ module Sentry
|
|
161
151
|
envelope
|
162
152
|
end
|
163
153
|
|
164
|
-
def record_lost_event(reason,
|
154
|
+
def record_lost_event(reason, data_category)
|
165
155
|
return unless @send_client_reports
|
166
156
|
return unless CLIENT_REPORT_REASONS.include?(reason)
|
167
157
|
|
168
|
-
@discarded_events[[reason,
|
158
|
+
@discarded_events[[reason, data_category]] += 1
|
169
159
|
end
|
170
160
|
|
171
161
|
def flush
|
@@ -185,11 +175,7 @@ module Sentry
|
|
185
175
|
return nil if @discarded_events.empty?
|
186
176
|
|
187
177
|
discarded_events_hash = @discarded_events.map do |key, val|
|
188
|
-
reason,
|
189
|
-
|
190
|
-
# 'event' has to be mapped to 'error'
|
191
|
-
category = type == 'event' ? 'error' : type
|
192
|
-
|
178
|
+
reason, category = key
|
193
179
|
{ reason: reason, category: category, quantity: val }
|
194
180
|
end
|
195
181
|
|
@@ -207,9 +193,9 @@ module Sentry
|
|
207
193
|
|
208
194
|
def reject_rate_limited_items(envelope)
|
209
195
|
envelope.items.reject! do |item|
|
210
|
-
if is_rate_limited?(item.
|
196
|
+
if is_rate_limited?(item.data_category)
|
211
197
|
log_debug("[Transport] Envelope item [#{item.type}] not sent: rate limiting")
|
212
|
-
record_lost_event(:ratelimit_backoff, item.
|
198
|
+
record_lost_event(:ratelimit_backoff, item.data_category)
|
213
199
|
|
214
200
|
true
|
215
201
|
else
|
@@ -15,5 +15,11 @@ module Sentry
|
|
15
15
|
raise ArgumentError, "expect the argument to be one of #{values.map(&:inspect).join(' or ')}, got #{argument.inspect}"
|
16
16
|
end
|
17
17
|
end
|
18
|
+
|
19
|
+
def check_callable!(name, value)
|
20
|
+
unless value == nil || value.respond_to?(:call)
|
21
|
+
raise ArgumentError, "#{name} must be callable (or nil to disable)"
|
22
|
+
end
|
23
|
+
end
|
18
24
|
end
|
19
25
|
end
|
data/lib/sentry/utils/real_ip.rb
CHANGED
@@ -15,7 +15,7 @@ module Sentry
|
|
15
15
|
"fc00::/7", # private IPv6 range fc00::/7
|
16
16
|
"10.0.0.0/8", # private IPv4 range 10.x.x.x
|
17
17
|
"172.16.0.0/12", # private IPv4 range 172.16.0.0 .. 172.31.255.255
|
18
|
-
"192.168.0.0/16"
|
18
|
+
"192.168.0.0/16" # private IPv4 range 192.168.x.x
|
19
19
|
]
|
20
20
|
|
21
21
|
attr_reader :ip
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Sentry
|
4
4
|
module Utils
|
5
5
|
module RequestId
|
6
|
-
REQUEST_ID_HEADERS = %w
|
6
|
+
REQUEST_ID_HEADERS = %w[action_dispatch.request_id HTTP_X_REQUEST_ID].freeze
|
7
7
|
|
8
8
|
# Request ID based on ActionDispatch::RequestId
|
9
9
|
def self.read_from(env)
|
data/lib/sentry/version.rb
CHANGED
data/lib/sentry-ruby.rb
CHANGED
@@ -23,10 +23,11 @@ require "sentry/background_worker"
|
|
23
23
|
require "sentry/session_flusher"
|
24
24
|
require "sentry/backpressure_monitor"
|
25
25
|
require "sentry/cron/monitor_check_ins"
|
26
|
+
require "sentry/metrics"
|
26
27
|
|
27
28
|
[
|
28
29
|
"sentry/rake",
|
29
|
-
"sentry/rack"
|
30
|
+
"sentry/rack"
|
30
31
|
].each do |lib|
|
31
32
|
begin
|
32
33
|
require lib
|
@@ -77,6 +78,10 @@ module Sentry
|
|
77
78
|
# @return [BackpressureMonitor, nil]
|
78
79
|
attr_reader :backpressure_monitor
|
79
80
|
|
81
|
+
# @!attribute [r] metrics_aggregator
|
82
|
+
# @return [Metrics::Aggregator, nil]
|
83
|
+
attr_reader :metrics_aggregator
|
84
|
+
|
80
85
|
##### Patch Registration #####
|
81
86
|
|
82
87
|
# @!visibility private
|
@@ -222,8 +227,9 @@ module Sentry
|
|
222
227
|
Thread.current.thread_variable_set(THREAD_LOCAL, hub)
|
223
228
|
@main_hub = hub
|
224
229
|
@background_worker = Sentry::BackgroundWorker.new(config)
|
225
|
-
@session_flusher = config.
|
230
|
+
@session_flusher = config.session_tracking? ? Sentry::SessionFlusher.new(config, client) : nil
|
226
231
|
@backpressure_monitor = config.enable_backpressure_handling ? Sentry::BackpressureMonitor.new(config, client) : nil
|
232
|
+
@metrics_aggregator = config.metrics.enabled ? Sentry::Metrics::Aggregator.new(config, client) : nil
|
227
233
|
exception_locals_tp.enable if config.include_local_variables
|
228
234
|
at_exit { close }
|
229
235
|
end
|
@@ -244,8 +250,14 @@ module Sentry
|
|
244
250
|
@backpressure_monitor = nil
|
245
251
|
end
|
246
252
|
|
253
|
+
if @metrics_aggregator
|
254
|
+
@metrics_aggregator.flush(force: true)
|
255
|
+
@metrics_aggregator.kill
|
256
|
+
@metrics_aggregator = nil
|
257
|
+
end
|
258
|
+
|
247
259
|
if client = get_current_client
|
248
|
-
client.
|
260
|
+
client.flush
|
249
261
|
|
250
262
|
if client.configuration.include_local_variables
|
251
263
|
exception_locals_tp.disable
|
data/sentry-ruby.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sentry-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
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-
|
11
|
+
date: 2024-04-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -30,6 +30,20 @@ dependencies:
|
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 1.0.2
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: bigdecimal
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
33
47
|
description: A gem that provides a client interface for the Sentry error logger
|
34
48
|
email: accounts@sentry.io
|
35
49
|
executables: []
|
@@ -75,6 +89,7 @@ files:
|
|
75
89
|
- lib/sentry/integrable.rb
|
76
90
|
- lib/sentry/interface.rb
|
77
91
|
- lib/sentry/interfaces/exception.rb
|
92
|
+
- lib/sentry/interfaces/mechanism.rb
|
78
93
|
- lib/sentry/interfaces/request.rb
|
79
94
|
- lib/sentry/interfaces/single_exception.rb
|
80
95
|
- lib/sentry/interfaces/stacktrace.rb
|
@@ -82,6 +97,16 @@ files:
|
|
82
97
|
- lib/sentry/interfaces/threads.rb
|
83
98
|
- lib/sentry/linecache.rb
|
84
99
|
- lib/sentry/logger.rb
|
100
|
+
- lib/sentry/metrics.rb
|
101
|
+
- lib/sentry/metrics/aggregator.rb
|
102
|
+
- lib/sentry/metrics/configuration.rb
|
103
|
+
- lib/sentry/metrics/counter_metric.rb
|
104
|
+
- lib/sentry/metrics/distribution_metric.rb
|
105
|
+
- lib/sentry/metrics/gauge_metric.rb
|
106
|
+
- lib/sentry/metrics/local_aggregator.rb
|
107
|
+
- lib/sentry/metrics/metric.rb
|
108
|
+
- lib/sentry/metrics/set_metric.rb
|
109
|
+
- lib/sentry/metrics/timing.rb
|
85
110
|
- lib/sentry/net/http.rb
|
86
111
|
- lib/sentry/profiler.rb
|
87
112
|
- lib/sentry/propagation_context.rb
|