sentry-ruby 5.22.3 → 5.23.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: 6efd6e1590191762ede29567335f21b5e54ff63bb85c26e586ecc5e3ce8c5f2a
4
- data.tar.gz: d7758ef8b065a2b772ccebec8eee4807683a002495ca55dab7e85f8c1b92768f
3
+ metadata.gz: '09ca0c97390e688d58572ffe3ae022523a1003a48ccea319857b302b3e1ebb95'
4
+ data.tar.gz: 28f154fb38f21c50090dc8ae3c2bc7b335f288a298e97d934a24db1b8e7ac372
5
5
  SHA512:
6
- metadata.gz: 126c7238fb1dbd17f80986824bbd73eab5fba5a70b1f39a87cc59ff7fafb52474b3eb5b9b8043af03b3049acdf2ac1b322c572c652edee015aa7cabeb1d5c61a
7
- data.tar.gz: 5f6777c874b1544eab2e47359d61d1eb6cd725b6f1788e2595815e8340d1291e7da7632373c77635ebe717e8c75537a9157a0a904a90bdc1b518fb9819adb0e8
6
+ metadata.gz: 5f170fe27327a1753f4a6f2d62b5a694f30c91f1f86c4e2caa837d70467298ea2af261475a2da1045e3513257f3a9be4bb66a0c2e0dba271e43a1478ecd42c0b
7
+ data.tar.gz: 32a7f13e8eee4f7c8958dfd1a083aecf7ee306fec695703c5dbeff810e4ae5ebd84a1435e7edaef8a61d94eaf64910442422d2142007d77c5be31080ad32f244
data/Gemfile CHANGED
@@ -3,6 +3,8 @@
3
3
  source "https://rubygems.org"
4
4
  git_source(:github) { |name| "https://github.com/#{name}.git" }
5
5
 
6
+ eval_gemfile "../Gemfile"
7
+
6
8
  gem "sentry-ruby", path: "./"
7
9
 
8
10
  rack_version = ENV["RACK_VERSION"]
@@ -27,9 +29,8 @@ gem "benchmark_driver"
27
29
  gem "benchmark-ipsa"
28
30
  gem "benchmark-memory"
29
31
 
30
- gem "yard", github: "lsegal/yard"
32
+ gem "yard"
31
33
  gem "webrick"
32
34
  gem "faraday"
33
35
  gem "excon"
34
-
35
- eval_gemfile File.expand_path("../Gemfile", __dir__)
36
+ gem "webmock"
@@ -16,7 +16,7 @@ module Sentry
16
16
  /x
17
17
 
18
18
  # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:170)
19
- JAVA_INPUT_FORMAT = /^(.+)\.([^\.]+)\(([^\:]+)\:(\d+)\)$/
19
+ JAVA_INPUT_FORMAT = /^([\w$.]+)\.([\w$]+)\(([\w$.]+):(\d+)\)$/
20
20
 
21
21
  # The file portion of the line (such as app/models/user.rb)
22
22
  attr_reader :file
@@ -47,7 +47,7 @@ module Sentry
47
47
  # @param message [String]
48
48
  # @return [void]
49
49
  def message=(message)
50
- @message = (message || "").byteslice(0..Event::MAX_MESSAGE_SIZE_IN_BYTES)
50
+ @message = message ? message.byteslice(0..Event::MAX_MESSAGE_SIZE_IN_BYTES) : ""
51
51
  end
52
52
 
53
53
  # @param level [String]
data/lib/sentry/client.rb CHANGED
@@ -184,7 +184,7 @@ module Sentry
184
184
  event = configuration.before_send.call(event, hint)
185
185
 
186
186
  case event
187
- when ErrorEvent
187
+ when ErrorEvent, CheckInEvent
188
188
  # do nothing
189
189
  when Hash
190
190
  log_debug(<<~MSG)
@@ -264,6 +264,7 @@ module Sentry
264
264
 
265
265
  # Easier way to use performance tracing
266
266
  # If set to true, will set traces_sample_rate to 1.0
267
+ # @deprecated It will be removed in the next major release.
267
268
  # @return [Boolean, nil]
268
269
  attr_reader :enable_tracing
269
270
 
@@ -360,8 +361,47 @@ module Sentry
360
361
  def add_post_initialization_callback(&block)
361
362
  post_initialization_callbacks << block
362
363
  end
