sentry-ruby 5.4.2 → 5.9.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/.rspec +0 -1
- data/Gemfile +12 -5
- data/README.md +3 -0
- data/Rakefile +8 -1
- data/lib/sentry/backtrace.rb +1 -1
- data/lib/sentry/baggage.rb +70 -0
- data/lib/sentry/client.rb +31 -11
- data/lib/sentry/configuration.rb +96 -20
- data/lib/sentry/envelope.rb +1 -4
- data/lib/sentry/event.rb +1 -1
- data/lib/sentry/hub.rb +26 -2
- data/lib/sentry/interfaces/request.rb +6 -16
- data/lib/sentry/interfaces/single_exception.rb +9 -1
- data/lib/sentry/net/http.rb +20 -35
- data/lib/sentry/profiler.rb +222 -0
- data/lib/sentry/puma.rb +25 -0
- data/lib/sentry/rack/capture_exceptions.rb +6 -4
- data/lib/sentry/rake.rb +1 -1
- data/lib/sentry/redis.rb +35 -23
- data/lib/sentry/scope.rb +55 -6
- data/lib/sentry/session.rb +5 -7
- data/lib/sentry/span.rb +19 -9
- data/lib/sentry/test_helper.rb +3 -1
- data/lib/sentry/transaction.rb +173 -19
- data/lib/sentry/transaction_event.rb +54 -0
- data/lib/sentry/transport.rb +19 -8
- data/lib/sentry/utils/encoding_helper.rb +22 -0
- data/lib/sentry/version.rb +1 -1
- data/lib/sentry-ruby.rb +38 -21
- metadata +6 -2
data/lib/sentry/transaction.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "sentry/baggage"
|
4
|
+
require "sentry/profiler"
|
5
|
+
|
3
6
|
module Sentry
|
4
7
|
class Transaction < Span
|
5
8
|
SENTRY_TRACE_REGEXP = Regexp.new(
|
@@ -12,16 +15,33 @@ module Sentry
|
|
12
15
|
UNLABELD_NAME = "<unlabeled transaction>".freeze
|
13
16
|
MESSAGE_PREFIX = "[Tracing]"
|
14
17
|
|
18
|
+
# https://develop.sentry.dev/sdk/event-payloads/transaction/#transaction-annotations
|
19
|
+
SOURCES = %i(custom url route view component task)
|
20
|
+
|
15
21
|
include LoggingHelper
|
16
22
|
|
17
23
|
# The name of the transaction.
|
18
24
|
# @return [String]
|
19
25
|
attr_reader :name
|
20
26
|
|
27
|
+
# The source of the transaction name.
|
28
|
+
# @return [Symbol]
|
29
|
+
attr_reader :source
|
30
|
+
|
21
31
|
# The sampling decision of the parent transaction, which will be considered when making the current transaction's sampling decision.
|
22
32
|
# @return [String]
|
23
33
|
attr_reader :parent_sampled
|
24
34
|
|
35
|
+
# The parsed incoming W3C baggage header.
|
36
|
+
# This is only for accessing the current baggage variable.
|
37
|
+
# Please use the #get_baggage method for interfacing outside this class.
|
38
|
+
# @return [Baggage, nil]
|
39
|
+
attr_reader :baggage
|
40
|
+
|
41
|
+
# The measurements added to the transaction.
|
42
|
+
# @return [Hash]
|
43
|
+
attr_reader :measurements
|
44
|
+
|
25
45
|
# @deprecated Use Sentry.get_current_hub instead.
|
26
46
|
attr_reader :hub
|
27
47
|
|
@@ -31,18 +51,44 @@ module Sentry
|
|
31
51
|
# @deprecated Use Sentry.logger instead.
|
32
52
|
attr_reader :logger
|
33
53
|
|
34
|
-
|
35
|
-
|
54
|
+
# The effective sample rate at which this transaction was sampled.
|
55
|
+
# @return [Float, nil]
|
56
|
+
attr_reader :effective_sample_rate
|
36
57
|
|
37
|
-
|
58
|
+
# Additional contexts stored directly on the transaction object.
|
59
|
+
# @return [Hash]
|
60
|
+
attr_reader :contexts
|
61
|
+
|
62
|
+
# The Profiler instance for this transaction.
|
63
|
+
# @return [Profiler]
|
64
|
+
attr_reader :profiler
|
65
|
+
|
66
|
+
def initialize(
|
67
|
+
hub:,
|
68
|
+
name: nil,
|
69
|
+
source: :custom,
|
70
|
+
parent_sampled: nil,
|
71
|
+
baggage: nil,
|
72
|
+
**options
|
73
|
+
)
|
74
|
+
super(transaction: self, **options)
|
75
|
+
|
76
|
+
set_name(name, source: source)
|
38
77
|
@parent_sampled = parent_sampled
|
39
|
-
@transaction = self
|
40
78
|
@hub = hub
|
79
|
+
@baggage = baggage
|
41
80
|
@configuration = hub.configuration # to be removed
|
42
81
|
@tracing_enabled = hub.configuration.tracing_enabled?
|
43
82
|
@traces_sampler = hub.configuration.traces_sampler
|
44
83
|
@traces_sample_rate = hub.configuration.traces_sample_rate
|
45
84
|
@logger = hub.configuration.logger
|
85
|
+
@release = hub.configuration.release
|
86
|
+
@environment = hub.configuration.environment
|
87
|
+
@dsn = hub.configuration.dsn
|
88
|
+
@effective_sample_rate = nil
|
89
|
+
@contexts = {}
|
90
|
+
@measurements = {}
|
91
|
+
@profiler = Profiler.new(@configuration)
|
46
92
|
init_span_recorder
|
47
93
|
end
|
48
94
|
|
@@ -52,31 +98,65 @@ module Sentry
|
|
52
98
|
#
|
53
99
|
# The child transaction will also store the parent's sampling decision in its `parent_sampled` attribute.
|
54
100
|
# @param sentry_trace [String] the trace string from the previous transaction.
|
101
|
+
# @param baggage [String, nil] the incoming baggage header string.
|
55
102
|
# @param hub [Hub] the hub that'll be responsible for sending this transaction when it's finished.
|
56
103
|
# @param options [Hash] the options you want to use to initialize a Transaction instance.
|
57
104
|
# @return [Transaction, nil]
|
58
|
-
def self.from_sentry_trace(sentry_trace, hub: Sentry.get_current_hub, **options)
|
105
|
+
def self.from_sentry_trace(sentry_trace, baggage: nil, hub: Sentry.get_current_hub, **options)
|
59
106
|
return unless hub.configuration.tracing_enabled?
|
60
107
|
return unless sentry_trace
|
61
108
|
|
109
|
+
sentry_trace_data = extract_sentry_trace(sentry_trace)
|
110
|
+
return unless sentry_trace_data
|
111
|
+
|
112
|
+
trace_id, parent_span_id, parent_sampled = sentry_trace_data
|
113
|
+
|
114
|
+
baggage = 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
|
122
|
+
|
123
|
+
baggage.freeze!
|
124
|
+
|
125
|
+
new(
|
126
|
+
trace_id: trace_id,
|
127
|
+
parent_span_id: parent_span_id,
|
128
|
+
parent_sampled: parent_sampled,
|
129
|
+
hub: hub,
|
130
|
+
baggage: baggage,
|
131
|
+
**options
|
132
|
+
)
|
133
|
+
end
|
134
|
+
|
135
|
+
# Extract the trace_id, parent_span_id and parent_sampled values from a sentry-trace header.
|
136
|
+
#
|
137
|
+
# @param sentry_trace [String] the sentry-trace header value from the previous transaction.
|
138
|
+
# @return [Array, nil]
|
139
|
+
def self.extract_sentry_trace(sentry_trace)
|
62
140
|
match = SENTRY_TRACE_REGEXP.match(sentry_trace)
|
63
|
-
return if match.nil?
|
64
|
-
trace_id, parent_span_id, sampled_flag = match[1..3]
|
141
|
+
return nil if match.nil?
|
65
142
|
|
66
|
-
|
67
|
-
|
68
|
-
nil
|
69
|
-
else
|
70
|
-
sampled_flag != "0"
|
71
|
-
end
|
143
|
+
trace_id, parent_span_id, sampled_flag = match[1..3]
|
144
|
+
parent_sampled = sampled_flag.nil? ? nil : sampled_flag != "0"
|
72
145
|
|
73
|
-
|
146
|
+
[trace_id, parent_span_id, parent_sampled]
|
74
147
|
end
|
75
148
|
|
76
149
|
# @return [Hash]
|
77
150
|
def to_hash
|
78
151
|
hash = super
|
79
|
-
|
152
|
+
|
153
|
+
hash.merge!(
|
154
|
+
name: @name,
|
155
|
+
source: @source,
|
156
|
+
sampled: @sampled,
|
157
|
+
parent_sampled: @parent_sampled
|
158
|
+
)
|
159
|
+
|
80
160
|
hash
|
81
161
|
end
|
82
162
|
|
@@ -94,6 +174,15 @@ module Sentry
|
|
94
174
|
copy
|
95
175
|
end
|
96
176
|
|
177
|
+
# Sets a custom measurement on the transaction.
|
178
|
+
# @param name [String] name of the measurement
|
179
|
+
# @param value [Float] value of the measurement
|
180
|
+
# @param unit [String] unit of the measurement
|
181
|
+
# @return [void]
|
182
|
+
def set_measurement(name, value, unit = "")
|
183
|
+
@measurements[name] = { value: value, unit: unit }
|
184
|
+
end
|
185
|
+
|
97
186
|
# Sets initial sampling decision of the transaction.
|
98
187
|
# @param sampling_context [Hash] a context Hash that'll be passed to `traces_sampler` (if provided).
|
99
188
|
# @return [void]
|
@@ -103,7 +192,10 @@ module Sentry
|
|
103
192
|
return
|
104
193
|
end
|
105
194
|
|
106
|
-
|
195
|
+
unless @sampled.nil?
|
196
|
+
@effective_sample_rate = @sampled ? 1.0 : 0.0
|
197
|
+
return
|
198
|
+
end
|
107
199
|
|
108
200
|
sample_rate =
|
109
201
|
if @traces_sampler.is_a?(Proc)
|
@@ -116,7 +208,11 @@ module Sentry
|
|
116
208
|
|
117
209
|
transaction_description = generate_transaction_description
|
118
210
|
|
119
|
-
|
211
|
+
if [true, false].include?(sample_rate)
|
212
|
+
@effective_sample_rate = sample_rate ? 1.0 : 0.0
|
213
|
+
elsif sample_rate.is_a?(Numeric) && sample_rate >= 0.0 && sample_rate <= 1.0
|
214
|
+
@effective_sample_rate = sample_rate.to_f
|
215
|
+
else
|
120
216
|
@sampled = false
|
121
217
|
log_warn("#{MESSAGE_PREFIX} Discarding #{transaction_description} because of invalid sample_rate: #{sample_rate}")
|
122
218
|
return
|
@@ -146,7 +242,7 @@ module Sentry
|
|
146
242
|
# Finishes the transaction's recording and send it to Sentry.
|
147
243
|
# @param hub [Hub] the hub that'll send this transaction. (Deprecated)
|
148
244
|
# @return [TransactionEvent]
|
149
|
-
def finish(hub: nil)
|
245
|
+
def finish(hub: nil, end_timestamp: nil)
|
150
246
|
if hub
|
151
247
|
log_warn(
|
152
248
|
<<~MSG
|
@@ -158,12 +254,14 @@ module Sentry
|
|
158
254
|
|
159
255
|
hub ||= @hub
|
160
256
|
|
161
|
-
super()
|
257
|
+
super(end_timestamp: end_timestamp)
|
162
258
|
|
163
259
|
if @name.nil?
|
164
260
|
@name = UNLABELD_NAME
|
165
261
|
end
|
166
262
|
|
263
|
+
@profiler.stop
|
264
|
+
|
167
265
|
if @sampled
|
168
266
|
event = hub.current_client.event_from_transaction(self)
|
169
267
|
hub.capture_event(event)
|
@@ -172,6 +270,39 @@ module Sentry
|
|
172
270
|
end
|
173
271
|
end
|
174
272
|
|
273
|
+
# Get the existing frozen incoming baggage
|
274
|
+
# or populate one with sentry- items as the head SDK.
|
275
|
+
# @return [Baggage]
|
276
|
+
def get_baggage
|
277
|
+
populate_head_baggage if @baggage.nil? || @baggage.mutable
|
278
|
+
@baggage
|
279
|
+
end
|
280
|
+
|
281
|
+
# Set the transaction name directly.
|
282
|
+
# Considered internal api since it bypasses the usual scope logic.
|
283
|
+
# @param name [String]
|
284
|
+
# @param source [Symbol]
|
285
|
+
# @return [void]
|
286
|
+
def set_name(name, source: :custom)
|
287
|
+
@name = name
|
288
|
+
@source = SOURCES.include?(source) ? source.to_sym : :custom
|
289
|
+
end
|
290
|
+
|
291
|
+
# Set contexts directly on the transaction.
|
292
|
+
# @param key [String, Symbol]
|
293
|
+
# @param value [Object]
|
294
|
+
# @return [void]
|
295
|
+
def set_context(key, value)
|
296
|
+
@contexts[key] = value
|
297
|
+
end
|
298
|
+
|
299
|
+
# Start the profiler.
|
300
|
+
# @return [void]
|
301
|
+
def start_profiler!
|
302
|
+
profiler.set_initial_sample_decision(sampled)
|
303
|
+
profiler.start
|
304
|
+
end
|
305
|
+
|
175
306
|
protected
|
176
307
|
|
177
308
|
def init_span_recorder(limit = 1000)
|
@@ -188,6 +319,29 @@ module Sentry
|
|
188
319
|
result
|
189
320
|
end
|
190
321
|
|
322
|
+
def populate_head_baggage
|
323
|
+
items = {
|
324
|
+
"trace_id" => trace_id,
|
325
|
+
"sample_rate" => effective_sample_rate&.to_s,
|
326
|
+
"environment" => @environment,
|
327
|
+
"release" => @release,
|
328
|
+
"public_key" => @dsn&.public_key
|
329
|
+
}
|
330
|
+
|
331
|
+
items["transaction"] = name unless source_low_quality?
|
332
|
+
|
333
|
+
user = @hub.current_scope&.user
|
334
|
+
items["user_segment"] = user["segment"] if user && user["segment"]
|
335
|
+
|
336
|
+
items.compact!
|
337
|
+
@baggage = Baggage.new(items, mutable: false)
|
338
|
+
end
|
339
|
+
|
340
|
+
# These are high cardinality and thus bad
|
341
|
+
def source_low_quality?
|
342
|
+
source == :url
|
343
|
+
end
|
344
|
+
|
191
345
|
class SpanRecorder
|
192
346
|
attr_reader :max_length, :spans
|
193
347
|
|
@@ -8,9 +8,37 @@ 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
|
+
|
14
|
+
# @return [Hash]
|
15
|
+
attr_accessor :measurements
|
16
|
+
|
11
17
|
# @return [Float, nil]
|
12
18
|
attr_reader :start_timestamp
|
13
19
|
|
20
|
+
# @return [Hash, nil]
|
21
|
+
attr_accessor :profile
|
22
|
+
|
23
|
+
def initialize(transaction:, **options)
|
24
|
+
super(**options)
|
25
|
+
|
26
|
+
self.transaction = transaction.name
|
27
|
+
self.transaction_info = { source: transaction.source }
|
28
|
+
self.contexts.merge!(transaction.contexts)
|
29
|
+
self.contexts.merge!(trace: transaction.get_trace_context)
|
30
|
+
self.timestamp = transaction.timestamp
|
31
|
+
self.start_timestamp = transaction.start_timestamp
|
32
|
+
self.tags = transaction.tags
|
33
|
+
self.dynamic_sampling_context = transaction.get_baggage.dynamic_sampling_context
|
34
|
+
self.measurements = transaction.measurements
|
35
|
+
|
36
|
+
finished_spans = transaction.span_recorder.spans.select { |span| span.timestamp && span != transaction }
|
37
|
+
self.spans = finished_spans.map(&:to_hash)
|
38
|
+
|
39
|
+
populate_profile(transaction)
|
40
|
+
end
|
41
|
+
|
14
42
|
# Sets the event's start_timestamp.
|
15
43
|
# @param time [Time, Float]
|
16
44
|
# @return [void]
|
@@ -23,7 +51,33 @@ module Sentry
|
|
23
51
|
data = super
|
24
52
|
data[:spans] = @spans.map(&:to_hash) if @spans
|
25
53
|
data[:start_timestamp] = @start_timestamp
|
54
|
+
data[:measurements] = @measurements
|
26
55
|
data
|
27
56
|
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def populate_profile(transaction)
|
61
|
+
profile_hash = transaction.profiler.to_hash
|
62
|
+
return if profile_hash.empty?
|
63
|
+
|
64
|
+
profile_hash.merge!(
|
65
|
+
environment: environment,
|
66
|
+
release: release,
|
67
|
+
timestamp: Time.at(start_timestamp).iso8601,
|
68
|
+
device: { architecture: Scope.os_context[:machine] },
|
69
|
+
os: { name: Scope.os_context[:name], version: Scope.os_context[:version] },
|
70
|
+
runtime: Scope.runtime_context,
|
71
|
+
transaction: {
|
72
|
+
id: event_id,
|
73
|
+
name: transaction.name,
|
74
|
+
trace_id: transaction.trace_id,
|
75
|
+
# TODO-neel-profiler stubbed for now, see thread_id note in profiler.rb
|
76
|
+
active_thead_id: '0'
|
77
|
+
}
|
78
|
+
)
|
79
|
+
|
80
|
+
self.profile = profile_hash
|
81
|
+
end
|
28
82
|
end
|
29
83
|
end
|
data/lib/sentry/transport.rb
CHANGED
@@ -136,20 +136,31 @@ 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
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
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' },
|
150
154
|
event_payload
|
151
155
|
)
|
152
156
|
|
157
|
+
if event.is_a?(TransactionEvent) && event.profile
|
158
|
+
envelope.add_item(
|
159
|
+
{ type: 'profile', content_type: 'application/json' },
|
160
|
+
event.profile
|
161
|
+
)
|
162
|
+
end
|
163
|
+
|
153
164
|
client_report_headers, client_report_payload = fetch_pending_client_report
|
154
165
|
envelope.add_item(client_report_headers, client_report_payload) if client_report_headers
|
155
166
|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sentry
|
4
|
+
module Utils
|
5
|
+
module EncodingHelper
|
6
|
+
def self.encode_to_utf_8(value)
|
7
|
+
if value.encoding != Encoding::UTF_8 && value.respond_to?(:force_encoding)
|
8
|
+
value = value.dup.force_encoding(Encoding::UTF_8)
|
9
|
+
end
|
10
|
+
|
11
|
+
value = value.scrub unless value.valid_encoding?
|
12
|
+
value
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.valid_utf_8?(value)
|
16
|
+
return true unless value.respond_to?(:force_encoding)
|
17
|
+
|
18
|
+
value.dup.force_encoding(Encoding::UTF_8).valid_encoding?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/sentry/version.rb
CHANGED
data/lib/sentry-ruby.rb
CHANGED
@@ -8,6 +8,7 @@ require "sentry/version"
|
|
8
8
|
require "sentry/exceptions"
|
9
9
|
require "sentry/core_ext/object/deep_dup"
|
10
10
|
require "sentry/utils/argument_checking_helper"
|
11
|
+
require "sentry/utils/encoding_helper"
|
11
12
|
require "sentry/utils/logging_helper"
|
12
13
|
require "sentry/configuration"
|
13
14
|
require "sentry/logger"
|
@@ -39,6 +40,8 @@ module Sentry
|
|
39
40
|
|
40
41
|
SENTRY_TRACE_HEADER_NAME = "sentry-trace".freeze
|
41
42
|
|
43
|
+
BAGGAGE_HEADER_NAME = "baggage".freeze
|
44
|
+
|
42
45
|
THREAD_LOCAL = :sentry_hub
|
43
46
|
|
44
47
|
class << self
|
@@ -70,8 +73,18 @@ module Sentry
|
|
70
73
|
##### Patch Registration #####
|
71
74
|
|
72
75
|
# @!visibility private
|
73
|
-
def register_patch(&block)
|
74
|
-
|
76
|
+
def register_patch(patch = nil, target = nil, &block)
|
77
|
+
if patch && block
|
78
|
+
raise ArgumentError.new("Please provide either a patch and its target OR a block, but not both")
|
79
|
+
end
|
80
|
+
|
81
|
+
if block
|
82
|
+
registered_patches << block
|
83
|
+
else
|
84
|
+
registered_patches << proc do
|
85
|
+
target.send(:prepend, patch) unless target.ancestors.include?(patch)
|
86
|
+
end
|
87
|
+
end
|
75
88
|
end
|
76
89
|
|
77
90
|
# @!visibility private
|
@@ -209,7 +222,7 @@ module Sentry
|
|
209
222
|
nil
|
210
223
|
end
|
211
224
|
|
212
|
-
if config.
|
225
|
+
if config.include_local_variables
|
213
226
|
exception_locals_tp.enable
|
214
227
|
end
|
215
228
|
|
@@ -231,7 +244,7 @@ module Sentry
|
|
231
244
|
@session_flusher = nil
|
232
245
|
end
|
233
246
|
|
234
|
-
if configuration&.
|
247
|
+
if configuration&.include_local_variables
|
235
248
|
exception_locals_tp.disable
|
236
249
|
end
|
237
250
|
|
@@ -348,7 +361,7 @@ module Sentry
|
|
348
361
|
# @yieldparam scope [Scope]
|
349
362
|
# @return [void]
|
350
363
|
def with_scope(&block)
|
351
|
-
return unless initialized?
|
364
|
+
return yield unless initialized?
|
352
365
|
get_current_hub.with_scope(&block)
|
353
366
|
end
|
354
367
|
|
@@ -439,22 +452,8 @@ module Sentry
|
|
439
452
|
# end
|
440
453
|
#
|
441
454
|
def with_child_span(**attributes, &block)
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
begin
|
446
|
-
current_span.with_child_span(**attributes) do |child_span|
|
447
|
-
get_current_scope.set_span(child_span)
|
448
|
-
result = yield(child_span)
|
449
|
-
end
|
450
|
-
ensure
|
451
|
-
get_current_scope.set_span(current_span)
|
452
|
-
end
|
453
|
-
|
454
|
-
result
|
455
|
-
else
|
456
|
-
yield(nil)
|
457
|
-
end
|
455
|
+
return yield(nil) unless Sentry.initialized?
|
456
|
+
get_current_hub.with_child_span(**attributes, &block)
|
458
457
|
end
|
459
458
|
|
460
459
|
# Returns the id of the lastly reported Sentry::Event.
|
@@ -473,6 +472,23 @@ module Sentry
|
|
473
472
|
!!exc.instance_variable_get(CAPTURED_SIGNATURE)
|
474
473
|
end
|
475
474
|
|
475
|
+
# Add a global event processor [Proc].
|
476
|
+
# These run before scope event processors.
|
477
|
+
#
|
478
|
+
# @yieldparam event [Event]
|
479
|
+
# @yieldparam hint [Hash, nil]
|
480
|
+
# @return [void]
|
481
|
+
#
|
482
|
+
# @example
|
483
|
+
# Sentry.add_global_event_processor do |event, hint|
|
484
|
+
# event.tags = { foo: 42 }
|
485
|
+
# event
|
486
|
+
# end
|
487
|
+
#
|
488
|
+
def add_global_event_processor(&block)
|
489
|
+
Scope.add_global_event_processor(&block)
|
490
|
+
end
|
491
|
+
|
476
492
|
##### Helpers #####
|
477
493
|
|
478
494
|
# @!visibility private
|
@@ -503,3 +519,4 @@ end
|
|
503
519
|
# patches
|
504
520
|
require "sentry/net/http"
|
505
521
|
require "sentry/redis"
|
522
|
+
require "sentry/puma"
|
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.9.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:
|
11
|
+
date: 2023-04-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -53,6 +53,7 @@ files:
|
|
53
53
|
- lib/sentry-ruby.rb
|
54
54
|
- lib/sentry/background_worker.rb
|
55
55
|
- lib/sentry/backtrace.rb
|
56
|
+
- lib/sentry/baggage.rb
|
56
57
|
- lib/sentry/breadcrumb.rb
|
57
58
|
- lib/sentry/breadcrumb/sentry_logger.rb
|
58
59
|
- lib/sentry/breadcrumb_buffer.rb
|
@@ -77,6 +78,8 @@ files:
|
|
77
78
|
- lib/sentry/linecache.rb
|
78
79
|
- lib/sentry/logger.rb
|
79
80
|
- lib/sentry/net/http.rb
|
81
|
+
- lib/sentry/profiler.rb
|
82
|
+
- lib/sentry/puma.rb
|
80
83
|
- lib/sentry/rack.rb
|
81
84
|
- lib/sentry/rack/capture_exceptions.rb
|
82
85
|
- lib/sentry/rake.rb
|
@@ -95,6 +98,7 @@ files:
|
|
95
98
|
- lib/sentry/transport/http_transport.rb
|
96
99
|
- lib/sentry/utils/argument_checking_helper.rb
|
97
100
|
- lib/sentry/utils/custom_inspection.rb
|
101
|
+
- lib/sentry/utils/encoding_helper.rb
|
98
102
|
- lib/sentry/utils/exception_cause_chain.rb
|
99
103
|
- lib/sentry/utils/logging_helper.rb
|
100
104
|
- lib/sentry/utils/real_ip.rb
|