sentry-ruby-core 5.4.2 → 5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c0a38f443aaf54712189bf04c5488c0dcaacb6efebbee219b0cf09a4b3e6f3be
4
- data.tar.gz: 648b58bcbb161af13f75582c686de061b12772901af789a5e9741667d1b803dd
3
+ metadata.gz: db4ea8b565496ba29fe0e5eae4c3f86a68ac789ab05c036153183dc3638b0465
4
+ data.tar.gz: 5c11d4679189282fba1da3ae2a78744b25391a1f3f174ea29b51fbdbee994bf9
5
5
  SHA512:
6
- metadata.gz: 84699d5507caa44203dd25b094e4a9e131522012b773bd96efd43a16b17fd670e47ad46e5bba8291806715f8e2718109c2f93392674d622b491c5cbb488a1ddc
7
- data.tar.gz: 0cf5e5774b06593c750b2c738246276bd2b21d0c27364c53257f604428388cbd5842d72d0f9a81fb4ca011b84a587a4a80388c7436c895a459aff4bde51bef22
6
+ metadata.gz: fd0a1a54f07adb2ea7b5d029423b2bb9c44bb79342cb2b3c0fa367e0aec90c4b4cac822234223c947bfce783260b7e844957b16ab81a7db2ad1542be37cc6de8
7
+ data.tar.gz: 91b8e37e42991183ea66d8d7e71ce33b9051d094059327b0e972159052a580c05cccb553615ca76410b7bef3426fd8989af338478d6ab890f2648681f855a270
data/Gemfile CHANGED
@@ -3,12 +3,13 @@ git_source(:github) { |name| "https://github.com/#{name}.git" }
3
3
 
4
4
  gem "sentry-ruby", path: "./"
5
5
 
6
- gem "rack" unless ENV["WITHOUT_RACK"] == "1"
6
+ rack_version = ENV["RACK_VERSION"]
7
+ rack_version = "3.0.0" if rack_version.nil?
8
+ gem "rack", "~> #{Gem::Version.new(rack_version)}" unless rack_version == "0"
7
9
 
8
10
  gem "rake", "~> 12.0"
9
11
  gem "rspec", "~> 3.0"
10
12
  gem "rspec-retry"
11
- gem "webmock"
12
13
  gem "fakeredis"
13
14
  gem "timecop"
14
15
  gem 'simplecov'
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cgi'
4
+
5
+ module Sentry
6
+ # A {https://www.w3.org/TR/baggage W3C Baggage Header} implementation.
7
+ class Baggage
8
+ SENTRY_PREFIX = 'sentry-'
9
+ SENTRY_PREFIX_REGEX = /^sentry-/.freeze
10
+
11
+ DSC_KEYS = %w(
12
+ trace_id
13
+ public_key
14
+ sample_rate
15
+ release
16
+ environment
17
+ transaction
18
+ user_id
19
+ user_segment
20
+ ).freeze
21
+
22
+ # @return [Hash]
23
+ attr_reader :items
24
+
25
+ # @return [Boolean]
26
+ attr_reader :mutable
27
+
28
+ def initialize(items, mutable: true)
29
+ @items = items
30
+ @mutable = mutable
31
+ end
32
+
33
+ # Creates a Baggage object from an incoming W3C Baggage header string.
34
+ #
35
+ # Sentry items are identified with the 'sentry-' prefix and stored in a hash.
36
+ # The presence of a Sentry item makes the baggage object immutable.
37
+ #
38
+ # @param header [String] The incoming Baggage header string.
39
+ # @return [Baggage, nil]
40
+ def self.from_incoming_header(header)
41
+ items = {}
42
+ mutable = true
43
+
44
+ header.split(',').each do |item|
45
+ item = item.strip
46
+ key, val = item.split('=')
47
+
48
+ next unless key && val
49
+ next unless key =~ SENTRY_PREFIX_REGEX
50
+
51
+ baggage_key = key.split('-')[1]
52
+ next unless baggage_key
53
+
54
+ items[CGI.unescape(baggage_key)] = CGI.unescape(val)
55
+ mutable = false
56
+ end
57
+
58
+ new(items, mutable: mutable)
59
+ end
60
+
61
+ # Make the Baggage immutable.
62
+ # @return [void]
63
+ def freeze!
64
+ @mutable = false
65
+ end
66
+
67
+ # A {https://develop.sentry.dev/sdk/performance/dynamic-sampling-context/#envelope-header Dynamic Sampling Context}
68
+ # hash to be used in the trace envelope header.
69
+ # @return [Hash]
70
+ def dynamic_sampling_context
71
+ @items.select { |k, _v| DSC_KEYS.include?(k) }
72
+ end
73
+
74
+ # Serialize the Baggage object back to a string.
75
+ # @return [String]
76
+ def serialize
77
+ items = @items.map { |k, v| "#{SENTRY_PREFIX}#{CGI.escape(k)}=#{CGI.escape(v)}" }
78
+ items.join(',')
79
+ end
80
+ end
81
+ end
data/lib/sentry/client.rb CHANGED
@@ -105,16 +105,7 @@ module Sentry
105
105
  # @param transaction [Transaction] the transaction to be recorded.