364
+
365
+ def validations
366
+ @validations ||= {}
367
+ end
368
+
369
+ def validate(attribute, optional: false, type: nil)
370
+ validations[attribute] = {
371
+ optional: optional,
372
+ type: type,
373
+ proc: build_validation_proc(optional, type)
374
+ }
375
+ end
376
+
377
+ private
378
+
379
+ def build_validation_proc(optional, type)
380
+ case type
381
+ when :numeric
382
+ ->(value) do
383
+ if optional && value.nil?
384
+ true
385
+ else
386
+ unless value.is_a?(Numeric)
387
+ message = "must be a Numeric"
388
+ message += " or nil" if optional
389
+
390
+ { error: message, value: value }
391
+ else
392
+ true
393
+ end
394
+ end
395
+ end
396
+ else
397
+ ->(value) { true }
398
+ end
399
+ end
363
400
  end
364
401
 
402
+ validate :traces_sample_rate, optional: true, type: :numeric
403
+ validate :profiles_sample_rate, optional: true, type: :numeric
404
+
365
405
  def initialize
366
406
  self.app_dirs_pattern = APP_DIRS_PATTERN
367
407
  self.debug = Sentry::Utils::EnvHelper.env_to_bool(ENV["SENTRY_DEBUG"])
@@ -417,6 +457,24 @@ module Sentry
417
457
  run_post_initialization_callbacks
418
458
  end
419
459
 
460
+ def validate
461
+ if profiler_class == Sentry::Profiler && profiles_sample_rate && !Sentry.dependency_installed?(:StackProf)
462
+ log_warn("Please add the 'stackprof' gem to your Gemfile to use the StackProf profiler with Sentry.")
463
+ end
464
+
465
+ if profiler_class == Sentry::Vernier::Profiler && profiles_sample_rate && !Sentry.dependency_installed?(:Vernier)
466
+ log_warn("Please add the 'vernier' gem to your Gemfile to use the Vernier profiler with Sentry.")
467
+ end
468
+
469
+ self.class.validations.each do |attribute, validation|
470
+ value = public_send(attribute)
471
+
472
+ next if (result = validation[:proc].call(value)) === true
473
+
474
+ raise ArgumentError, result[:error]
475
+ end
476
+ end
477
+
420
478
  def dsn=(value)
421
479
  @dsn = init_dsn(value)
422
480
  end
@@ -485,22 +543,21 @@ module Sentry
485
543
  end
486
544
 
487
545
  def enable_tracing=(enable_tracing)
546
+ unless enable_tracing.nil?
547
+ log_warn <<~MSG
548
+ `enable_tracing` is now deprecated in favor of `traces_sample_rate = 1.0`.
549
+ MSG
550
+ end
551
+
488
552
  @enable_tracing = enable_tracing
489
553
  @traces_sample_rate ||= 1.0 if enable_tracing
490
554
  end
491
555
 
492
- def is_numeric_or_nil?(value)
493
- value.is_a?(Numeric) || value.nil?
494
- end
495
-
496
556
  def traces_sample_rate=(traces_sample_rate)
497
- raise ArgumentError, "traces_sample_rate must be a Numeric or nil" unless is_numeric_or_nil?(traces_sample_rate)
498
557
  @traces_sample_rate = traces_sample_rate
499
558
  end
500
559
 
501
560
  def profiles_sample_rate=(profiles_sample_rate)
502
- raise ArgumentError, "profiles_sample_rate must be a Numeric or nil" unless is_numeric_or_nil?(profiles_sample_rate)
503
- log_warn("Please make sure to include the 'stackprof' gem in your Gemfile to use Profiling with Sentry.") unless defined?(StackProf)
504
561
  @profiles_sample_rate = profiles_sample_rate
505
562
  end
506
563
 
@@ -509,7 +566,6 @@ module Sentry
509
566
  begin
510
567
  require "vernier"
511
568
  rescue LoadError
512
- raise ArgumentError, "Please add the 'vernier' gem to your Gemfile to use the Vernier profiler with Sentry."
513
569
  end
514
570
  end
515
571
 
data/lib/sentry/hub.rb CHANGED
@@ -8,12 +8,42 @@ module Sentry
8
8
  class Hub
9
9
  include ArgumentCheckingHelper
10
10
 
11
+ MUTEX = Mutex.new
12
+
11
13
  attr_reader :last_event_id
12
14
 
15
+ attr_reader :current_profiler
16
+
13
17
  def initialize(client, scope)
14
18
  first_layer = Layer.new(client, scope)
15
19
  @stack = [first_layer]
16
20
  @last_event_id = nil
