sentry-ruby-core 6.4.1 → 6.5.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/lib/sentry/baggage.rb +1 -1
- data/lib/sentry/configuration.rb +30 -0
- data/lib/sentry/dsn.rb +13 -1
- data/lib/sentry/exceptions.rb +3 -0
- data/lib/sentry/metric_event.rb +1 -1
- data/lib/sentry/propagation_context.rb +48 -8
- data/lib/sentry/release_detector.rb +1 -1
- data/lib/sentry/scope.rb +1 -0
- data/lib/sentry/transaction.rb +2 -1
- data/lib/sentry/transport/http_transport.rb +6 -0
- data/lib/sentry/transport.rb +6 -1
- data/lib/sentry/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e2784eb13a9b7e212a5bc3c607cd305e835631596418688c3a1e0e2fbcdfaa7a
|
|
4
|
+
data.tar.gz: 4d15760d10a1093a747d74caa928b6812d8b5b24c81698c01833bc52b5a775a3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cd34baa8e81dbe92f33bb98ceedb8f526efd1406ca724e98eb86a0ea8d78585e31302037394961679850b11766a2ad777f9987dca3a94075421330043764ee10
|
|
7
|
+
data.tar.gz: f3cca1b504d70ac8f9f6e2083826c4f2fbcc7df5bf8da3438daf0a74ec1c7034ba4c0a98859ad291ac7cd453e88ca7be4af2a5722c1bb432f096f56e014ce83d
|
data/lib/sentry/baggage.rb
CHANGED
|
@@ -25,7 +25,7 @@ module Sentry
|
|
|
25
25
|
# The presence of a Sentry item makes the baggage object immutable.
|
|
26
26
|
#
|
|
27
27
|
# @param header [String] The incoming Baggage header string.
|
|
28
|
-
# @return [Baggage
|
|
28
|
+
# @return [Baggage]
|
|
29
29
|
def self.from_incoming_header(header)
|
|
30
30
|
items = {}
|
|
31
31
|
mutable = true
|
data/lib/sentry/configuration.rb
CHANGED
|
@@ -371,6 +371,24 @@ module Sentry
|
|
|
371
371
|
# @return [Proc, nil]
|
|
372
372
|
attr_reader :std_lib_logger_filter
|
|
373
373
|
|
|
374
|
+
# An optional organization ID. The SDK will try to extract it from the DSN in most cases
|
|
375
|
+
# but you can provide it explicitly for self-hosted and Relay setups.
|
|
376
|
+
# This value is used for trace propagation and for features like strict_trace_continuation.
|
|
377
|
+
# @return [String, nil]
|
|
378
|
+
attr_reader :org_id
|
|
379
|
+
|
|
380
|
+
# If set to true, the SDK will only continue a trace if the org_id of the incoming trace found in the
|
|
381
|
+
# baggage header matches the org_id of the current Sentry client and only if BOTH are present.
|
|
382
|
+
#
|
|
383
|
+
# If set to false, consistency of org_id will only be enforced if both are present.
|
|
384
|
+
# If either are missing, the trace will be continued.
|
|
385
|
+
#
|
|
386
|
+
# The client's organization ID is extracted from the DSN or can be set with the org_id option.
|
|
387
|
+
# If the organization IDs do not match, the SDK will start a new trace instead of continuing the incoming one.
|
|
388
|
+
# This is useful to prevent traces of unknown third-party services from being continued in your application.
|
|
389
|
+
# @return [Boolean]
|
|
390
|
+
attr_accessor :strict_trace_continuation
|
|
391
|
+
|
|
374
392
|
# these are not config options
|
|
375
393
|
# @!visibility private
|
|
376
394
|
attr_reader :errors, :gem_specs
|
|
@@ -520,6 +538,8 @@ module Sentry
|
|
|
520
538
|
self.trusted_proxies = []
|
|
521
539
|
self.dsn = ENV["SENTRY_DSN"]
|
|
522
540
|
self.capture_queue_time = true
|
|
541
|
+
self.org_id = nil
|
|
542
|
+
self.strict_trace_continuation = false
|
|
523
543
|
|
|
524
544
|
spotlight_env = ENV["SENTRY_SPOTLIGHT"]
|
|
525
545
|
spotlight_bool = Sentry::Utils::EnvHelper.env_to_bool(spotlight_env, strict: true)
|
|
@@ -673,6 +693,16 @@ module Sentry
|
|
|
673
693
|
@profiler_class = profiler_class
|
|
674
694
|
end
|
|
675
695
|
|
|
696
|
+
def org_id=(value)
|
|
697
|
+
@org_id = value&.to_s
|
|
698
|
+
end
|
|
699
|
+
|
|
700
|
+
# Returns the effective org ID, preferring the explicit config option over the DSN-parsed value.
|
|
701
|
+
# @return [String, nil]
|
|
702
|
+
def effective_org_id
|
|
703
|
+
org_id || dsn&.org_id
|
|
704
|
+
end
|
|
705
|
+
|
|
676
706
|
def sending_allowed?
|
|
677
707
|
spotlight || sending_to_dsn_allowed?
|
|
678
708
|
end
|
data/lib/sentry/dsn.rb
CHANGED
|
@@ -11,8 +11,9 @@ module Sentry
|
|
|
11
11
|
REQUIRED_ATTRIBUTES = %w[host path public_key project_id].freeze
|
|
12
12
|
LOCALHOST_NAMES = %w[localhost 127.0.0.1 ::1 [::1]].freeze
|
|
13
13
|
LOCALHOST_PATTERN = /\.local(host|domain)?$/i
|
|
14
|
+
ORG_ID_REGEX = /\Ao(\d+)\./
|
|
14
15
|
|
|
15
|
-
attr_reader :scheme, :secret_key, :port, *REQUIRED_ATTRIBUTES
|
|
16
|
+
attr_reader :scheme, :secret_key, :port, :org_id, *REQUIRED_ATTRIBUTES
|
|
16
17
|
|
|
17
18
|
def initialize(dsn_string)
|
|
18
19
|
@raw_value = dsn_string
|
|
@@ -31,6 +32,8 @@ module Sentry
|
|
|
31
32
|
@host = uri.host
|
|
32
33
|
@port = uri.port if uri.port
|
|
33
34
|
@path = uri_path.join("/")
|
|
35
|
+
|
|
36
|
+
@org_id = extract_org_id_from_host
|
|
34
37
|
end
|
|
35
38
|
|
|
36
39
|
def valid?
|
|
@@ -101,5 +104,14 @@ module Sentry
|
|
|
101
104
|
|
|
102
105
|
"Sentry " + fields.map { |key, value| "#{key}=#{value}" }.join(", ")
|
|
103
106
|
end
|
|
107
|
+
|
|
108
|
+
private
|
|
109
|
+
|
|
110
|
+
def extract_org_id_from_host
|
|
111
|
+
return nil unless @host
|
|
112
|
+
|
|
113
|
+
match = ORG_ID_REGEX.match(@host)
|
|
114
|
+
match ? match[1] : nil
|
|
115
|
+
end
|
|
104
116
|
end
|
|
105
117
|
end
|
data/lib/sentry/exceptions.rb
CHANGED
data/lib/sentry/metric_event.rb
CHANGED
|
@@ -53,6 +53,44 @@ module Sentry
|
|
|
53
53
|
[trace_id, parent_span_id, parent_sampled]
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
+
# Determines whether we should continue an incoming trace based on org_id matching
|
|
57
|
+
# and the strict_trace_continuation configuration option.
|
|
58
|
+
#
|
|
59
|
+
# @param incoming_baggage [Baggage] the baggage from the incoming request
|
|
60
|
+
# @return [Boolean]
|
|
61
|
+
def self.should_continue_trace?(incoming_baggage)
|
|
62
|
+
return true unless Sentry.initialized?
|
|
63
|
+
|
|
64
|
+
configuration = Sentry.configuration
|
|
65
|
+
sdk_org_id = configuration.effective_org_id
|
|
66
|
+
baggage_org_id = incoming_baggage.items["org_id"]
|
|
67
|
+
|
|
68
|
+
# Mismatched org IDs always start a new trace regardless of strict mode
|
|
69
|
+
if sdk_org_id && baggage_org_id && sdk_org_id != baggage_org_id
|
|
70
|
+
Sentry.sdk_logger.debug(LOGGER_PROGNAME) do
|
|
71
|
+
"Starting a new trace because org IDs don't match (incoming baggage org_id: #{baggage_org_id}, SDK org_id: #{sdk_org_id})"
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
return false
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
return true unless configuration.strict_trace_continuation
|
|
78
|
+
|
|
79
|
+
# In strict mode, both must be present and match (unless both are missing)
|
|
80
|
+
if sdk_org_id.nil? && baggage_org_id.nil?
|
|
81
|
+
true
|
|
82
|
+
elsif sdk_org_id.nil? || baggage_org_id.nil?
|
|
83
|
+
Sentry.sdk_logger.debug(LOGGER_PROGNAME) do
|
|
84
|
+
"Starting a new trace because strict trace continuation is enabled and one org ID is missing " \
|
|
85
|
+
"(incoming baggage org_id: #{baggage_org_id.inspect}, SDK org_id: #{sdk_org_id.inspect})"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
false
|
|
89
|
+
else
|
|
90
|
+
true
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
56
94
|
def self.extract_sample_rand_from_baggage(baggage, trace_id = nil)
|
|
57
95
|
return unless baggage&.items
|
|
58
96
|
|
|
@@ -96,9 +134,7 @@ module Sentry
|
|
|
96
134
|
sentry_trace_data = self.class.extract_sentry_trace(sentry_trace_header)
|
|
97
135
|
|
|
98
136
|
if sentry_trace_data
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
@baggage =
|
|
137
|
+
incoming_baggage =
|
|
102
138
|
if baggage_header && !baggage_header.empty?
|
|
103
139
|
Baggage.from_incoming_header(baggage_header)
|
|
104
140
|
else
|
|
@@ -108,10 +144,13 @@ module Sentry
|
|
|
108
144
|
Baggage.new({})
|
|
109
145
|
end
|
|
110
146
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
147
|
+
if self.class.should_continue_trace?(incoming_baggage)
|
|
148
|
+
@trace_id, @parent_span_id, @parent_sampled = sentry_trace_data
|
|
149
|
+
@baggage = incoming_baggage
|
|
150
|
+
@sample_rand = self.class.extract_sample_rand_from_baggage(@baggage, @trace_id)
|
|
151
|
+
@baggage.freeze!
|
|
152
|
+
@incoming_trace = true
|
|
153
|
+
end
|
|
115
154
|
end
|
|
116
155
|
end
|
|
117
156
|
end
|
|
@@ -162,7 +201,8 @@ module Sentry
|
|
|
162
201
|
"sample_rand" => Utils::SampleRand.format(@sample_rand),
|
|
163
202
|
"environment" => configuration.environment,
|
|
164
203
|
"release" => configuration.release,
|
|
165
|
-
"public_key" => configuration.dsn&.public_key
|
|
204
|
+
"public_key" => configuration.dsn&.public_key,
|
|
205
|
+
"org_id" => configuration.effective_org_id
|
|
166
206
|
}
|
|
167
207
|
|
|
168
208
|
items.compact!
|
data/lib/sentry/scope.rb
CHANGED
data/lib/sentry/transaction.rb
CHANGED
|
@@ -295,7 +295,8 @@ module Sentry
|
|
|
295
295
|
"sampled" => sampled&.to_s,
|
|
296
296
|
"environment" => configuration&.environment,
|
|
297
297
|
"release" => configuration&.release,
|
|
298
|
-
"public_key" => configuration&.dsn&.public_key
|
|
298
|
+
"public_key" => configuration&.dsn&.public_key,
|
|
299
|
+
"org_id" => configuration&.effective_org_id
|
|
299
300
|
}
|
|
300
301
|
|
|
301
302
|
items["transaction"] = name unless source_low_quality?
|
|
@@ -49,6 +49,12 @@ module Sentry
|
|
|
49
49
|
|
|
50
50
|
if response.code.match?(/\A2\d{2}/)
|
|
51
51
|
handle_rate_limited_response(response) if has_rate_limited_header?(response)
|
|
52
|
+
elsif response.code == "413"
|
|
53
|
+
error_message = "HTTP 413: Envelope dropped due to exceeded size limit"
|
|
54
|
+
error_message += " (body: #{response.body})" if response.body && !response.body.empty?
|
|
55
|
+
log_warn(error_message)
|
|
56
|
+
|
|
57
|
+
raise Sentry::SizeExceededError, error_message
|
|
52
58
|
elsif response.code == "429"
|
|
53
59
|
log_debug("the server responded with status 429")
|
|
54
60
|
handle_rate_limited_response(response)
|
data/lib/sentry/transport.rb
CHANGED
|
@@ -19,7 +19,8 @@ module Sentry
|
|
|
19
19
|
:before_send,
|
|
20
20
|
:event_processor,
|
|
21
21
|
:insufficient_data,
|
|
22
|
-
:backpressure
|
|
22
|
+
:backpressure,
|
|
23
|
+
:send_error
|
|
23
24
|
]
|
|
24
25
|
|
|
25
26
|
include LoggingHelper
|
|
@@ -61,6 +62,10 @@ module Sentry
|
|
|
61
62
|
log_debug("[Transport] Sending envelope with items [#{serialized_items.map(&:type).join(', ')}] #{envelope.event_id} to Sentry")
|
|
62
63
|
send_data(data)
|
|
63
64
|
end
|
|
65
|
+
rescue Sentry::SizeExceededError
|
|
66
|
+
serialized_items&.each do |item|
|
|
67
|
+
record_lost_event(:send_error, item.data_category)
|
|
68
|
+
end
|
|
64
69
|
end
|
|
65
70
|
|
|
66
71
|
def serialize_envelope(envelope)
|
data/lib/sentry/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sentry-ruby-core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 6.
|
|
4
|
+
version: 6.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sentry Team
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 6.
|
|
18
|
+
version: 6.5.0
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - '='
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 6.
|
|
25
|
+
version: 6.5.0
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: concurrent-ruby
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|