sentry-ruby-core 4.8.0 → 5.2.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/.yardopts +2 -0
- data/Gemfile +3 -0
- data/README.md +2 -0
- data/lib/sentry/background_worker.rb +33 -3
- data/lib/sentry/backtrace.rb +1 -3
- data/lib/sentry/breadcrumb/sentry_logger.rb +2 -0
- data/lib/sentry/breadcrumb.rb +24 -3
- data/lib/sentry/breadcrumb_buffer.rb +16 -0
- data/lib/sentry/client.rb +38 -2
- data/lib/sentry/configuration.rb +94 -41
- data/lib/sentry/core_ext/object/deep_dup.rb +2 -0
- data/lib/sentry/core_ext/object/duplicable.rb +1 -0
- data/lib/sentry/dsn.rb +2 -0
- data/lib/sentry/envelope.rb +45 -0
- data/lib/sentry/event.rb +55 -18
- data/lib/sentry/exceptions.rb +2 -0
- data/lib/sentry/hub.rb +38 -2
- data/lib/sentry/integrable.rb +2 -0
- data/lib/sentry/interface.rb +3 -10
- data/lib/sentry/interfaces/exception.rb +14 -3
- data/lib/sentry/interfaces/request.rb +37 -20
- data/lib/sentry/interfaces/single_exception.rb +2 -0
- data/lib/sentry/interfaces/stacktrace.rb +6 -0
- data/lib/sentry/interfaces/stacktrace_builder.rb +39 -10
- data/lib/sentry/interfaces/threads.rb +12 -2
- data/lib/sentry/linecache.rb +3 -0
- data/lib/sentry/net/http.rb +54 -65
- data/lib/sentry/rack/capture_exceptions.rb +28 -24
- data/lib/sentry/rack.rb +2 -0
- data/lib/sentry/rake.rb +16 -6
- data/lib/sentry/redis.rb +90 -0
- data/lib/sentry/release_detector.rb +3 -0
- data/lib/sentry/scope.rb +85 -6
- data/lib/sentry/session.rb +35 -0
- data/lib/sentry/session_flusher.rb +79 -0
- data/lib/sentry/span.rb +84 -8
- data/lib/sentry/transaction.rb +48 -14
- data/lib/sentry/transaction_event.rb +8 -0
- data/lib/sentry/transport/configuration.rb +3 -2
- data/lib/sentry/transport/dummy_transport.rb +8 -1
- data/lib/sentry/transport/http_transport.rb +55 -42
- data/lib/sentry/transport.rb +79 -37
- data/lib/sentry/utils/argument_checking_helper.rb +2 -0
- data/lib/sentry/utils/custom_inspection.rb +2 -0
- data/lib/sentry/utils/exception_cause_chain.rb +2 -0
- data/lib/sentry/utils/logging_helper.rb +6 -4
- data/lib/sentry/utils/real_ip.rb +2 -0
- data/lib/sentry/utils/request_id.rb +2 -0
- data/lib/sentry/version.rb +3 -1
- data/lib/sentry-ruby.rb +212 -41
- data/sentry-ruby-core.gemspec +0 -1
- data/sentry-ruby.gemspec +0 -1
- metadata +7 -16
data/lib/sentry/transport.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "json"
|
2
4
|
require "base64"
|
5
|
+
require "sentry/envelope"
|
3
6
|
|
4
7
|
module Sentry
|
5
8
|
class Transport
|
@@ -20,7 +23,10 @@ module Sentry
|
|
20
23
|
|
21
24
|
include LoggingHelper
|
22
25
|
|
23
|
-
attr_reader :
|
26
|
+
attr_reader :rate_limits, :discarded_events, :last_client_report_sent
|
27
|
+
|
28
|
+
# @deprecated Use Sentry.logger to retrieve the current logger instead.
|
29
|
+
attr_reader :logger
|
24
30
|
|
25
31
|
def initialize(configuration)
|
26
32
|
@logger = configuration.logger
|
@@ -40,23 +46,54 @@ module Sentry
|
|
40
46
|
end
|
41
47
|
|
42
48
|
def send_event(event)
|
43
|
-
|
44
|
-
|
49
|
+
envelope = envelope_from_event(event)
|
50
|
+
send_envelope(envelope)
|
51
|
+
|
52
|
+
event
|
53
|
+
end
|
54
|
+
|
55
|
+
def send_envelope(envelope)
|
56
|
+
reject_rate_limited_items(envelope)
|
45
57
|
|
46
|
-
if
|
47
|
-
log_info("Envelope [#{item_type}] not sent: rate limiting")
|
48
|
-
record_lost_event(:ratelimit_backoff, item_type)
|
58
|
+
return if envelope.items.empty?
|
49
59
|
|
50
|
-
|
60
|
+
data, serialized_items = serialize_envelope(envelope)
|
61
|
+
|
62
|
+
if data
|
63
|
+
log_info("[Transport] Sending envelope with items [#{serialized_items.map(&:type).join(', ')}] #{envelope.event_id} to Sentry")
|
64
|
+
send_data(data)
|
51
65
|
end
|
66
|
+
end
|
52
67
|
|
53
|
-
|
68
|
+
def serialize_envelope(envelope)
|
69
|
+
serialized_items = []
|
70
|
+
serialized_results = []
|
54
71
|
|
55
|
-
|
72
|
+
envelope.items.each do |item|
|
73
|
+
result = item.to_s
|
56
74
|
|
57
|
-
|
75
|
+
if result.bytesize > Event::MAX_SERIALIZED_PAYLOAD_SIZE
|
76
|
+
item.payload.delete(:breadcrumbs)
|
77
|
+
result = item.to_s
|
78
|
+
end
|
58
79
|
|
59
|
-
|
80
|
+
if result.bytesize > Event::MAX_SERIALIZED_PAYLOAD_SIZE
|
81
|
+
size_breakdown = item.payload.map do |key, value|
|
82
|
+
"#{key}: #{JSON.generate(value).bytesize}"
|
83
|
+
end.join(", ")
|
84
|
+
|
85
|
+
log_debug("Envelope item [#{item.type}] is still oversized without breadcrumbs: {#{size_breakdown}}")
|
86
|
+
|
87
|
+
next
|
88
|
+
end
|
89
|
+
|
90
|
+
serialized_results << result
|
91
|
+
serialized_items << item
|
92
|
+
end
|
93
|
+
|
94
|
+
data = [JSON.generate(envelope.headers), *serialized_results].join("\n") unless serialized_results.empty?
|
95
|
+
|
96
|
+
[data, serialized_items]
|
60
97
|
end
|
61
98
|
|
62
99
|
def is_rate_limited?(item_type)
|
@@ -65,6 +102,8 @@ module Sentry
|
|
65
102
|
case item_type
|
66
103
|
when "transaction"
|
67
104
|
@rate_limits["transaction"]
|
105
|
+
when "sessions"
|
106
|
+
@rate_limits["session"]
|
68
107
|
else
|
69
108
|
@rate_limits["error"]
|
70
109
|
end
|
@@ -100,32 +139,28 @@ module Sentry
|
|
100
139
|
'Sentry ' + fields.map { |key, value| "#{key}=#{value}" }.join(', ')
|
101
140
|
end
|
102
141
|
|
103
|
-
def
|
142
|
+
def envelope_from_event(event)
|
104
143
|
# Convert to hash
|
105
144
|
event_payload = event.to_hash
|
106
|
-
|
107
145
|
event_id = event_payload[:event_id] || event_payload["event_id"]
|
108
146
|
item_type = get_item_type(event_payload)
|
109
147
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
148
|
+
envelope = Envelope.new(
|
149
|
+
{
|
150
|
+
event_id: event_id,
|
151
|
+
dsn: @dsn.to_s,
|
152
|
+
sdk: Sentry.sdk_meta,
|
153
|
+
sent_at: Sentry.utc_now.iso8601
|
154
|
+
}
|
155
|
+
)
|
116
156
|
|
117
|
-
|
157
|
+
envelope.add_item(
|
158
|
+
{ type: item_type, content_type: 'application/json' },
|
159
|
+
event_payload
|
160
|
+
)
|
118
161
|
|
119
|
-
|
120
|
-
|
121
|
-
#{JSON.generate(event_header)}
|
122
|
-
#{JSON.generate(event_payload)}
|
123
|
-
ENVELOPE
|
124
|
-
|
125
|
-
client_report = fetch_pending_client_report
|
126
|
-
envelope << client_report if client_report
|
127
|
-
|
128
|
-
log_info("Sending envelope [#{item_type}] #{event_id} to Sentry")
|
162
|
+
client_report_headers, client_report_payload = fetch_pending_client_report
|
163
|
+
envelope.add_item(client_report_headers, client_report_payload) if client_report_headers
|
129
164
|
|
130
165
|
envelope
|
131
166
|
end
|
@@ -159,21 +194,28 @@ module Sentry
|
|
159
194
|
end
|
160
195
|
|
161
196
|
item_header = { type: 'client_report' }
|
162
|
-
|
163
197
|
item_payload = {
|
164
198
|
timestamp: Sentry.utc_now.iso8601,
|
165
199
|
discarded_events: discarded_events_hash
|
166
200
|
}
|
167
201
|
|
168
|
-
client_report_item = <<~CLIENT_REPORT_ITEM
|
169
|
-
#{JSON.generate(item_header)}
|
170
|
-
#{JSON.generate(item_payload)}
|
171
|
-
CLIENT_REPORT_ITEM
|
172
|
-
|
173
202
|
@discarded_events = Hash.new(0)
|
174
203
|
@last_client_report_sent = Time.now
|
175
204
|
|
176
|
-
|
205
|
+
[item_header, item_payload]
|
206
|
+
end
|
207
|
+
|
208
|
+
def reject_rate_limited_items(envelope)
|
209
|
+
envelope.items.reject! do |item|
|
210
|
+
if is_rate_limited?(item.type)
|
211
|
+
log_info("[Transport] Envelope item [#{item.type}] not sent: rate limiting")
|
212
|
+
record_lost_event(:ratelimit_backoff, item.type)
|
213
|
+
|
214
|
+
true
|
215
|
+
else
|
216
|
+
false
|
217
|
+
end
|
218
|
+
end
|
177
219
|
end
|
178
220
|
end
|
179
221
|
end
|
@@ -1,24 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Sentry
|
2
4
|
module LoggingHelper
|
3
5
|
def log_error(message, exception, debug: false)
|
4
6
|
message = "#{message}: #{exception.message}"
|
5
7
|
message += "\n#{exception.backtrace.join("\n")}" if debug
|
6
8
|
|
7
|
-
logger.error(LOGGER_PROGNAME) do
|
9
|
+
@logger.error(LOGGER_PROGNAME) do
|
8
10
|
message
|
9
11
|
end
|
10
12
|
end
|
11
13
|
|
12
14
|
def log_info(message)
|
13
|
-
logger.info(LOGGER_PROGNAME) { message }
|
15
|
+
@logger.info(LOGGER_PROGNAME) { message }
|
14
16
|
end
|
15
17
|
|
16
18
|
def log_debug(message)
|
17
|
-
logger.debug(LOGGER_PROGNAME) { message }
|
19
|
+
@logger.debug(LOGGER_PROGNAME) { message }
|
18
20
|
end
|
19
21
|
|
20
22
|
def log_warn(message)
|
21
|
-
logger.warn(LOGGER_PROGNAME) { message }
|
23
|
+
@logger.warn(LOGGER_PROGNAME) { message }
|
22
24
|
end
|
23
25
|
end
|
24
26
|
end
|
data/lib/sentry/utils/real_ip.rb
CHANGED
data/lib/sentry/version.rb
CHANGED
data/lib/sentry-ruby.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "English"
|
2
4
|
require "forwardable"
|
3
5
|
require "time"
|
@@ -15,7 +17,7 @@ require "sentry/span"
|
|
15
17
|
require "sentry/transaction"
|
16
18
|
require "sentry/hub"
|
17
19
|
require "sentry/background_worker"
|
18
|
-
|
20
|
+
require "sentry/session_flusher"
|
19
21
|
|
20
22
|
[
|
21
23
|
"sentry/rake",
|
@@ -30,6 +32,8 @@ end
|
|
30
32
|
module Sentry
|
31
33
|
META = { "name" => "sentry.ruby", "version" => Sentry::VERSION }.freeze
|
32
34
|
|
35
|
+
CAPTURED_SIGNATURE = :@__sentry_captured
|
36
|
+
|
33
37
|
LOGGER_PROGNAME = "sentry".freeze
|
34
38
|
|
35
39
|
SENTRY_TRACE_HEADER_NAME = "sentry-trace".freeze
|
@@ -37,6 +41,7 @@ module Sentry
|
|
37
41
|
THREAD_LOCAL = :sentry_hub
|
38
42
|
|
39
43
|
class << self
|
44
|
+
# @!visibility private
|
40
45
|
def exception_locals_tp
|
41
46
|
@exception_locals_tp ||= TracePoint.new(:raise) do |tp|
|
42
47
|
exception = tp.raised_exception
|
@@ -53,46 +58,130 @@ module Sentry
|
|
53
58
|
end
|
54
59
|
end
|
55
60
|
|
61
|
+
# @!attribute [rw] background_worker
|
62
|
+
# @return [BackgroundWorker]
|
56
63
|
attr_accessor :background_worker
|
57
64
|
|
65
|
+
# @!attribute [r] session_flusher
|
66
|
+
# @return [SessionFlusher]
|
67
|
+
attr_reader :session_flusher
|
68
|
+
|
58
69
|
##### Patch Registration #####
|
59
|
-
|
70
|
+
|
71
|
+
# @!visibility private
|
60
72
|
def register_patch(&block)
|
61
73
|
registered_patches << block
|
62
74
|
end
|
63
75
|
|
76
|
+
# @!visibility private
|
64
77
|
def apply_patches(config)
|
65
78
|
registered_patches.each do |patch|
|
66
79
|
patch.call(config)
|
67
80
|
end
|
68
81
|
end
|
69
82
|
|
83
|
+
# @!visibility private
|
70
84
|
def registered_patches
|
71
85
|
@registered_patches ||= []
|
72
86
|
end
|
73
87
|
|
74
88
|
##### Integrations #####
|
75
|
-
|
89
|
+
|
76
90
|
# Returns a hash that contains all the integrations that have been registered to the main SDK.
|
91
|
+
#
|
92
|
+
# @return [Hash{String=>Hash}]
|
77
93
|
def integrations
|
78
94
|
@integrations ||= {}
|
79
95
|
end
|
80
96
|
|
81
97
|
# Registers the SDK integration with its name and version.
|
98
|
+
#
|
99
|
+
# @param name [String] name of the integration
|
100
|
+
# @param version [String] version of the integration
|
82
101
|
def register_integration(name, version)
|
83
102
|
meta = { name: "sentry.ruby.#{name}", version: version }.freeze
|
84
103
|
integrations[name.to_s] = meta
|
85
104
|
end
|
86
105
|
|
87
106
|
##### Method Delegation #####
|
88
|
-
|
107
|
+
|
89
108
|
extend Forwardable
|
90
109
|
|
91
|
-
|
92
|
-
|
110
|
+
# @!macro [new] configuration
|
111
|
+
# The Configuration object that's used for configuring the client and its transport.
|
112
|
+
# @return [Configuration]
|
113
|
+
# @!macro [new] send_event
|
114
|
+
# Sends the event to Sentry.
|
115
|
+
# @param event [Event] the event to be sent.
|
116
|
+
# @param hint [Hash] the hint data that'll be passed to `before_send` callback.
|
117
|
+
# @return [Event]
|
118
|
+
|
119
|
+
# @!method configuration
|
120
|
+
# @!macro configuration
|
121
|
+
def configuration
|
122
|
+
return unless initialized?
|
123
|
+
get_current_client.configuration
|
124
|
+
end
|
125
|
+
|
126
|
+
# @!method send_event
|
127
|
+
# @!macro send_event
|
128
|
+
def send_event(*args)
|
129
|
+
return unless initialized?
|
130
|
+
get_current_client.send_event(*args)
|
131
|
+
end
|
132
|
+
|
133
|
+
# @!macro [new] set_extras
|
134
|
+
# Updates the scope's extras attribute by merging with the old value.
|
135
|
+
# @param extras [Hash]
|
136
|
+
# @return [Hash]
|
137
|
+
# @!macro [new] set_user
|
138
|
+
# Sets the scope's user attribute.
|
139
|
+
# @param user [Hash]
|
140
|
+
# @return [Hash]
|
141
|
+
# @!macro [new] set_context
|
142
|
+
# Adds a new key-value pair to current contexts.
|
143
|
+
# @param key [String, Symbol]
|
144
|
+
# @param value [Object]
|
145
|
+
# @return [Hash]
|
146
|
+
# @!macro [new] set_tags
|
147
|
+
# Updates the scope's tags attribute by merging with the old value.
|
148
|
+
# @param tags [Hash]
|
149
|
+
# @return [Hash]
|
150
|
+
|
151
|
+
# @!method set_tags
|
152
|
+
# @!macro set_tags
|
153
|
+
def set_tags(*args)
|
154
|
+
return unless initialized?
|
155
|
+
get_current_scope.set_tags(*args)
|
156
|
+
end
|
157
|
+
|
158
|
+
# @!method set_extras
|
159
|
+
# @!macro set_extras
|
160
|
+
def set_extras(*args)
|
161
|
+
return unless initialized?
|
162
|
+
get_current_scope.set_extras(*args)
|
163
|
+
end
|
164
|
+
|
165
|
+
# @!method set_user
|
166
|
+
# @!macro set_user
|
167
|
+
def set_user(*args)
|
168
|
+
return unless initialized?
|
169
|
+
get_current_scope.set_user(*args)
|
170
|
+
end
|
171
|
+
|
172
|
+
# @!method set_context
|
173
|
+
# @!macro set_context
|
174
|
+
def set_context(*args)
|
175
|
+
return unless initialized?
|
176
|
+
get_current_scope.set_context(*args)
|
177
|
+
end
|
93
178
|
|
94
179
|
##### Main APIs #####
|
180
|
+
|
181
|
+
# Initializes the SDK with given configuration.
|
95
182
|
#
|
183
|
+
# @yieldparam config [Configuration]
|
184
|
+
# @return [void]
|
96
185
|
def init(&block)
|
97
186
|
config = Configuration.new
|
98
187
|
yield(config) if block_given?
|
@@ -105,36 +194,62 @@ module Sentry
|
|
105
194
|
@main_hub = hub
|
106
195
|
@background_worker = Sentry::BackgroundWorker.new(config)
|
107
196
|
|
197
|
+
@session_flusher = if config.auto_session_tracking
|
198
|
+
Sentry::SessionFlusher.new(config, client)
|
199
|
+
else
|
200
|
+
nil
|
201
|
+
end
|
202
|
+
|
108
203
|
if config.capture_exception_frame_locals
|
109
204
|
exception_locals_tp.enable
|
110
205
|
end
|
206
|
+
|
207
|
+
at_exit do
|
208
|
+
@session_flusher&.kill
|
209
|
+
@background_worker.shutdown
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
# Returns true if the SDK is initialized.
|
214
|
+
#
|
215
|
+
# @return [Boolean]
|
216
|
+
def initialized?
|
217
|
+
!!get_main_hub
|
111
218
|
end
|
112
219
|
|
113
220
|
# Returns an uri for security policy reporting that's generated from the given DSN
|
114
221
|
# (To learn more about security policy reporting: https://docs.sentry.io/product/security-policy-reporting/)
|
115
222
|
#
|
116
223
|
# It returns nil if
|
224
|
+
# - The SDK is not initialized yet.
|
225
|
+
# - The DSN is not provided or is invalid.
|
117
226
|
#
|
118
|
-
#
|
119
|
-
# 2. The DSN is not provided or is invalid.
|
227
|
+
# @return [String, nil]
|
120
228
|
def csp_report_uri
|
121
229
|
return unless initialized?
|
122
230
|
configuration.csp_report_uri
|
123
231
|
end
|
124
232
|
|
125
233
|
# Returns the main thread's active hub.
|
234
|
+
#
|
235
|
+
# @return [Hub]
|
126
236
|
def get_main_hub
|
127
237
|
@main_hub
|
128
238
|
end
|
129
239
|
|
130
240
|
# Takes an instance of Sentry::Breadcrumb and stores it to the current active scope.
|
241
|
+
#
|
242
|
+
# @return [Breadcrumb, nil]
|
131
243
|
def add_breadcrumb(breadcrumb, **options)
|
132
|
-
|
244
|
+
return unless initialized?
|
245
|
+
get_current_hub.add_breadcrumb(breadcrumb, **options)
|
133
246
|
end
|
134
247
|
|
135
248
|
# Returns the current active hub.
|
136
249
|
# If the current thread doesn't have an active hub, it will clone the main thread's active hub,
|
137
250
|
# stores it in the current thread, and then returns it.
|
251
|
+
#
|
252
|
+
# @return [Hub]
|
138
253
|
def get_current_hub
|
139
254
|
# we need to assign a hub to the current thread if it doesn't have one yet
|
140
255
|
#
|
@@ -145,85 +260,141 @@ module Sentry
|
|
145
260
|
end
|
146
261
|
|
147
262
|
# Returns the current active client.
|
263
|
+
# @return [Client, nil]
|
148
264
|
def get_current_client
|
149
|
-
|
265
|
+
return unless initialized?
|
266
|
+
get_current_hub.current_client
|
150
267
|
end
|
151
268
|
|
152
269
|
# Returns the current active scope.
|
270
|
+
#
|
271
|
+
# @return [Scope, nil]
|
153
272
|
def get_current_scope
|
154
|
-
|
273
|
+
return unless initialized?
|
274
|
+
get_current_hub.current_scope
|
155
275
|
end
|
156
276
|
|
157
277
|
# Clones the main thread's active hub and stores it to the current thread.
|
278
|
+
#
|
279
|
+
# @return [void]
|
158
280
|
def clone_hub_to_current_thread
|
159
281
|
Thread.current.thread_variable_set(THREAD_LOCAL, get_main_hub.clone)
|
160
282
|
end
|
161
283
|
|
162
284
|
# Takes a block and yields the current active scope.
|
163
285
|
#
|
164
|
-
#
|
165
|
-
#
|
166
|
-
#
|
167
|
-
#
|
286
|
+
# @example
|
287
|
+
# Sentry.configure_scope do |scope|
|
288
|
+
# scope.set_tags(foo: "bar")
|
289
|
+
# end
|
168
290
|
#
|
169
|
-
#
|
170
|
-
# ```
|
291
|
+
# Sentry.capture_message("test message") # this event will have tags { foo: "bar" }
|
171
292
|
#
|
293
|
+
# @yieldparam scope [Scope]
|
294
|
+
# @return [void]
|
172
295
|
def configure_scope(&block)
|
173
|
-
|
296
|
+
return unless initialized?
|
297
|
+
get_current_hub.configure_scope(&block)
|
174
298
|
end
|
175
299
|
|
176
300
|
# Takes a block and yields a temporary scope.
|
177
301
|
# The temporary scope will inherit all the attributes from the current active scope and replace it to be the active
|
178
|
-
# scope inside the block.
|
302
|
+
# scope inside the block.
|
179
303
|
#
|
180
|
-
#
|
181
|
-
#
|
182
|
-
#
|
183
|
-
#
|
304
|
+
# @example
|
305
|
+
# Sentry.configure_scope do |scope|
|
306
|
+
# scope.set_tags(foo: "bar")
|
307
|
+
# end
|
184
308
|
#
|
185
|
-
#
|
309
|
+
# Sentry.capture_message("test message") # this event will have tags { foo: "bar" }
|
186
310
|
#
|
187
|
-
#
|
188
|
-
#
|
189
|
-
#
|
190
|
-
#
|
311
|
+
# Sentry.with_scope do |temp_scope|
|
312
|
+
# temp_scope.set_tags(foo: "baz")
|
313
|
+
# Sentry.capture_message("test message 2") # this event will have tags { foo: "baz" }
|
314
|
+
# end
|
191
315
|
#
|
192
|
-
#
|
193
|
-
# ```
|
316
|
+
# Sentry.capture_message("test message 3") # this event will have tags { foo: "bar" }
|
194
317
|
#
|
318
|
+
# @yieldparam scope [Scope]
|
319
|
+
# @return [void]
|
195
320
|
def with_scope(&block)
|
196
|
-
|
321
|
+
return unless initialized?
|
322
|
+
get_current_hub.with_scope(&block)
|
323
|
+
end
|
324
|
+
|
325
|
+
# Wrap a given block with session tracking.
|
326
|
+
# Aggregate sessions in minutely buckets will be recorded
|
327
|
+
# around this block and flushed every minute.
|
328
|
+
#
|
329
|
+
# @example
|
330
|
+
# Sentry.with_session_tracking do
|
331
|
+
# a = 1 + 1 # new session recorded with :exited status
|
332
|
+
# end
|
333
|
+
#
|
334
|
+
# Sentry.with_session_tracking do
|
335
|
+
# 1 / 0
|
336
|
+
# rescue => e
|
337
|
+
# Sentry.capture_exception(e) # new session recorded with :errored status
|
338
|
+
# end
|
339
|
+
# @return [void]
|
340
|
+
def with_session_tracking(&block)
|
341
|
+
return yield unless initialized?
|
342
|
+
get_current_hub.with_session_tracking(&block)
|
197
343
|
end
|
198
344
|
|
199
345
|
# Takes an exception and reports it to Sentry via the currently active hub.
|
346
|
+
#
|
347
|
+
# @yieldparam scope [Scope]
|
348
|
+
# @return [Event, nil]
|
200
349
|
def capture_exception(exception, **options, &block)
|
201
|
-
|
350
|
+
return unless initialized?
|
351
|
+
get_current_hub.capture_exception(exception, **options, &block)
|
202
352
|
end
|
203
353
|
|
204
354
|
# Takes a message string and reports it to Sentry via the currently active hub.
|
355
|
+
#
|
356
|
+
# @yieldparam scope [Scope]
|
357
|
+
# @return [Event, nil]
|
205
358
|
def capture_message(message, **options, &block)
|
206
|
-
|
359
|
+
return unless initialized?
|
360
|
+
get_current_hub.capture_message(message, **options, &block)
|
207
361
|
end
|
208
362
|
|
209
363
|
# Takes an instance of Sentry::Event and dispatches it to the currently active hub.
|
364
|
+
#
|
365
|
+
# @return [Event, nil]
|
210
366
|
def capture_event(event)
|
211
|
-
|
367
|
+
return unless initialized?
|
368
|
+
get_current_hub.capture_event(event)
|
212
369
|
end
|
213
370
|
|
214
371
|
# Takes or initializes a new Sentry::Transaction and makes a sampling decision for it.
|
372
|
+
#
|
373
|
+
# @return [Transaction, nil]
|
215
374
|
def start_transaction(**options)
|
216
|
-
|
375
|
+
return unless initialized?
|
376
|
+
get_current_hub.start_transaction(**options)
|
217
377
|
end
|
218
378
|
|
219
379
|
# Returns the id of the lastly reported Sentry::Event.
|
380
|
+
#
|
381
|
+
# @return [String, nil]
|
220
382
|
def last_event_id
|
221
|
-
|
383
|
+
return unless initialized?
|
384
|
+
get_current_hub.last_event_id
|
222
385
|
end
|
223
386
|
|
387
|
+
# Checks if the exception object has been captured by the SDK.
|
388
|
+
#
|
389
|
+
# @return [Boolean]
|
390
|
+
def exception_captured?(exc)
|
391
|
+
return false unless initialized?
|
392
|
+
!!exc.instance_variable_get(CAPTURED_SIGNATURE)
|
393
|
+
end
|
224
394
|
|
225
395
|
##### Helpers #####
|
226
|
-
|
396
|
+
|
397
|
+
# @!visibility private
|
227
398
|
def sys_command(command)
|
228
399
|
result = `#{command} 2>&1` rescue nil
|
229
400
|
return if result.nil? || result.empty? || ($CHILD_STATUS && $CHILD_STATUS.exitstatus != 0)
|
@@ -231,18 +402,17 @@ module Sentry
|
|
231
402
|
result.strip
|
232
403
|
end
|
233
404
|
|
234
|
-
|
235
|
-
!!@main_hub
|
236
|
-
end
|
237
|
-
|
405
|
+
# @!visibility private
|
238
406
|
def logger
|
239
407
|
configuration.logger
|
240
408
|
end
|
241
409
|
|
410
|
+
# @!visibility private
|
242
411
|
def sdk_meta
|
243
412
|
META
|
244
413
|
end
|
245
414
|
|
415
|
+
# @!visibility private
|
246
416
|
def utc_now
|
247
417
|
Time.now.utc
|
248
418
|
end
|
@@ -251,3 +421,4 @@ end
|
|
251
421
|
|
252
422
|
# patches
|
253
423
|
require "sentry/net/http"
|
424
|
+
require "sentry/redis"
|
data/sentry-ruby-core.gemspec
CHANGED
data/sentry-ruby.gemspec
CHANGED
@@ -18,6 +18,5 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/master/CHANGELOG.md"
|
19
19
|
|
20
20
|
spec.add_dependency "sentry-ruby-core", Sentry::VERSION
|
21
|
-
spec.add_dependency "faraday", ">= 1.0"
|
22
21
|
spec.add_dependency "concurrent-ruby", '~> 1.0', '>= 1.0.2'
|
23
22
|
end
|