106
106
  # @return [TransactionEvent]
107
107
  def event_from_transaction(transaction)
108
- TransactionEvent.new(configuration: configuration).tap do |event|
109
- event.transaction = transaction.name
110
- event.contexts.merge!(trace: transaction.get_trace_context)
111
- event.timestamp = transaction.timestamp
112
- event.start_timestamp = transaction.start_timestamp
113
- event.tags = transaction.tags
114
-
115
- finished_spans = transaction.span_recorder.spans.select { |span| span.timestamp && span != transaction }
116
- event.spans = finished_spans.map(&:to_hash)
117
- end
108
+ TransactionEvent.new(configuration: configuration, transaction: transaction)
118
109
  end
119
110
 
120
111
  # @!macro send_event
@@ -156,6 +147,22 @@ module Sentry
156
147
  trace
157
148
  end
158
149
 
150
+ # Generates a W3C Baggage header for distribted tracing from the given Span.
151
+ # Returns `nil` if `config.propagate_traces` is `false`.
152
+ # @param span [Span] the span to generate trace from.
153
+ # @return [String, nil]
154
+ def generate_baggage(span)
155
+ return unless configuration.propagate_traces
156
+
157
+ baggage = span.to_baggage
158
+
159
+ if baggage && !baggage.empty?
160
+ log_debug("[Tracing] Adding #{BAGGAGE_HEADER_NAME} header to outgoing request: #{baggage}")
161
+ end
162
+
163
+ baggage
164
+ end
165
+
159
166
  private
160
167
 
161
168
  def dispatch_background_event(event, hint)
data/lib/sentry/event.rb CHANGED
@@ -18,7 +18,7 @@ module Sentry
18
18
  event_id level timestamp
19
19
  release environment server_name modules
20
20
  message user tags contexts extra
21
- fingerprint breadcrumbs transaction
21
+ fingerprint breadcrumbs transaction transaction_info
22
22
  platform sdk type
23
23
  )
24
24
 
@@ -123,13 +123,15 @@ module Sentry
123
123
  !(key.start_with?('HTTP_') || CONTENT_HEADERS.include?(key))
124
124
  end
125
125
 
126
- # Rack adds in an incorrect HTTP_VERSION key, which causes downstream
126
+ # In versions < 3, Rack adds in an incorrect HTTP_VERSION key, which causes downstream
127
127
  # to think this is a Version header. Instead, this is mapped to
128
128
  # env['SERVER_PROTOCOL']. But we don't want to ignore a valid header
129
129
  # if the request has legitimately sent a Version header themselves.
130
130
  # See: https://github.com/rack/rack/blob/028438f/lib/rack/handler/cgi.rb#L29
131
- # NOTE: This will be removed in version 3.0+
132
131
  def is_server_protocol?(key, value, protocol_version)