21
+ @current_profiler = {}
22
+ end
23
+
24
+ # This is an internal private method
25
+ # @api private
26
+ def start_profiler!(transaction)
27
+ MUTEX.synchronize do
28
+ transaction.start_profiler!
29
+ @current_profiler[transaction.__id__] = transaction.profiler
30
+ end
31
+ end
32
+
33
+ # This is an internal private method
34
+ # @api private
35
+ def stop_profiler!(transaction)
36
+ MUTEX.synchronize do
37
+ @current_profiler.delete(transaction.__id__)&.stop
38
+ end
39
+ end
40
+
41
+ # This is an internal private method
42
+ # @api private
43
+ def profiler_running?
44
+ MUTEX.synchronize do
45
+ !@current_profiler.empty?
46
+ end
17
47
  end
18
48
 
19
49
  def new_from_top
@@ -96,7 +126,7 @@ module Sentry
96
126
  sampling_context.merge!(custom_sampling_context)
97
127
  transaction.set_initial_sample_decision(sampling_context: sampling_context)
98
128
 
99
- transaction.start_profiler!
129
+ start_profiler!(transaction)
100
130
 
101
131
  transaction
102
132
  end
@@ -29,9 +29,9 @@ module Sentry
29
29
 
30
30
  def getlines(path)
31
31
  @cache[path] ||= begin
32
- IO.readlines(path)
33
- rescue
34
- nil
32
+ File.open(path, "r", &:readlines)
33
+ rescue
34
+ nil
35
35
  end
36
36
  end
37
37
 
@@ -83,5 +83,18 @@ module Sentry
83
83
  def extract_sentry_exceptions(event)
84
84
  event&.exception&.values || []
85
85
  end
86
+
87
+ def reset_sentry_globals!
88
+ Sentry::MUTEX.synchronize do
89
+ # Don't check initialized? because sometimes we stub it in tests
90
+ if Sentry.instance_variable_defined?(:@main_hub)
91
+ Sentry::GLOBALS.each do |var|
92
+ Sentry.instance_variable_set(:"@#{var}", nil)
93
+ end
94
+
95
+ Thread.current.thread_variable_set(Sentry::THREAD_LOCAL, nil)
96
+ end
97
+ end
98
+ end
86
99
  end
87
100
  end
@@ -85,7 +85,11 @@ module Sentry
85
85
  @effective_sample_rate = nil
86
86
  @contexts = {}
87
87
  @measurements = {}
88
- @profiler = @configuration.profiler_class.new(@configuration)
88
+
89
+ unless @hub.profiler_running?
90
+ @profiler = @configuration.profiler_class.new(@configuration)
91
+ end
92
+
89
93
  init_span_recorder
90
94
  end
91
95
 
@@ -257,7 +261,7 @@ module Sentry
257
261
  @name = UNLABELD_NAME
258
262
  end
259
263
 
260
- @profiler.stop
264
+ @hub.stop_profiler!(self)
261
265
 
262
266
  if @sampled
263
267
  event = hub.current_client.event_from_transaction(self)
@@ -299,6 +303,8 @@ module Sentry
299
303
  # Start the profiler.
300
304
  # @return [void]
301
305
  def start_profiler!
306
+ return unless profiler
307
+
302
308
  profiler.set_initial_sample_decision(sampled)
303
309
  profiler.start
304
310
  end
@@ -59,8 +59,11 @@ module Sentry
59
59
 
60
60
  private
61
61
 
62
+ EMPTY_PROFILE = {}.freeze
63
+
62
64
  def populate_profile(transaction)
63
- profile_hash = transaction.profiler.to_hash
65
+ profile_hash = transaction.profiler&.to_hash || EMPTY_PROFILE
66
+
64
67
  return if profile_hash.empty?
65
68
 
66
69
  profile_hash.merge!(
@@ -23,7 +23,6 @@ module Sentry
23
23
  Zlib::BufError, Errno::EHOSTUNREACH, Errno::ECONNREFUSED
24
24
  ].freeze
25
25
 
26
-
27
26
  def initialize(*args)
28
27
  super
29
28
  log_debug("Sentry HTTP Transport will connect to #{@dsn.server}") if @dsn
@@ -17,7 +17,7 @@ module Sentry
17
17
 
18
18
  def record_sentry_breadcrumb(request_info, response_status)
