sentry-ruby 5.9.0 → 5.16.1
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/Gemfile +2 -10
- data/README.md +9 -9
- data/lib/sentry/background_worker.rb +8 -1
- data/lib/sentry/backpressure_monitor.rb +75 -0
- data/lib/sentry/breadcrumb.rb +8 -2
- data/lib/sentry/check_in_event.rb +60 -0
- data/lib/sentry/client.rb +48 -10
- data/lib/sentry/configuration.rb +89 -17
- 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 +1 -1
- data/lib/sentry/event.rb +6 -28
- data/lib/sentry/hub.rb +74 -2
- data/lib/sentry/integrable.rb +6 -0
- data/lib/sentry/interfaces/single_exception.rb +5 -3
- data/lib/sentry/net/http.rb +26 -20
- data/lib/sentry/profiler.rb +18 -7
- data/lib/sentry/propagation_context.rb +134 -0
- data/lib/sentry/puma.rb +11 -4
- data/lib/sentry/rack/capture_exceptions.rb +1 -4
- data/lib/sentry/rake.rb +0 -13
- data/lib/sentry/redis.rb +9 -3
- data/lib/sentry/release_detector.rb +1 -1
- data/lib/sentry/scope.rb +29 -13
- data/lib/sentry/span.rb +39 -2
- data/lib/sentry/test_helper.rb +18 -12
- data/lib/sentry/transaction.rb +18 -19
- data/lib/sentry/transaction_event.rb +0 -3
- 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 +21 -17
- data/lib/sentry/utils/argument_checking_helper.rb +9 -3
- data/lib/sentry/version.rb +1 -1
- data/lib/sentry-ruby.rb +83 -25
- metadata +10 -3
- data/CODE_OF_CONDUCT.md +0 -74
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 565289974a80625ef7ecac6926cfb7292569dfafd84f12584a8214619bdd5ed5
|
4
|
+
data.tar.gz: 005b3e5c27b7188058c412d36981779eb759f7be1032429eea17a2e4a7ffcb9f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d0e68db7961263d6aa070feaa131fae4c2039884e565cd248795298a99f08d66e7c921df1a6f6175e68ac0ed554185b4b94769f8b0fcba12d76e6aa042fc3359
|
7
|
+
data.tar.gz: 5e10f1406d7a7809aed02cef80e1d4355e61af54ed42ffd9a1b3a54a730229abfef4f0a690980c646757b93fffa6219d6500c5700b08a6eef61b6eb682d63620
|
data/Gemfile
CHANGED
@@ -12,19 +12,9 @@ gem "redis", "~> #{redis_rb_version}"
|
|
12
12
|
|
13
13
|
gem "puma"
|
14
14
|
|
15
|
-
gem "rake", "~> 12.0"
|
16
|
-
gem "rspec", "~> 3.0"
|
17
|
-
gem "rspec-retry"
|
18
15
|
gem "timecop"
|
19
|
-
gem "simplecov"
|
20
|
-
gem "simplecov-cobertura", "~> 1.4"
|
21
|
-
gem "rexml"
|
22
16
|
gem "stackprof" unless RUBY_PLATFORM == "java"
|
23
17
|
|
24
|
-
gem "object_tracer"
|
25
|
-
gem "debug", github: "ruby/debug", platform: :ruby if RUBY_VERSION.to_f >= 2.6
|
26
|
-
gem "pry"
|
27
|
-
|
28
18
|
gem "benchmark-ips"
|
29
19
|
gem "benchmark_driver"
|
30
20
|
gem "benchmark-ipsa"
|
@@ -32,3 +22,5 @@ gem "benchmark-memory"
|
|
32
22
|
|
33
23
|
gem "yard", github: "lsegal/yard"
|
34
24
|
gem "webrick"
|
25
|
+
|
26
|
+
eval_gemfile File.expand_path("../Gemfile", __dir__)
|
data/README.md
CHANGED
@@ -13,14 +13,14 @@ _Bad software is everywhere, and we're tired of it. Sentry is on a mission to he
|
|
13
13
|
Sentry SDK for Ruby
|
14
14
|
===========
|
15
15
|
|
16
|
-
| current version
|
17
|
-
| ---
|
18
|
-
| [](https://rubygems.org/gems/sentry-ruby)
|
19
|
-
| [](https://rubygems.org/gems/sentry-rails)
|
20
|
-
| [](https://rubygems.org/gems/sentry-sidekiq)
|
21
|
-
| [](https://rubygems.org/gems/sentry-delayed_job)
|
22
|
-
| [](https://rubygems.org/gems/sentry-resque)
|
23
|
-
| [](https://rubygems.org/gems/sentry-opentelemetry) | [](https://rubygems.org/gems/sentry-ruby) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_ruby_test.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [](https://rubygems.org/gems/sentry-ruby/) |
|
19
|
+
| [](https://rubygems.org/gems/sentry-rails) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_rails_test.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [](https://rubygems.org/gems/sentry-rails/) |
|
20
|
+
| [](https://rubygems.org/gems/sentry-sidekiq) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_sidekiq_test.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [](https://rubygems.org/gems/sentry-sidekiq/) |
|
21
|
+
| [](https://rubygems.org/gems/sentry-delayed_job) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_delayed_job_test.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [](https://rubygems.org/gems/sentry-delayed_job/) |
|
22
|
+
| [](https://rubygems.org/gems/sentry-resque) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_resque_test.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [](https://rubygems.org/gems/sentry-resque/) |
|
23
|
+
| [](https://rubygems.org/gems/sentry-opentelemetry) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_opentelemetry_test.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [](https://rubygems.org/gems/sentry-opentelemetry/) |
|
24
24
|
|
25
25
|
|
26
26
|
|
@@ -33,7 +33,7 @@ If you're using `sentry-raven`, we recommend you to migrate to this new SDK. You
|
|
33
33
|
|
34
34
|
## Requirements
|
35
35
|
|
36
|
-
We test
|
36
|
+
We test from Ruby 2.4 to Ruby 3.2 at the latest patchlevel/teeny version. We also support JRuby 9.0.
|
37
37
|
|
38
38
|
If you use self-hosted Sentry, please also make sure its version is above `20.6.0`.
|
39
39
|
|
@@ -13,10 +13,12 @@ module Sentry
|
|
13
13
|
attr_reader :logger
|
14
14
|
attr_accessor :shutdown_timeout
|
15
15
|
|
16
|
+
DEFAULT_MAX_QUEUE = 30
|
17
|
+
|
16
18
|
def initialize(configuration)
|
17
|
-
@max_queue = 30
|
18
19
|
@shutdown_timeout = 1
|
19
20
|
@number_of_threads = configuration.background_worker_threads
|
21
|
+
@max_queue = configuration.background_worker_max_queue
|
20
22
|
@logger = configuration.logger
|
21
23
|
@debug = configuration.debug
|
22
24
|
@shutdown_callback = nil
|
@@ -63,6 +65,11 @@ module Sentry
|
|
63
65
|
@shutdown_callback&.call
|
64
66
|
end
|
65
67
|
|
68
|
+
def full?
|
69
|
+
@executor.is_a?(Concurrent::ThreadPoolExecutor) &&
|
70
|
+
@executor.remaining_capacity == 0
|
71
|
+
end
|
72
|
+
|
66
73
|
private
|
67
74
|
|
68
75
|
def _perform(&block)
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sentry
|
4
|
+
class BackpressureMonitor
|
5
|
+
include LoggingHelper
|
6
|
+
|
7
|
+
DEFAULT_INTERVAL = 10
|
8
|
+
MAX_DOWNSAMPLE_FACTOR = 10
|
9
|
+
|
10
|
+
def initialize(configuration, client, interval: DEFAULT_INTERVAL)
|
11
|
+
@interval = interval
|
12
|
+
@client = client
|
13
|
+
@logger = configuration.logger
|
14
|
+
|
15
|
+
@thread = nil
|
16
|
+
@exited = false
|
17
|
+
|
18
|
+
@healthy = true
|
19
|
+
@downsample_factor = 0
|
20
|
+
end
|
21
|
+
|
22
|
+
def healthy?
|
23
|
+
ensure_thread
|
24
|
+
@healthy
|
25
|
+
end
|
26
|
+
|
27
|
+
def downsample_factor
|
28
|
+
ensure_thread
|
29
|
+
@downsample_factor
|
30
|
+
end
|
31
|
+
|
32
|
+
def run
|
33
|
+
check_health
|
34
|
+
set_downsample_factor
|
35
|
+
end
|
36
|
+
|
37
|
+
def check_health
|
38
|
+
@healthy = !(@client.transport.any_rate_limited? || Sentry.background_worker&.full?)
|
39
|
+
end
|
40
|
+
|
41
|
+
def set_downsample_factor
|
42
|
+
if @healthy
|
43
|
+
log_debug("[BackpressureMonitor] health check positive, reverting to normal sampling") if @downsample_factor.positive?
|
44
|
+
@downsample_factor = 0
|
45
|
+
else
|
46
|
+
@downsample_factor += 1 if @downsample_factor < MAX_DOWNSAMPLE_FACTOR
|
47
|
+
log_debug("[BackpressureMonitor] health check negative, downsampling with a factor of #{@downsample_factor}")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def kill
|
52
|
+
log_debug("[BackpressureMonitor] killing monitor")
|
53
|
+
|
54
|
+
@exited = true
|
55
|
+
@thread&.kill
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def ensure_thread
|
61
|
+
return if @exited
|
62
|
+
return if @thread&.alive?
|
63
|
+
|
64
|
+
@thread = Thread.new do
|
65
|
+
loop do
|
66
|
+
sleep(@interval)
|
67
|
+
run
|
68
|
+
end
|
69
|
+
end
|
70
|
+
rescue ThreadError
|
71
|
+
log_debug("[BackpressureMonitor] Thread creation failed")
|
72
|
+
@exited = true
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/sentry/breadcrumb.rb
CHANGED
@@ -9,7 +9,7 @@ module Sentry
|
|
9
9
|
# @return [Hash, nil]
|
10
10
|
attr_accessor :data
|
11
11
|
# @return [String, nil]
|
12
|
-
|
12
|
+
attr_reader :level
|
13
13
|
# @return [Time, Integer, nil]
|
14
14
|
attr_accessor :timestamp
|
15
15
|
# @return [String, nil]
|
@@ -26,10 +26,10 @@ module Sentry
|
|
26
26
|
def initialize(category: nil, data: nil, message: nil, timestamp: nil, level: nil, type: nil)
|
27
27
|
@category = category
|
28
28
|
@data = data || {}
|
29
|
-
@level = level
|
30
29
|
@timestamp = timestamp || Sentry.utc_now.to_i
|
31
30
|
@type = type
|
32
31
|
self.message = message
|
32
|
+
self.level = level
|
33
33
|
end
|
34
34
|
|
35
35
|
# @return [Hash]
|
@@ -50,6 +50,12 @@ module Sentry
|
|
50
50
|
@message = (message || "").byteslice(0..Event::MAX_MESSAGE_SIZE_IN_BYTES)
|
51
51
|
end
|
52
52
|
|
53
|
+
# @param level [String]
|
54
|
+
# @return [void]
|
55
|
+
def level=(level) # needed to meet the Sentry spec
|
56
|
+
@level = level == "warn" ? "warning" : level
|
57
|
+
end
|
58
|
+
|
53
59
|
private
|
54
60
|
|
55
61
|
def serialized_data
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'securerandom'
|
4
|
+
require 'sentry/cron/monitor_config'
|
5
|
+
|
6
|
+
module Sentry
|
7
|
+
class CheckInEvent < Event
|
8
|
+
TYPE = 'check_in'
|
9
|
+
|
10
|
+
# uuid to identify this check-in.
|
11
|
+
# @return [String]
|
12
|
+
attr_accessor :check_in_id
|
13
|
+
|
14
|
+
# Identifier of the monitor for this check-in.
|
15
|
+
# @return [String]
|
16
|
+
attr_accessor :monitor_slug
|
17
|
+
|
18
|
+
# Duration of this check since it has started in seconds.
|
19
|
+
# @return [Integer, nil]
|
20
|
+
attr_accessor :duration
|
21
|
+
|
22
|
+
# Monitor configuration to support upserts.
|
23
|
+
# @return [Cron::MonitorConfig, nil]
|
24
|
+
attr_accessor :monitor_config
|
25
|
+
|
26
|
+
# Status of this check-in.
|
27
|
+
# @return [Symbol]
|
28
|
+
attr_accessor :status
|
29
|
+
|
30
|
+
VALID_STATUSES = %i(ok in_progress error)
|
31
|
+
|
32
|
+
def initialize(
|
33
|
+
slug:,
|
34
|
+
status:,
|
35
|
+
duration: nil,
|
36
|
+
monitor_config: nil,
|
37
|
+
check_in_id: nil,
|
38
|
+
**options
|
39
|
+
)
|
40
|
+
super(**options)
|
41
|
+
|
42
|
+
self.monitor_slug = slug
|
43
|
+
self.status = status
|
44
|
+
self.duration = duration
|
45
|
+
self.monitor_config = monitor_config
|
46
|
+
self.check_in_id = check_in_id || SecureRandom.uuid.delete('-')
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [Hash]
|
50
|
+
def to_hash
|
51
|
+
data = super
|
52
|
+
data[:check_in_id] = check_in_id
|
53
|
+
data[:monitor_slug] = monitor_slug
|
54
|
+
data[:status] = status
|
55
|
+
data[:duration] = duration if duration
|
56
|
+
data[:monitor_config] = monitor_config.to_hash if monitor_config
|
57
|
+
data
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/sentry/client.rb
CHANGED
@@ -10,6 +10,10 @@ module Sentry
|
|
10
10
|
# @return [Transport]
|
11
11
|
attr_reader :transport
|
12
12
|
|
13
|
+
# The Transport object that'll send events for the client.
|
14
|
+
# @return [SpotlightTransport, nil]
|
15
|
+
attr_reader :spotlight_transport
|
16
|
+
|
13
17
|
# @!macro configuration
|
14
18
|
attr_reader :configuration
|
15
19
|
|
@@ -32,6 +36,8 @@ module Sentry
|
|
32
36
|
DummyTransport.new(configuration)
|
33
37
|
end
|
34
38
|
end
|
39
|
+
|
40
|
+
@spotlight_transport = SpotlightTransport.new(configuration) if configuration.spotlight
|
35
41
|
end
|
36
42
|
|
37
43
|
# Applies the given scope's data to the event and sends it to Sentry.
|
@@ -42,7 +48,7 @@ module Sentry
|
|
42
48
|
def capture_event(event, scope, hint = {})
|
43
49
|
return unless configuration.sending_allowed?
|
44
50
|
|
45
|
-
|
51
|
+
if event.is_a?(ErrorEvent) && !configuration.sample_allowed?
|
46
52
|
transport.record_lost_event(:sample_rate, 'event')
|
47
53
|
return
|
48
54
|
end
|
@@ -51,7 +57,7 @@ module Sentry
|
|
51
57
|
event = scope.apply_to_event(event, hint)
|
52
58
|
|
53
59
|
if event.nil?
|
54
|
-
|
60
|
+
log_debug("Discarded event because one of the event processors returned nil")
|
55
61
|
transport.record_lost_event(:event_processor, event_type)
|
56
62
|
return
|
57
63
|
end
|
@@ -104,6 +110,37 @@ module Sentry
|
|
104
110
|
event
|
105
111
|
end
|
106
112
|
|
113
|
+
# Initializes a CheckInEvent object with the given options.
|
114
|
+
#
|
115
|
+
# @param slug [String] identifier of this monitor
|
116
|
+
# @param status [Symbol] status of this check-in, one of {CheckInEvent::VALID_STATUSES}
|
117
|
+
# @param hint [Hash] the hint data that'll be passed to `before_send` callback and the scope's event processors.
|
118
|
+
# @param duration [Integer, nil] seconds elapsed since this monitor started
|
119
|
+
# @param monitor_config [Cron::MonitorConfig, nil] configuration for this monitor
|
120
|
+
# @param check_in_id [String, nil] for updating the status of an existing monitor
|
121
|
+
#
|
122
|
+
# @return [Event]
|
123
|
+
def event_from_check_in(
|
124
|
+
slug,
|
125
|
+
status,
|
126
|
+
hint = {},
|
127
|
+
duration: nil,
|
128
|
+
monitor_config: nil,
|
129
|
+
check_in_id: nil
|
130
|
+
)
|
131
|
+
return unless configuration.sending_allowed?
|
132
|
+
|
133
|
+
CheckInEvent.new(
|
134
|
+
configuration: configuration,
|
135
|
+
integration_meta: Sentry.integrations[hint[:integration]],
|
136
|
+
slug: slug,
|
137
|
+
status: status,
|
138
|
+
duration: duration,
|
139
|
+
monitor_config: monitor_config,
|
140
|
+
check_in_id: check_in_id
|
141
|
+
)
|
142
|
+
end
|
143
|
+
|
107
144
|
# Initializes an Event object with the given Transaction object.
|
108
145
|
# @param transaction [Transaction] the transaction to be recorded.
|
109
146
|
# @return [TransactionEvent]
|
@@ -119,7 +156,7 @@ module Sentry
|
|
119
156
|
event = configuration.before_send.call(event, hint)
|
120
157
|
|
121
158
|
if event.nil?
|
122
|
-
|
159
|
+
log_debug("Discarded event because before_send returned nil")
|
123
160
|
transport.record_lost_event(:before_send, 'event')
|
124
161
|
return
|
125
162
|
end
|
@@ -129,25 +166,24 @@ module Sentry
|
|
129
166
|
event = configuration.before_send_transaction.call(event, hint)
|
130
167
|
|
131
168
|
if event.nil?
|
132
|
-
|
169
|
+
log_debug("Discarded event because before_send_transaction returned nil")
|
133
170
|
transport.record_lost_event(:before_send, 'transaction')
|
134
171
|
return
|
135
172
|
end
|
136
173
|
end
|
137
174
|
|
138
175
|
transport.send_event(event)
|
176
|
+
spotlight_transport&.send_event(event)
|
139
177
|
|
140
178
|
event
|
141
179
|
rescue => e
|
142
|
-
|
143
|
-
log_error("#{loggable_event_type} sending failed", e, debug: configuration.debug)
|
144
|
-
|
145
|
-
event_info = Event.get_log_message(event.to_hash)
|
146
|
-
log_info("Unreported #{loggable_event_type}: #{event_info}")
|
180
|
+
log_error("Event sending failed", e, debug: configuration.debug)
|
147
181
|
transport.record_lost_event(:network_error, event_type)
|
148
182
|
raise
|
149
183
|
end
|
150
184
|
|
185
|
+
# @deprecated use Sentry.get_traceparent instead.
|
186
|
+
#
|
151
187
|
# Generates a Sentry trace for distribted tracing from the given Span.
|
152
188
|
# Returns `nil` if `config.propagate_traces` is `false`.
|
153
189
|
# @param span [Span] the span to generate trace from.
|
@@ -160,7 +196,9 @@ module Sentry
|
|
160
196
|
trace
|
161
197
|
end
|
162
198
|
|
163
|
-
#
|
199
|
+
# @deprecated Use Sentry.get_baggage instead.
|
200
|
+
#
|
201
|
+
# Generates a W3C Baggage header for distributed tracing from the given Span.
|
164
202
|
# Returns `nil` if `config.propagate_traces` is `false`.
|
165
203
|
# @param span [Span] the span to generate trace from.
|
166
204
|
# @return [String, nil]
|
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
|
#
|
@@ -140,6 +150,14 @@ module Sentry
|
|
140
150
|
# @return [Boolean]
|
141
151
|
attr_accessor :include_local_variables
|
142
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
|
+
|
143
161
|
# @deprecated Use {#include_local_variables} instead.
|
144
162
|
alias_method :capture_exception_frame_locals, :include_local_variables
|
145
163
|
|
@@ -179,7 +197,7 @@ module Sentry
|
|
179
197
|
# Release tag to be passed with every event sent to Sentry.
|
180
198
|
# We automatically try to set this to a git SHA or Capistrano release.
|
181
199
|
# @return [String]
|
182
|
-
|
200
|
+
attr_reader :release
|
183
201
|
|
184
202
|
# The sampling factor to apply to events. A value of 0.0 will not send
|
185
203
|
# any events, and a value of 1.0 will send 100% of events.
|
@@ -209,13 +227,17 @@ module Sentry
|
|
209
227
|
# @return [String]
|
210
228
|
attr_accessor :server_name
|
211
229
|
|
212
|
-
#
|
213
|
-
# @return [Transport]
|
230
|
+
# Transport related configuration.
|
231
|
+
# @return [Transport::Configuration]
|
214
232
|
attr_reader :transport
|
215
233
|
|
234
|
+
# Cron related configuration.
|
235
|
+
# @return [Cron::Configuration]
|
236
|
+
attr_reader :cron
|
237
|
+
|
216
238
|
# Take a float between 0.0 and 1.0 as the sample rate for tracing events (transactions).
|
217
|
-
# @return [Float]
|
218
|
-
|
239
|
+
# @return [Float, nil]
|
240
|
+
attr_reader :traces_sample_rate
|
219
241
|
|
220
242
|
# Take a Proc that controls the sample rate for every tracing event, e.g.
|
221
243
|
# @example
|
@@ -241,6 +263,17 @@ module Sentry
|
|
241
263
|
# @return [Boolean]
|
242
264
|
attr_accessor :auto_session_tracking
|
243
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
|
+
|
244
277
|
# The instrumenter to use, :sentry or :otel
|
245
278
|
# @return [Symbol]
|
246
279
|
attr_reader :instrumenter
|
@@ -251,10 +284,24 @@ module Sentry
|
|
251
284
|
# @return [Float, nil]
|
252
285
|
attr_reader :profiles_sample_rate
|
253
286
|
|
287
|
+
# Array of patches to apply.
|
288
|
+
# Default is {DEFAULT_PATCHES}
|
289
|
+
# @return [Array<Symbol>]
|
290
|
+
attr_accessor :enabled_patches
|
291
|
+
|
254
292
|
# these are not config options
|
255
293
|
# @!visibility private
|
256
294
|
attr_reader :errors, :gem_specs
|
257
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
|
+
|
258
305
|
# Most of these errors generate 4XX responses. In general, Sentry clients
|
259
306
|
# only automatically report 5xx responses.
|
260
307
|
IGNORE_DEFAULT = [
|
@@ -279,6 +326,10 @@ module Sentry
|
|
279
326
|
|
280
327
|
INSTRUMENTERS = [:sentry, :otel]
|
281
328
|
|
329
|
+
PROPAGATION_TARGETS_MATCH_ALL = /.*/.freeze
|
330
|
+
|
331
|
+
DEFAULT_PATCHES = %i(redis puma http).freeze
|
332
|
+
|
282
333
|
class << self
|
283
334
|
# Post initialization callbacks are called at the end of initialization process
|
284
335
|
# allowing extending the configuration of sentry-ruby by multiple extensions
|
@@ -296,6 +347,7 @@ module Sentry
|
|
296
347
|
self.app_dirs_pattern = nil
|
297
348
|
self.debug = false
|
298
349
|
self.background_worker_threads = Concurrent.processor_count
|
350
|
+
self.background_worker_max_queue = BackgroundWorker::DEFAULT_MAX_QUEUE
|
299
351
|
self.backtrace_cleanup_callback = nil
|
300
352
|
self.max_breadcrumbs = BreadcrumbBuffer::DEFAULT_SIZE
|
301
353
|
self.breadcrumbs_logger = []
|
@@ -304,7 +356,7 @@ module Sentry
|
|
304
356
|
self.environment = environment_from_env
|
305
357
|
self.enabled_environments = []
|
306
358
|
self.exclude_loggers = []
|
307
|
-
self.excluded_exceptions = IGNORE_DEFAULT
|
359
|
+
self.excluded_exceptions = IGNORE_DEFAULT + PUMA_IGNORE_DEFAULT
|
308
360
|
self.inspect_exception_causes_for_exclusion = true
|
309
361
|
self.linecache = ::Sentry::LineCache.new
|
310
362
|
self.logger = ::Sentry::Logger.new(STDOUT)
|
@@ -317,19 +369,23 @@ module Sentry
|
|
317
369
|
self.skip_rake_integration = false
|
318
370
|
self.send_client_reports = true
|
319
371
|
self.auto_session_tracking = true
|
372
|
+
self.enable_backpressure_handling = false
|
320
373
|
self.trusted_proxies = []
|
321
374
|
self.dsn = ENV['SENTRY_DSN']
|
375
|
+
self.spotlight = false
|
322
376
|
self.server_name = server_name_from_env
|
323
377
|
self.instrumenter = :sentry
|
378
|
+
self.trace_propagation_targets = [PROPAGATION_TARGETS_MATCH_ALL]
|
379
|
+
self.enabled_patches = DEFAULT_PATCHES.dup
|
324
380
|
|
325
381
|
self.before_send = nil
|
326
382
|
self.before_send_transaction = nil
|
327
383
|
self.rack_env_whitelist = RACK_ENV_WHITELIST_DEFAULT
|
328
|
-
self.traces_sample_rate = nil
|
329
384
|
self.traces_sampler = nil
|
330
385
|
self.enable_tracing = nil
|
331
386
|
|
332
387
|
@transport = Transport::Configuration.new
|
388
|
+
@cron = Cron::Configuration.new
|
333
389
|
@gem_specs = Hash[Gem::Specification.map { |spec| [spec.name, spec.version.to_s] }] if Gem::Specification.respond_to?(:map)
|
334
390
|
|
335
391
|
run_post_initialization_callbacks
|
@@ -341,6 +397,12 @@ module Sentry
|
|
341
397
|
|
342
398
|
alias server= dsn=
|
343
399
|
|
400
|
+
def release=(value)
|
401
|
+
check_argument_type!(value, String, NilClass)
|
402
|
+
|
403
|
+
@release = value
|
404
|
+
end
|
405
|
+
|
344
406
|
def async=(value)
|
345
407
|
check_callable!("async", value)
|
346
408
|
|
@@ -401,15 +463,25 @@ module Sentry
|
|
401
463
|
@traces_sample_rate ||= 1.0 if enable_tracing
|
402
464
|
end
|
403
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
|
+
|
404
475
|
def profiles_sample_rate=(profiles_sample_rate)
|
405
|
-
|
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)
|
406
478
|
@profiles_sample_rate = profiles_sample_rate
|
407
479
|
end
|
408
480
|
|
409
481
|
def sending_allowed?
|
410
482
|
@errors = []
|
411
483
|
|
412
|
-
valid? && capture_in_environment?
|
484
|
+
spotlight || (valid? && capture_in_environment?)
|
413
485
|
end
|
414
486
|
|
415
487
|
def sample_allowed?
|
@@ -435,19 +507,19 @@ module Sentry
|
|
435
507
|
enabled_environments.empty? || enabled_environments.include?(environment)
|
436
508
|
end
|
437
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
|
+
|
438
515
|
def tracing_enabled?
|
439
|
-
valid_sampler = !!((@traces_sample_rate
|
440
|
-
@traces_sample_rate >= 0.0 &&
|
441
|
-
@traces_sample_rate <= 1.0) ||
|
442
|
-
@traces_sampler)
|
516
|
+
valid_sampler = !!((valid_sample_rate?(@traces_sample_rate)) || @traces_sampler)
|
443
517
|
|
444
518
|
(@enable_tracing != false) && valid_sampler && sending_allowed?
|
445
519
|
end
|
446
520
|
|
447
521
|
def profiling_enabled?
|
448
|
-
valid_sampler = !!(@profiles_sample_rate
|
449
|
-
@profiles_sample_rate >= 0.0 &&
|
450
|
-
@profiles_sample_rate <= 1.0)
|
522
|
+
valid_sampler = !!(valid_sample_rate?(@profiles_sample_rate))
|
451
523
|
|
452
524
|
tracing_enabled? && valid_sampler && sending_allowed?
|
453
525
|
end
|
@@ -477,7 +549,7 @@ module Sentry
|
|
477
549
|
def detect_release
|
478
550
|
return unless sending_allowed?
|
479
551
|
|
480
|
-
|
552
|
+
@release ||= ReleaseDetector.detect_release(project_root: project_root, running_on_heroku: running_on_heroku?)
|
481
553
|
|
482
554
|
if running_on_heroku? && release.nil?
|
483
555
|
log_warn(HEROKU_DYNO_METADATA_MESSAGE)
|
@@ -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
|