132
+ rack_version = Gem::Version.new(::Rack.release)
133
+ return false if rack_version >= Gem::Version.new("3.0")
134
+
133
135
  key == 'HTTP_VERSION' && value == protocol_version
134
136
  end
135
137
 
@@ -42,8 +42,13 @@ module Sentry
42
42
  def set_sentry_trace_header(req, sentry_span)
43
43
  return unless sentry_span
44
44
 
45
- trace = Sentry.get_current_client.generate_sentry_trace(sentry_span)
45
+ client = Sentry.get_current_client
46
+
47
+ trace = client.generate_sentry_trace(sentry_span)
46
48
  req[SENTRY_TRACE_HEADER_NAME] = trace if trace
49
+
50
+ baggage = client.generate_baggage(sentry_span)
51
+ req[BAGGAGE_HEADER_NAME] = baggage if baggage && !baggage.empty?
47
52
  end
48
53
 
49
54
  def record_sentry_breadcrumb(req, res)
@@ -18,7 +18,7 @@ module Sentry
18
18
  Sentry.with_scope do |scope|
19
19
  Sentry.with_session_tracking do
20
20
  scope.clear_breadcrumbs
21
- scope.set_transaction_name(env["PATH_INFO"]) if env["PATH_INFO"]
21
+ scope.set_transaction_name(env["PATH_INFO"], source: :url) if env["PATH_INFO"]
22
22
  scope.set_rack_env(env)
23
23
 
24
24
  transaction = start_transaction(env, scope)
@@ -63,8 +63,10 @@ module Sentry
63
63
 
64
64
  def start_transaction(env, scope)
65
65
  sentry_trace = env["HTTP_SENTRY_TRACE"]
66
- options = { name: scope.transaction_name, op: transaction_op }
67
- transaction = Sentry::Transaction.from_sentry_trace(sentry_trace, **options) if sentry_trace
66
+ baggage = env["HTTP_BAGGAGE"]
67
+
68
+ options = { name: scope.transaction_name, source: scope.transaction_source, op: transaction_op }
69
+ transaction = Sentry::Transaction.from_sentry_trace(sentry_trace, baggage: baggage, **options) if sentry_trace
68
70
  Sentry.start_transaction(transaction: transaction, custom_sampling_context: { env: env }, **options)
69
71
  end
70
72
 
data/lib/sentry/rake.rb CHANGED
@@ -10,7 +10,7 @@ module Sentry
10
10
  def display_error_message(ex)
11
11
  Sentry.capture_exception(ex) do |scope|
12
12
  task_name = top_level_tasks.join(' ')
13
- scope.set_transaction_name(task_name)
13
+ scope.set_transaction_name(task_name, source: :task)
14
14
  scope.set_tag("rake_task", task_name)
15
15
  end if Sentry.initialized? && !Sentry.configuration.skip_rake_integration
16
16
 
data/lib/sentry/scope.rb CHANGED
@@ -7,7 +7,21 @@ module Sentry
7
7
  class Scope
8
8
  include ArgumentCheckingHelper
9
9
 
10
- ATTRIBUTES = [:transaction_names, :contexts, :extra, :tags, :user, :level, :breadcrumbs, :fingerprint, :event_processors, :rack_env, :span, :session]
10
+ ATTRIBUTES = [
11
+ :transaction_names,
12
+ :transaction_sources,
13
+ :contexts,
14
+ :extra,
15
+ :tags,
16
+ :user,
17
+ :level,
18
+ :breadcrumbs,
19
+ :fingerprint,
20
+ :event_processors,
21
+ :rack_env,
22
+ :span,
23
+ :session
24
+ ]
11
25
 
12
26
  attr_reader(*ATTRIBUTES)
13
27
 
@@ -33,6 +47,7 @@ module Sentry
33
47
  event.extra = extra.merge(event.extra)
34
48
  event.contexts = contexts.merge(event.contexts)
35
49
  event.transaction = transaction_name if transaction_name
50
+ event.transaction_info = { source: transaction_source } if transaction_source
36
51
 
37
52
  if span
38
53
  event.contexts[:trace] = span.get_trace_context
