sentry-ruby 5.4.2 → 5.16.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +0 -1
- data/Gemfile +13 -14
- data/README.md +11 -8
- data/Rakefile +8 -1
- data/lib/sentry/background_worker.rb +8 -1
- data/lib/sentry/backpressure_monitor.rb +75 -0
- data/lib/sentry/backtrace.rb +1 -1
- data/lib/sentry/baggage.rb +70 -0
- data/lib/sentry/breadcrumb.rb +8 -2
- data/lib/sentry/check_in_event.rb +60 -0
- data/lib/sentry/client.rb +77 -19
- data/lib/sentry/configuration.rb +177 -29
- data/lib/sentry/cron/configuration.rb +23 -0
- data/lib/sentry/cron/monitor_check_ins.rb +75 -0
- data/lib/sentry/cron/monitor_config.rb +53 -0
- data/lib/sentry/cron/monitor_schedule.rb +42 -0
- data/lib/sentry/envelope.rb +2 -5
- data/lib/sentry/event.rb +7 -29
- data/lib/sentry/hub.rb +100 -4
- data/lib/sentry/integrable.rb +6 -0
- data/lib/sentry/interfaces/request.rb +6 -16
- data/lib/sentry/interfaces/single_exception.rb +13 -3
- data/lib/sentry/net/http.rb +37 -46
- data/lib/sentry/profiler.rb +233 -0
- data/lib/sentry/propagation_context.rb +134 -0
- data/lib/sentry/puma.rb +32 -0
- data/lib/sentry/rack/capture_exceptions.rb +4 -5
- data/lib/sentry/rake.rb +1 -14
- data/lib/sentry/redis.rb +41 -23
- data/lib/sentry/release_detector.rb +1 -1
- data/lib/sentry/scope.rb +81 -16
- data/lib/sentry/session.rb +5 -7
- data/lib/sentry/span.rb +57 -10
- data/lib/sentry/test_helper.rb +19 -11
- data/lib/sentry/transaction.rb +183 -30
- data/lib/sentry/transaction_event.rb +51 -0
- data/lib/sentry/transport/configuration.rb +74 -1
- data/lib/sentry/transport/http_transport.rb +68 -37
- data/lib/sentry/transport/spotlight_transport.rb +50 -0
- data/lib/sentry/transport.rb +39 -24
- data/lib/sentry/utils/argument_checking_helper.rb +9 -3
- data/lib/sentry/utils/encoding_helper.rb +22 -0
- data/lib/sentry/version.rb +1 -1
- data/lib/sentry-ruby.rb +116 -41
- metadata +14 -3
- data/CODE_OF_CONDUCT.md +0 -74
data/lib/sentry/configuration.rb
CHANGED
@@ -7,6 +7,7 @@ require 'sentry/utils/custom_inspection'
|
|
7
7
|
require "sentry/dsn"
|
8
8
|
require "sentry/release_detector"
|
9
9
|
require "sentry/transport/configuration"
|
10
|
+
require "sentry/cron/configuration"
|
10
11
|
require "sentry/linecache"
|
11
12
|
require "sentry/interfaces/stacktrace_builder"
|
12
13
|
|
@@ -14,6 +15,8 @@ module Sentry
|
|
14
15
|
class Configuration
|
15
16
|
include CustomInspection
|
16
17
|
include LoggingHelper
|
18
|
+
include ArgumentCheckingHelper
|
19
|
+
|
17
20
|
# Directories to be recognized as part of your app. e.g. if you
|
18
21
|
# have an `engines` dir at the root of your project, you may want
|
19
22
|
# to set this to something like /(app|config|engines|lib)/
|
@@ -38,6 +41,13 @@ module Sentry
|
|
38
41
|
# @return [Integer]
|
39
42
|
attr_accessor :background_worker_threads
|
40
43
|
|
44
|
+
# The maximum queue size for the background worker.
|
45
|
+
# Jobs will be rejected above this limit.
|
46
|
+
#
|
47
|
+
# Default is {BackgroundWorker::DEFAULT_MAX_QUEUE}.
|
48
|
+
# @return [Integer]
|
49
|
+
attr_accessor :background_worker_max_queue
|
50
|
+
|
41
51
|
# a proc/lambda that takes an array of stack traces
|
42
52
|
# it'll be used to silence (reduce) backtrace of the exception
|
43
53
|
#
|
@@ -72,6 +82,19 @@ module Sentry
|
|
72
82
|
# @return [Proc]
|
73
83
|
attr_reader :before_send
|
74
84
|
|
85
|
+
# Optional Proc, called before sending an event to the server
|
86
|
+
# @example
|
87
|
+
# config.before_send_transaction = lambda do |event, hint|
|
88
|
+
# # skip unimportant transactions or strip sensitive data
|
89
|
+
# if event.transaction == "/healthcheck/route"
|
90
|
+
# nil
|
91
|
+
# else
|
92
|
+
# event
|
93
|
+
# end
|
94
|
+
# end
|
95
|
+
# @return [Proc]
|
96
|
+
attr_reader :before_send_transaction
|
97
|
+
|
75
98
|
# An array of breadcrumbs loggers to be used. Available options are:
|
76
99
|
# - :sentry_logger
|
77
100
|
# - :http_logger
|
@@ -84,10 +107,6 @@ module Sentry
|
|
84
107
|
# @return [Array<Symbol>]
|
85
108
|
attr_reader :breadcrumbs_logger
|
86
109
|
|
87
|
-
# Whether to capture local variables from the raised exception's frame. Default is false.
|
88
|
-
# @return [Boolean]
|
89
|
-
attr_accessor :capture_exception_frame_locals
|
90
|
-
|
91
110
|
# Max number of breadcrumbs a breadcrumb buffer can hold
|
92
111
|
# @return [Integer]
|
93
112
|
attr_accessor :max_breadcrumbs
|
@@ -127,6 +146,30 @@ module Sentry
|
|
127
146
|
attr_accessor :inspect_exception_causes_for_exclusion
|
128
147
|
alias inspect_exception_causes_for_exclusion? inspect_exception_causes_for_exclusion
|
129
148
|
|
149
|
+
# Whether to capture local variables from the raised exception's frame. Default is false.
|
150
|
+
# @return [Boolean]
|
151
|
+
attr_accessor :include_local_variables
|
152
|
+
|
153
|
+
# Whether to capture events and traces into Spotlight. Default is false.
|
154
|
+
# If you set this to true, Sentry will send events and traces to the local
|
155
|
+
# Sidecar proxy at http://localhost:8969/stream.
|
156
|
+
# If you want to use a different Sidecar proxy address, set this to String
|
157
|
+
# with the proxy URL.
|
158
|
+
# @return [Boolean, String]
|
159
|
+
attr_accessor :spotlight
|
160
|
+
|
161
|
+
# @deprecated Use {#include_local_variables} instead.
|
162
|
+
alias_method :capture_exception_frame_locals, :include_local_variables
|
163
|
+
|
164
|
+
# @deprecated Use {#include_local_variables=} instead.
|
165
|
+
def capture_exception_frame_locals=(value)
|
166
|
+
log_warn <<~MSG
|
167
|
+
`capture_exception_frame_locals` is now deprecated in favor of `include_local_variables`.
|
168
|
+
MSG
|
169
|
+
|
170
|
+
self.include_local_variables = value
|
171
|
+
end
|
172
|
+
|
130
173
|
# You may provide your own LineCache for matching paths with source files.
|
131
174
|
# This may be useful if you need to get source code from places other than the disk.
|
132
175
|
# @see LineCache
|
@@ -154,7 +197,7 @@ module Sentry
|
|
154
197
|
# Release tag to be passed with every event sent to Sentry.
|
155
198
|
# We automatically try to set this to a git SHA or Capistrano release.
|
156
199
|
# @return [String]
|
157
|
-
|
200
|
+
attr_reader :release
|
158
201
|
|
159
202
|
# The sampling factor to apply to events. A value of 0.0 will not send
|
160
203
|
# any events, and a value of 1.0 will send 100% of events.
|
@@ -184,13 +227,17 @@ module Sentry
|
|
184
227
|
# @return [String]
|
185
228
|
attr_accessor :server_name
|
186
229
|
|
187
|
-
#
|
188
|
-
# @return [Transport]
|
230
|
+
# Transport related configuration.
|
231
|
+
# @return [Transport::Configuration]
|
189
232
|
attr_reader :transport
|
190
233
|
|
234
|
+
# Cron related configuration.
|
235
|
+
# @return [Cron::Configuration]
|
236
|
+
attr_reader :cron
|
237
|
+
|
191
238
|
# Take a float between 0.0 and 1.0 as the sample rate for tracing events (transactions).
|
192
|
-
# @return [Float]
|
193
|
-
|
239
|
+
# @return [Float, nil]
|
240
|
+
attr_reader :traces_sample_rate
|
194
241
|
|
195
242
|
# Take a Proc that controls the sample rate for every tracing event, e.g.
|
196
243
|
# @example
|
@@ -202,6 +249,11 @@ module Sentry
|
|
202
249
|
# @return [Proc]
|
203
250
|
attr_accessor :traces_sampler
|
204
251
|
|
252
|
+
# Easier way to use performance tracing
|
253
|
+
# If set to true, will set traces_sample_rate to 1.0
|
254
|
+
# @return [Boolean, nil]
|
255
|
+
attr_reader :enable_tracing
|
256
|
+
|
205
257
|
# Send diagnostic client reports about dropped events, true by default
|
206
258
|
# tries to attach to an existing envelope max once every 30s
|
207
259
|
# @return [Boolean]
|
@@ -211,10 +263,45 @@ module Sentry
|
|
211
263
|
# @return [Boolean]
|
212
264
|
attr_accessor :auto_session_tracking
|
213
265
|
|
266
|
+
# Whether to downsample transactions automatically because of backpressure.
|
267
|
+
# Starts a new monitor thread to check health of the SDK every 10 seconds.
|
268
|
+
# Default is false
|
269
|
+
# @return [Boolean]
|
270
|
+
attr_accessor :enable_backpressure_handling
|
271
|
+
|
272
|
+
# Allowlist of outgoing request targets to which sentry-trace and baggage headers are attached.
|
273
|
+
# Default is all (/.*/)
|
274
|
+
# @return [Array<String, Regexp>]
|
275
|
+
attr_accessor :trace_propagation_targets
|
276
|
+
|
277
|
+
# The instrumenter to use, :sentry or :otel
|
278
|
+
# @return [Symbol]
|
279
|
+
attr_reader :instrumenter
|
280
|
+
|
281
|
+
# Take a float between 0.0 and 1.0 as the sample rate for capturing profiles.
|
282
|
+
# Note that this rate is relative to traces_sample_rate / traces_sampler,
|
283
|
+
# i.e. the profile is sampled by this rate after the transaction is sampled.
|
284
|
+
# @return [Float, nil]
|
285
|
+
attr_reader :profiles_sample_rate
|
286
|
+
|
287
|
+
# Array of patches to apply.
|
288
|
+
# Default is {DEFAULT_PATCHES}
|
289
|
+
# @return [Array<Symbol>]
|
290
|
+
attr_accessor :enabled_patches
|
291
|
+
|
214
292
|
# these are not config options
|
215
293
|
# @!visibility private
|
216
294
|
attr_reader :errors, :gem_specs
|
217
295
|
|
296
|
+
# These exceptions could enter Puma's `lowlevel_error_handler` callback and the SDK's Puma integration
|
297
|
+
# But they are mostly considered as noise and should be ignored by default
|
298
|
+
# Please see https://github.com/getsentry/sentry-ruby/pull/2026 for more information
|
299
|
+
PUMA_IGNORE_DEFAULT = [
|
300
|
+
'Puma::MiniSSL::SSLError',
|
301
|
+
'Puma::HttpParserError',
|
302
|
+
'Puma::HttpParserError501'
|
303
|
+
].freeze
|
304
|
+
|
218
305
|
# Most of these errors generate 4XX responses. In general, Sentry clients
|
219
306
|
# only automatically report 5xx responses.
|
220
307
|
IGNORE_DEFAULT = [
|
@@ -237,23 +324,39 @@ module Sentry
|
|
237
324
|
MODULE_SEPARATOR = "::".freeze
|
238
325
|
SKIP_INSPECTION_ATTRIBUTES = [:@linecache, :@stacktrace_builder]
|
239
326
|
|
240
|
-
|
241
|
-
|
242
|
-
|
327
|
+
INSTRUMENTERS = [:sentry, :otel]
|
328
|
+
|
329
|
+
PROPAGATION_TARGETS_MATCH_ALL = /.*/.freeze
|
330
|
+
|
331
|
+
DEFAULT_PATCHES = %i(redis puma http).freeze
|
332
|
+
|
333
|
+
class << self
|
334
|
+
# Post initialization callbacks are called at the end of initialization process
|
335
|
+
# allowing extending the configuration of sentry-ruby by multiple extensions
|
336
|
+
def post_initialization_callbacks
|
337
|
+
@post_initialization_callbacks ||= []
|
338
|
+
end
|
339
|
+
|
340
|
+
# allow extensions to add their hooks to the Configuration class
|
341
|
+
def add_post_initialization_callback(&block)
|
342
|
+
post_initialization_callbacks << block
|
343
|
+
end
|
344
|
+
end
|
243
345
|
|
244
346
|
def initialize
|
245
347
|
self.app_dirs_pattern = nil
|
246
348
|
self.debug = false
|
247
349
|
self.background_worker_threads = Concurrent.processor_count
|
350
|
+
self.background_worker_max_queue = BackgroundWorker::DEFAULT_MAX_QUEUE
|
248
351
|
self.backtrace_cleanup_callback = nil
|
249
352
|
self.max_breadcrumbs = BreadcrumbBuffer::DEFAULT_SIZE
|
250
353
|
self.breadcrumbs_logger = []
|
251
354
|
self.context_lines = 3
|
252
|
-
self.
|
355
|
+
self.include_local_variables = false
|
253
356
|
self.environment = environment_from_env
|
254
357
|
self.enabled_environments = []
|
255
358
|
self.exclude_loggers = []
|
256
|
-
self.excluded_exceptions = IGNORE_DEFAULT
|
359
|
+
self.excluded_exceptions = IGNORE_DEFAULT + PUMA_IGNORE_DEFAULT
|
257
360
|
self.inspect_exception_causes_for_exclusion = true
|
258
361
|
self.linecache = ::Sentry::LineCache.new
|
259
362
|
self.logger = ::Sentry::Logger.new(STDOUT)
|
@@ -266,16 +369,23 @@ module Sentry
|
|
266
369
|
self.skip_rake_integration = false
|
267
370
|
self.send_client_reports = true
|
268
371
|
self.auto_session_tracking = true
|
372
|
+
self.enable_backpressure_handling = false
|
269
373
|
self.trusted_proxies = []
|
270
374
|
self.dsn = ENV['SENTRY_DSN']
|
375
|
+
self.spotlight = false
|
271
376
|
self.server_name = server_name_from_env
|
377
|
+
self.instrumenter = :sentry
|
378
|
+
self.trace_propagation_targets = [PROPAGATION_TARGETS_MATCH_ALL]
|
379
|
+
self.enabled_patches = DEFAULT_PATCHES.dup
|
272
380
|
|
273
381
|
self.before_send = nil
|
382
|
+
self.before_send_transaction = nil
|
274
383
|
self.rack_env_whitelist = RACK_ENV_WHITELIST_DEFAULT
|
275
|
-
self.traces_sample_rate = nil
|
276
384
|
self.traces_sampler = nil
|
385
|
+
self.enable_tracing = nil
|
277
386
|
|
278
387
|
@transport = Transport::Configuration.new
|
388
|
+
@cron = Cron::Configuration.new
|
279
389
|
@gem_specs = Hash[Gem::Specification.map { |spec| [spec.name, spec.version.to_s] }] if Gem::Specification.respond_to?(:map)
|
280
390
|
|
281
391
|
run_post_initialization_callbacks
|
@@ -287,6 +397,12 @@ module Sentry
|
|
287
397
|
|
288
398
|
alias server= dsn=
|
289
399
|
|
400
|
+
def release=(value)
|
401
|
+
check_argument_type!(value, String, NilClass)
|
402
|
+
|
403
|
+
@release = value
|
404
|
+
end
|
405
|
+
|
290
406
|
def async=(value)
|
291
407
|
check_callable!("async", value)
|
292
408
|
|
@@ -322,6 +438,12 @@ module Sentry
|
|
322
438
|
@before_send = value
|
323
439
|
end
|
324
440
|
|
441
|
+
def before_send_transaction=(value)
|
442
|
+
check_callable!("before_send_transaction", value)
|
443
|
+
|
444
|
+
@before_send_transaction = value
|
445
|
+
end
|
446
|
+
|
325
447
|
def before_breadcrumb=(value)
|
326
448
|
check_callable!("before_breadcrumb", value)
|
327
449
|
|
@@ -332,10 +454,34 @@ module Sentry
|
|
332
454
|
@environment = environment.to_s
|
333
455
|
end
|
334
456
|
|
457
|
+
def instrumenter=(instrumenter)
|
458
|
+
@instrumenter = INSTRUMENTERS.include?(instrumenter) ? instrumenter : :sentry
|
459
|
+
end
|
460
|
+
|
461
|
+
def enable_tracing=(enable_tracing)
|
462
|
+
@enable_tracing = enable_tracing
|
463
|
+
@traces_sample_rate ||= 1.0 if enable_tracing
|
464
|
+
end
|
465
|
+
|
466
|
+
def is_numeric_or_nil?(value)
|
467
|
+
value.is_a?(Numeric) || value.nil?
|
468
|
+
end
|
469
|
+
|
470
|
+
def traces_sample_rate=(traces_sample_rate)
|
471
|
+
raise ArgumentError, "traces_sample_rate must be a Numeric or nil" unless is_numeric_or_nil?(traces_sample_rate)
|
472
|
+
@traces_sample_rate = traces_sample_rate
|
473
|
+
end
|
474
|
+
|
475
|
+
def profiles_sample_rate=(profiles_sample_rate)
|
476
|
+
raise ArgumentError, "profiles_sample_rate must be a Numeric or nil" unless is_numeric_or_nil?(profiles_sample_rate)
|
477
|
+
log_warn("Please make sure to include the 'stackprof' gem in your Gemfile to use Profiling with Sentry.") unless defined?(StackProf)
|
478
|
+
@profiles_sample_rate = profiles_sample_rate
|
479
|
+
end
|
480
|
+
|
335
481
|
def sending_allowed?
|
336
482
|
@errors = []
|
337
483
|
|
338
|
-
valid? && capture_in_environment?
|
484
|
+
spotlight || (valid? && capture_in_environment?)
|
339
485
|
end
|
340
486
|
|
341
487
|
def sample_allowed?
|
@@ -361,8 +507,21 @@ module Sentry
|
|
361
507
|
enabled_environments.empty? || enabled_environments.include?(environment)
|
362
508
|
end
|
363
509
|
|
510
|
+
def valid_sample_rate?(sample_rate)
|
511
|
+
return false unless sample_rate.is_a?(Numeric)
|
512
|
+
sample_rate >= 0.0 && sample_rate <= 1.0
|
513
|
+
end
|
514
|
+
|
364
515
|
def tracing_enabled?
|
365
|
-
!!((@traces_sample_rate
|
516
|
+
valid_sampler = !!((valid_sample_rate?(@traces_sample_rate)) || @traces_sampler)
|
517
|
+
|
518
|
+
(@enable_tracing != false) && valid_sampler && sending_allowed?
|
519
|
+
end
|
520
|
+
|
521
|
+
def profiling_enabled?
|
522
|
+
valid_sampler = !!(valid_sample_rate?(@profiles_sample_rate))
|
523
|
+
|
524
|
+
tracing_enabled? && valid_sampler && sending_allowed?
|
366
525
|
end
|
367
526
|
|
368
527
|
# @return [String, nil]
|
@@ -390,7 +549,7 @@ module Sentry
|
|
390
549
|
def detect_release
|
391
550
|
return unless sending_allowed?
|
392
551
|
|
393
|
-
|
552
|
+
@release ||= ReleaseDetector.detect_release(project_root: project_root, running_on_heroku: running_on_heroku?)
|
394
553
|
|
395
554
|
if running_on_heroku? && release.nil?
|
396
555
|
log_warn(HEROKU_DYNO_METADATA_MESSAGE)
|
@@ -487,16 +646,5 @@ module Sentry
|
|
487
646
|
instance_eval(&hook)
|
488
647
|
end
|
489
648
|
end
|
490
|
-
|
491
|
-
# allow extensions to add their hooks to the Configuration class
|
492
|
-
def self.add_post_initialization_callback(&block)
|
493
|
-
self.post_initialization_callbacks << block
|
494
|
-
end
|
495
|
-
|
496
|
-
protected
|
497
|
-
|
498
|
-
def self.post_initialization_callbacks
|
499
|
-
@@post_initialization_callbacks
|
500
|
-
end
|
501
649
|
end
|
502
650
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sentry
|
4
|
+
module Cron
|
5
|
+
class Configuration
|
6
|
+
# Defaults set here will apply to all {Cron::MonitorConfig} objects unless overwritten.
|
7
|
+
|
8
|
+
# How long (in minutes) after the expected checkin time will we wait
|
9
|
+
# until we consider the checkin to have been missed.
|
10
|
+
# @return [Integer, nil]
|
11
|
+
attr_accessor :default_checkin_margin
|
12
|
+
|
13
|
+
# How long (in minutes) is the checkin allowed to run for in in_progress
|
14
|
+
# before it is considered failed.
|
15
|
+
# @return [Integer, nil]
|
16
|
+
attr_accessor :default_max_runtime
|
17
|
+
|
18
|
+
# tz database style timezone string
|
19
|
+
# @return [String, nil]
|
20
|
+
attr_accessor :default_timezone
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Sentry
|
2
|
+
module Cron
|
3
|
+
module MonitorCheckIns
|
4
|
+
MAX_SLUG_LENGTH = 50
|
5
|
+
|
6
|
+
module Patch
|
7
|
+
def perform(*args, **opts)
|
8
|
+
slug = self.class.sentry_monitor_slug
|
9
|
+
monitor_config = self.class.sentry_monitor_config
|
10
|
+
|
11
|
+
check_in_id = Sentry.capture_check_in(slug,
|
12
|
+
:in_progress,
|
13
|
+
monitor_config: monitor_config)
|
14
|
+
|
15
|
+
start = Sentry.utc_now.to_i
|
16
|
+
|
17
|
+
begin
|
18
|
+
# need to do this on ruby <= 2.6 sadly
|
19
|
+
ret = method(:perform).super_method.arity == 0 ? super() : super
|
20
|
+
duration = Sentry.utc_now.to_i - start
|
21
|
+
|
22
|
+
Sentry.capture_check_in(slug,
|
23
|
+
:ok,
|
24
|
+
check_in_id: check_in_id,
|
25
|
+
duration: duration,
|
26
|
+
monitor_config: monitor_config)
|
27
|
+
|
28
|
+
ret
|
29
|
+
rescue Exception
|
30
|
+
duration = Sentry.utc_now.to_i - start
|
31
|
+
|
32
|
+
Sentry.capture_check_in(slug,
|
33
|
+
:error,
|
34
|
+
check_in_id: check_in_id,
|
35
|
+
duration: duration,
|
36
|
+
monitor_config: monitor_config)
|
37
|
+
|
38
|
+
raise
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
module ClassMethods
|
44
|
+
def sentry_monitor_check_ins(slug: nil, monitor_config: nil)
|
45
|
+
if monitor_config && Sentry.configuration
|
46
|
+
cron_config = Sentry.configuration.cron
|
47
|
+
monitor_config.checkin_margin ||= cron_config.default_checkin_margin
|
48
|
+
monitor_config.max_runtime ||= cron_config.default_max_runtime
|
49
|
+
monitor_config.timezone ||= cron_config.default_timezone
|
50
|
+
end
|
51
|
+
|
52
|
+
@sentry_monitor_slug = slug
|
53
|
+
@sentry_monitor_config = monitor_config
|
54
|
+
|
55
|
+
prepend Patch
|
56
|
+
end
|
57
|
+
|
58
|
+
def sentry_monitor_slug(name: self.name)
|
59
|
+
@sentry_monitor_slug ||= begin
|
60
|
+
slug = name.gsub('::', '-').downcase
|
61
|
+
slug[-MAX_SLUG_LENGTH..-1] || slug
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def sentry_monitor_config
|
66
|
+
@sentry_monitor_config
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.included(base)
|
71
|
+
base.extend(ClassMethods)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'sentry/cron/monitor_schedule'
|
4
|
+
|
5
|
+
module Sentry
|
6
|
+
module Cron
|
7
|
+
class MonitorConfig
|
8
|
+
# The monitor schedule configuration
|
9
|
+
# @return [MonitorSchedule::Crontab, MonitorSchedule::Interval]
|
10
|
+
attr_accessor :schedule
|
11
|
+
|
12
|
+
# How long (in minutes) after the expected checkin time will we wait
|
13
|
+
# until we consider the checkin to have been missed.
|
14
|
+
# @return [Integer, nil]
|
15
|
+
attr_accessor :checkin_margin
|
16
|
+
|
17
|
+
# How long (in minutes) is the checkin allowed to run for in in_progress
|
18
|
+
# before it is considered failed.
|
19
|
+
# @return [Integer, nil]
|
20
|
+
attr_accessor :max_runtime
|
21
|
+
|
22
|
+
# tz database style timezone string
|
23
|
+
# @return [String, nil]
|
24
|
+
attr_accessor :timezone
|
25
|
+
|
26
|
+
def initialize(schedule, checkin_margin: nil, max_runtime: nil, timezone: nil)
|
27
|
+
@schedule = schedule
|
28
|
+
@checkin_margin = checkin_margin
|
29
|
+
@max_runtime = max_runtime
|
30
|
+
@timezone = timezone
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.from_crontab(crontab, **options)
|
34
|
+
new(MonitorSchedule::Crontab.new(crontab), **options)
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.from_interval(num, unit, **options)
|
38
|
+
return nil unless MonitorSchedule::Interval::VALID_UNITS.include?(unit)
|
39
|
+
|
40
|
+
new(MonitorSchedule::Interval.new(num, unit), **options)
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_hash
|
44
|
+
{
|
45
|
+
schedule: schedule.to_hash,
|
46
|
+
checkin_margin: checkin_margin,
|
47
|
+
max_runtime: max_runtime,
|
48
|
+
timezone: timezone
|
49
|
+
}.compact
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sentry
|
4
|
+
module Cron
|
5
|
+
module MonitorSchedule
|
6
|
+
class Crontab
|
7
|
+
# A crontab formatted string such as "0 * * * *".
|
8
|
+
# @return [String]
|
9
|
+
attr_accessor :value
|
10
|
+
|
11
|
+
def initialize(value)
|
12
|
+
@value = value
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_hash
|
16
|
+
{ type: :crontab, value: value }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Interval
|
21
|
+
# The number representing duration of the interval.
|
22
|
+
# @return [Integer]
|
23
|
+
attr_accessor :value
|
24
|
+
|
25
|
+
# The unit representing duration of the interval.
|
26
|
+
# @return [Symbol]
|
27
|
+
attr_accessor :unit
|
28
|
+
|
29
|
+
VALID_UNITS = %i(year month week day hour minute)
|
30
|
+
|
31
|
+
def initialize(value, unit)
|
32
|
+
@value = value
|
33
|
+
@unit = unit
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_hash
|
37
|
+
{ type: :interval, value: value, unit: unit }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/sentry/envelope.rb
CHANGED
@@ -5,7 +5,7 @@ module Sentry
|
|
5
5
|
class Envelope
|
6
6
|
class Item
|
7
7
|
STACKTRACE_FRAME_LIMIT_ON_OVERSIZED_PAYLOAD = 500
|
8
|
-
MAX_SERIALIZED_PAYLOAD_SIZE = 1024 *
|
8
|
+
MAX_SERIALIZED_PAYLOAD_SIZE = 1024 * 1000
|
9
9
|
|
10
10
|
attr_accessor :headers, :payload
|
11
11
|
|
@@ -19,10 +19,7 @@ module Sentry
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def to_s
|
22
|
-
|
23
|
-
#{JSON.generate(@headers)}
|
24
|
-
#{JSON.generate(@payload)}
|
25
|
-
ITEM
|
22
|
+
[JSON.generate(@headers), JSON.generate(@payload)].join("\n")
|
26
23
|
end
|
27
24
|
|
28
25
|
def serialize
|
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
|
|
@@ -37,6 +37,11 @@ module Sentry
|
|
37
37
|
# @return [RequestInterface]
|
38
38
|
attr_reader :request
|
39
39
|
|
40
|
+
# Dynamic Sampling Context (DSC) that gets attached
|
41
|
+
# as the trace envelope header in the transport.
|
42
|
+
# @return [Hash, nil]
|
43
|
+
attr_accessor :dynamic_sampling_context
|
44
|
+
|
40
45
|
# @param configuration [Configuration]
|
41
46
|
# @param integration_meta [Hash, nil]
|
42
47
|
# @param message [String, nil]
|
@@ -54,6 +59,7 @@ module Sentry
|
|
54
59
|
@tags = {}
|
55
60
|
|
56
61
|
@fingerprint = []
|
62
|
+
@dynamic_sampling_context = nil
|
57
63
|
|
58
64
|
# configuration data that's directly used by events
|
59
65
|
@server_name = configuration.server_name
|
@@ -70,34 +76,6 @@ module Sentry
|
|
70
76
|
@message = (message || "").byteslice(0..MAX_MESSAGE_SIZE_IN_BYTES)
|
71
77
|
end
|
72
78
|
|
73
|
-
class << self
|
74
|
-
# @!visibility private
|
75
|
-
def get_log_message(event_hash)
|
76
|
-
message = event_hash[:message] || event_hash['message']
|
77
|
-
|
78
|
-
return message unless message.nil? || message.empty?
|
79
|
-
|
80
|
-
message = get_message_from_exception(event_hash)
|
81
|
-
|
82
|
-
return message unless message.nil? || message.empty?
|
83
|
-
|
84
|
-
message = event_hash[:transaction] || event_hash["transaction"]
|
85
|
-
|
86
|
-
return message unless message.nil? || message.empty?
|
87
|
-
|
88
|
-
'<no message value>'
|
89
|
-
end
|
90
|
-
|
91
|
-
# @!visibility private
|
92
|
-
def get_message_from_exception(event_hash)
|
93
|
-
if exception = event_hash.dig(:exception, :values, 0)
|
94
|
-
"#{exception[:type]}: #{exception[:value]}"
|
95
|
-
elsif exception = event_hash.dig("exception", "values", 0)
|
96
|
-
"#{exception["type"]}: #{exception["value"]}"
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
79
|
# @deprecated This method will be removed in v5.0.0. Please just use Sentry.configuration
|
102
80
|
# @return [Configuration]
|
103
81
|
def configuration
|