19
19
  crumb = Sentry::Breadcrumb.new(
20
- level: :info,
20
+ level: get_level(response_status),
21
21
  category: self.class::BREADCRUMB_CATEGORY,
22
22
  type: "info",
23
23
  data: { status: response_status, **request_info }
@@ -55,6 +55,20 @@ module Sentry
55
55
  "#{URI.encode_www_form_component(prefix)}=#{URI.encode_www_form_component(value)}"
56
56
  end
57
57
  end
58
+
59
+ private
60
+
61
+ def get_level(status)
62
+ return :info unless status && status.is_a?(Integer)
63
+
64
+ if status >= 500
65
+ :error
66
+ elsif status >= 400
67
+ :warning
68
+ else
69
+ :info
70
+ end
71
+ end
58
72
  end
59
73
  end
60
74
  end
@@ -74,6 +74,7 @@ module Sentry
74
74
  return unless @started
75
75
 
76
76
  @result = ::Vernier.stop_profile
77
+ @started = false
77
78
 
78
79
  log("Stopped")
79
80
  rescue RuntimeError => e
@@ -89,13 +90,13 @@ module Sentry
89
90
  end
90
91
 
91
92
  def to_hash
92
- return EMPTY_RESULT unless @started
93
-
94
93
  unless @sampled
95
94
  record_lost_event(:sample_rate)
96
95
  return EMPTY_RESULT
97
96
  end
98
97
 
98
+ return EMPTY_RESULT unless result
99
+
99
100
  { **profile_meta, profile: output.to_h }
100
101
  end
101
102
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sentry
4
- VERSION = "5.22.3"
4
+ VERSION = "5.23.0"
5
5
  end
data/lib/sentry-ruby.rb CHANGED
@@ -52,6 +52,14 @@ module Sentry
52
52
 
53
53
  MUTEX = Mutex.new
54
54
 
55
+ GLOBALS = %i[
56
+ main_hub
57
+ session_flusher
58
+ backpressure_monitor
59
+ metrics_aggregator
60
+ exception_locals_tp
61
+ ].freeze
62
+
55
63
  class << self
56
64
  # @!visibility private
57
65
  def exception_locals_tp
@@ -232,6 +240,7 @@ module Sentry
232
240
  yield(config) if block_given?
233
241
  config.detect_release
234
242
  apply_patches(config)
243
+ config.validate
235
244
  client = Client.new(config)
236
245
  scope = Scope.new(max_breadcrumbs: config.max_breadcrumbs)
237
246
  hub = Hub.new(client, scope)
@@ -608,6 +617,11 @@ module Sentry
608
617
  def utc_now
609
618
  Time.now.utc
610
619
  end
620
+
621
+ # @!visibility private
622
+ def dependency_installed?(name)
623
+ Object.const_defined?(name)
624
+ end
611
625
  end
612
626
  end
613
627
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sentry-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.22.3
4
+ version: 5.23.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sentry Team
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-01-29 00:00:00.000000000 Z
10
+ date: 2025-03-11 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: concurrent-ruby
@@ -150,15 +150,15 @@ files:
150
150
  - lib/sentry/version.rb
151
151
  - sentry-ruby-core.gemspec
152
152
  - sentry-ruby.gemspec
153
- homepage: https://github.com/getsentry/sentry-ruby/tree/5.22.3/sentry-ruby
153
+ homepage: https://github.com/getsentry/sentry-ruby/tree/5.23.0/sentry-ruby
154
154
  licenses:
155
155
  - MIT
156
156
  metadata:
157
- homepage_uri: https://github.com/getsentry/sentry-ruby/tree/5.22.3/sentry-ruby
158
- source_code_uri: https://github.com/getsentry/sentry-ruby/tree/5.22.3/sentry-ruby
159
- changelog_uri: https://github.com/getsentry/sentry-ruby/blob/5.22.3/CHANGELOG.md
157
+ homepage_uri: https://github.com/getsentry/sentry-ruby/tree/5.23.0/sentry-ruby
158
+ source_code_uri: https://github.com/getsentry/sentry-ruby/tree/5.23.0/sentry-ruby
159
+ changelog_uri: https://github.com/getsentry/sentry-ruby/blob/5.23.0/CHANGELOG.md
160
160
  bug_tracker_uri: https://github.com/getsentry/sentry-ruby/issues
161
- documentation_uri: http://www.rubydoc.info/gems/sentry-ruby/5.22.3
161
+ documentation_uri: http://www.rubydoc.info/gems/sentry-ruby/5.23.0
162
162
  rdoc_options: []
163
163
  require_paths:
164
164
  - lib