@@ -73,7 +88,8 @@ module Sentry
73
88
  copy.extra = extra.deep_dup
74
89
  copy.tags = tags.deep_dup
75
90
  copy.user = user.deep_dup
76
- copy.transaction_names = transaction_names.deep_dup
91
+ copy.transaction_names = transaction_names.dup
92
+ copy.transaction_sources = transaction_sources.dup
77
93
  copy.fingerprint = fingerprint.deep_dup
78
94
  copy.span = span.deep_dup
79
95
  copy.session = session.deep_dup
@@ -90,6 +106,7 @@ module Sentry
90
106
  self.tags = scope.tags
91
107
  self.user = scope.user
92
108
  self.transaction_names = scope.transaction_names
109
+ self.transaction_sources = scope.transaction_sources
93
110
  self.fingerprint = scope.fingerprint
94
111
  self.span = scope.span
95
112
  end
@@ -195,8 +212,9 @@ module Sentry
195
212
  # The "transaction" here does not refer to `Transaction` objects.
196
213
  # @param transaction_name [String]
197
214
  # @return [void]
198
- def set_transaction_name(transaction_name)
215
+ def set_transaction_name(transaction_name, source: :custom)
199
216
  @transaction_names << transaction_name
217
+ @transaction_sources << source
200
218
  end
201
219
 
202
220
  # Sets the currently active session on the scope.
@@ -213,6 +231,13 @@ module Sentry
213
231
  @transaction_names.last
214
232
  end
215
233
 
234
+ # Returns current transaction source.
235
+ # The "transaction" here does not refer to `Transaction` objects.
236
+ # @return [String, nil]
237
+ def transaction_source
238
+ @transaction_sources.last
239
+ end
240
+
216
241
  # Returns the associated Transaction object.
217
242
  # @return [Transaction, nil]
218
243
  def get_transaction
@@ -256,6 +281,7 @@ module Sentry
256
281
  @level = :error
257
282
  @fingerprint = []
258
283
  @transaction_names = []
284
+ @transaction_sources = []
259
285
  @event_processors = []
260
286
  @rack_env = {}
261
287
  @span = nil
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Sentry
4
4
  class Session
5
- attr_reader :started, :status
5
+ attr_reader :started, :status, :aggregation_key
6
6
 
7
7
  # TODO-neel add :crashed after adding handled mechanism
8
8
  STATUSES = %i(ok errored exited)
@@ -11,6 +11,10 @@ module Sentry
11
11
  def initialize
12
12
  @started = Sentry.utc_now
13
13
  @status = :ok
14
+
15
+ # truncate seconds from the timestamp since we only care about
16
+ # minute level granularity for aggregation
17
+ @aggregation_key = Time.utc(@started.year, @started.month, @started.day, @started.hour, @started.min)
14
18
  end
15
19
 
16
20
  # TODO-neel add :crashed after adding handled mechanism
@@ -22,12 +26,6 @@ module Sentry
22
26
  @status = :exited if @status == :ok
23
27
  end
24
28
 
25
- # truncate seconds from the timestamp since we only care about
26
- # minute level granularity for aggregation
27
- def aggregation_key
28
- Time.utc(started.year, started.month, started.day, started.hour, started.min)
29
- end
30
-
31
29
  def deep_dup
32
30
  dup
33
31
  end
data/lib/sentry/span.rb CHANGED
@@ -104,6 +104,13 @@ module Sentry
104
104
  "#{@trace_id}-#{@span_id}-#{sampled_flag}"
105
105
  end
106
106
 
107
+ # Generates a W3C Baggage header string for distributed tracing
108
+ # from the incoming baggage stored on the transation.
109
+ # @return [String, nil]
110
+ def to_baggage
111
+ transaction&.get_baggage&.serialize
112
+ end
113
+
107
114
  # @return [Hash]
108
115
  def to_hash
109
116
  {
@@ -31,6 +31,7 @@ module Sentry
31
31
 
32
32
  test_client = Sentry::Client.new(copied_config)
33
33
  Sentry.get_current_hub.bind_client(test_client)
34
+ Sentry.get_current_scope.clear
34
35
  end
35
36
 
36
37
  # Clears all stored events and envelopes.
@@ -41,6 +42,7 @@ module Sentry
41
42
 
42
43
  sentry_transport.events = []
43
44
  sentry_transport.envelopes = []
45
+ Sentry.get_current_scope.clear
44
46
  end
45
47
 
46
48
  # @return [Transport]
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "sentry/baggage"
4
+
3
5
  module Sentry
4
6
  class Transaction < Span
5
7
  SENTRY_TRACE_REGEXP = Regexp.new(
@@ -12,16 +14,29 @@ module Sentry
12
14
  UNLABELD_NAME = "<unlabeled transaction>".freeze
13
15
  MESSAGE_PREFIX = "[Tracing]"
14
16
 
17
+ # https://develop.sentry.dev/sdk/event-payloads/transaction/#transaction-annotations
18
+ SOURCES = %i(custom url route view component task)
19
+
15
20
  include LoggingHelper
16
21
 
17
22
  # The name of the transaction.
18
23
  # @return [String]
19
24
  attr_reader :name
20
25
 
26
+ # The source of the transaction name.
27
+ # @return [Symbol]
28
+ attr_reader :source
29
+
21
30
  # The sampling decision of the parent transaction, which will be considered when making the current transaction's sampling decision.
22
31
  # @return [String]
23
32
  attr_reader :parent_sampled
24
33
 
34
+ # The parsed incoming W3C baggage header.
35
+ # This is only for accessing the current baggage variable.
36
+ # Please use the #get_baggage method for interfacing outside this class.
37
+ # @return [Baggage, nil]
38
+ attr_reader :baggage
39
+
25
40
  # @deprecated Use Sentry.get_current_hub instead.
26
41
  attr_reader :hub
27
42
 
@@ -31,18 +46,35 @@ module Sentry
31
46
  # @deprecated Use Sentry.logger instead.
32
47
  attr_reader :logger
33
48
 
34
- def initialize(name: nil, parent_sampled: nil, hub:, **options)
49
+ # The effective sample rate at which this transaction was sampled.
50
+ # @return [Float, nil]
51
+ attr_reader :effective_sample_rate
52
+
53
+ def initialize(
54
+ hub:,
55
+ name: nil,
56
+ source: :custom,
57
+ parent_sampled: nil,
58
+ baggage: nil,
59
+ **options
60
+ )
35
61
  super(**options)
36
62
 
37
63
  @name = name
64
+ @source = SOURCES.include?(source) ? source.to_sym : :custom
38
65
  @parent_sampled = parent_sampled
39
66
  @transaction = self
40
67
  @hub = hub
68
+ @baggage = baggage
41
69
  @configuration = hub.configuration # to be removed
42
70
  @tracing_enabled = hub.configuration.tracing_enabled?
43
71
  @traces_sampler = hub.configuration.traces_sampler
44
72
  @traces_sample_rate = hub.configuration.traces_sample_rate
45
73
  @logger = hub.configuration.logger
74
+ @release = hub.configuration.release
75
+ @environment = hub.configuration.environment
76
+ @dsn = hub.configuration.dsn
77
+ @effective_sample_rate = nil
46
78
  init_span_recorder
47
79
  end
48
80
 
@@ -52,10 +84,11 @@ module Sentry
52
84
  #
53
85
  # The child transaction will also store the parent's sampling decision in its `parent_sampled` attribute.
54
86
  # @param sentry_trace [String] the trace string from the previous transaction.
87
+ # @param baggage [String, nil] the incoming baggage header string.
55
88
  # @param hub [Hub] the hub that'll be responsible for sending this transaction when it's finished.
56
89
  # @param options [Hash] the options you want to use to initialize a Transaction instance.
57
90
  # @return [Transaction, nil]
58
- def self.from_sentry_trace(sentry_trace, hub: Sentry.get_current_hub, **options)
91
+ def self.from_sentry_trace(sentry_trace, baggage: nil, hub: Sentry.get_current_hub, **options)
59
92
  return unless hub.configuration.tracing_enabled?
60
93
  return unless sentry_trace
61
94
 
@@ -70,13 +103,38 @@ module Sentry
70
103
  sampled_flag != "0"
71
104
  end
72
105
 
73
- new(trace_id: trace_id, parent_span_id: parent_span_id, parent_sampled: parent_sampled, hub: hub, **options)
106
+ baggage = if baggage && !baggage.empty?
107
+ Baggage.from_incoming_header(baggage)
108
+ else
109
+ # If there's an incoming sentry-trace but no incoming baggage header,
110
+ # for instance in traces coming from older SDKs,
111
+ # baggage will be empty and frozen and won't be populated as head SDK.
112
+ Baggage.new({})
113
+ end
114
+
115
+ baggage.freeze!
116
+
117
+ new(
118
+ trace_id: trace_id,
119
+ parent_span_id: parent_span_id,
120
+ parent_sampled: parent_sampled,
121
+ hub: hub,
122
+ baggage: baggage,
123
+ **options
124
+ )
74
125
  end
75
126
 
76
127
  # @return [Hash]
77
128
  def to_hash
78
129
  hash = super
79
- hash.merge!(name: @name, sampled: @sampled, parent_sampled: @parent_sampled)
130
+
131
+ hash.merge!(
132
+ name: @name,
133
+ source: @source,
134
+ sampled: @sampled,
135
+ parent_sampled: @parent_sampled
136
+ )
137
+
80
138
  hash
81
139
  end
82
140
 
@@ -103,7 +161,10 @@ module Sentry
103
161
  return
104
162
  end
105
163
 
106
- return unless @sampled.nil?
164
+ unless @sampled.nil?
165
+ @effective_sample_rate = @sampled ? 1.0 : 0.0
166
+ return
167
+ end
107
168
 
108
169
  sample_rate =
109
170
  if @traces_sampler.is_a?(Proc)
@@ -116,7 +177,11 @@ module Sentry
116
177
 
117
178
  transaction_description = generate_transaction_description
118
179
 
119
- unless [true, false].include?(sample_rate) || (sample_rate.is_a?(Numeric) && sample_rate >= 0.0 && sample_rate <= 1.0)
180
+ if [true, false].include?(sample_rate)
181
+ @effective_sample_rate = sample_rate ? 1.0 : 0.0
182
+ elsif sample_rate.is_a?(Numeric) && sample_rate >= 0.0 && sample_rate <= 1.0
183
+ @effective_sample_rate = sample_rate.to_f
184
+ else
120
185
  @sampled = false
121
186
  log_warn("#{MESSAGE_PREFIX} Discarding #{transaction_description} because of invalid sample_rate: #{sample_rate}")
122
187
  return
@@ -172,6 +237,14 @@ module Sentry
172
237
  end
173
238
  end
174
239
 
240
+ # Get the existing frozen incoming baggage
241
+ # or populate one with sentry- items as the head SDK.
242
+ # @return [Baggage]
243
+ def get_baggage
244
+ populate_head_baggage if @baggage.nil? || @baggage.mutable
245
+ @baggage
246
+ end
247
+
175
248
  protected
176
249
 
177
250
  def init_span_recorder(limit = 1000)
@@ -188,6 +261,29 @@ module Sentry
188
261
  result
189
262
  end
190
263
 
264
+ def populate_head_baggage
265
+ items = {
266
+ "trace_id" => trace_id,
267
+ "sample_rate" => effective_sample_rate&.to_s,
268
+ "environment" => @environment,
269
+ "release" => @release,
270
+ "public_key" => @dsn&.public_key
271
+ }
272
+
273
+ items["transaction"] = name unless source_low_quality?
274
+
275
+ user = @hub.current_scope&.user
276
+ items["user_segment"] = user["segment"] if user && user["segment"]
277
+
278
+ items.compact!
279
+ @baggage = Baggage.new(items, mutable: false)
280
+ end
281
+
282
+ # These are high cardinality and thus bad
283
+ def source_low_quality?
284
+ source == :url
285
+ end
286
+
191
287
  class SpanRecorder
192
288
  attr_reader :max_length, :spans
193
289
 
@@ -8,9 +8,27 @@ module Sentry
8
8
  # @return [<Array[Span]>]
9
9
  attr_accessor :spans
10
10
 
11
+ # @return [Hash, nil]
12
+ attr_accessor :dynamic_sampling_context
13
+
11
14
  # @return [Float, nil]
12
15
  attr_reader :start_timestamp
13
16
 
17
+ def initialize(transaction:, **options)
18
+ super(**options)
19
+
20
+ self.transaction = transaction.name
21
+ self.transaction_info = { source: transaction.source }
22
+ self.contexts.merge!(trace: transaction.get_trace_context)
23
+ self.timestamp = transaction.timestamp
24
+ self.start_timestamp = transaction.start_timestamp
25
+ self.tags = transaction.tags
26
+ self.dynamic_sampling_context = transaction.get_baggage.dynamic_sampling_context
27
+
28
+ finished_spans = transaction.span_recorder.spans.select { |span| span.timestamp && span != transaction }
29
+ self.spans = finished_spans.map(&:to_hash)
30
+ end
31
+
14
32
  # Sets the event's start_timestamp.
15
33
  # @param time [Time, Float]
16
34
  # @return [void]
@@ -136,14 +136,18 @@ module Sentry
136
136
  event_id = event_payload[:event_id] || event_payload["event_id"]
137
137
  item_type = event_payload[:type] || event_payload["type"]
138
138
 
139
- envelope = Envelope.new(
140
- {
141
- event_id: event_id,
142
- dsn: @dsn.to_s,
143
- sdk: Sentry.sdk_meta,
144
- sent_at: Sentry.utc_now.iso8601
145
- }
146
- )
139
+ envelope_headers = {
140
+ event_id: event_id,
141
+ dsn: @dsn.to_s,
142
+ sdk: Sentry.sdk_meta,
143
+ sent_at: Sentry.utc_now.iso8601
144
+ }
145
+
146
+ if event.is_a?(TransactionEvent) && event.dynamic_sampling_context
147
+ envelope_headers[:trace] = event.dynamic_sampling_context
148
+ end
149
+
150
+ envelope = Envelope.new(envelope_headers)
147
151
 
148
152
  envelope.add_item(
149
153
  { type: item_type, content_type: 'application/json' },
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sentry
4
- VERSION = "5.4.2"
4
+ VERSION = "5.5.0"
5
5
  end
data/lib/sentry-ruby.rb CHANGED
@@ -39,6 +39,8 @@ module Sentry
39
39
 
40
40
  SENTRY_TRACE_HEADER_NAME = "sentry-trace".freeze
41
41
 
42
+ BAGGAGE_HEADER_NAME = "baggage".freeze
43
+
42
44
  THREAD_LOCAL = :sentry_hub
43
45
 
44
46
  class << self
@@ -348,7 +350,7 @@ module Sentry
348
350
  # @yieldparam scope [Scope]
349
351
  # @return [void]
350
352
  def with_scope(&block)
351
- return unless initialized?
353
+ return yield unless initialized?
352
354
  get_current_hub.with_scope(&block)
353
355
  end
354
356
 
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.4.2
4
+ version: 5.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sentry Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-17 00:00:00.000000000 Z
11
+ date: 2022-10-03 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.4.2
19
+ version: 5.5.0
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.4.2
26
+ version: 5.5.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: concurrent-ruby
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -61,6 +61,7 @@ files:
61
61
  - lib/sentry-ruby.rb
62
62
  - lib/sentry/background_worker.rb
63
63
  - lib/sentry/backtrace.rb
64
+ - lib/sentry/baggage.rb
64
65
  - lib/sentry/breadcrumb.rb
65
66
  - lib/sentry/breadcrumb/sentry_logger.rb
66
67
  - lib/sentry/breadcrumb_buffer.rb