sentry-ruby 5.8.0 → 5.12.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/Gemfile +14 -2
- data/README.md +8 -8
- data/Rakefile +8 -1
- data/lib/sentry/backtrace.rb +1 -1
- data/lib/sentry/baggage.rb +1 -12
- data/lib/sentry/check_in_event.rb +60 -0
- data/lib/sentry/client.rb +40 -2
- data/lib/sentry/configuration.rb +76 -7
- data/lib/sentry/cron/monitor_check_ins.rb +61 -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 +6 -0
- data/lib/sentry/hub.rb +78 -3
- data/lib/sentry/integrable.rb +6 -0
- data/lib/sentry/interfaces/single_exception.rb +4 -3
- data/lib/sentry/net/http.rb +21 -22
- data/lib/sentry/profiler.rb +233 -0
- data/lib/sentry/propagation_context.rb +134 -0
- data/lib/sentry/puma.rb +25 -0
- data/lib/sentry/rack/capture_exceptions.rb +1 -4
- data/lib/sentry/redis.rb +6 -7
- data/lib/sentry/scope.rb +23 -3
- data/lib/sentry/span.rb +39 -2
- data/lib/sentry/test_helper.rb +18 -12
- data/lib/sentry/transaction.rb +24 -17
- data/lib/sentry/transaction_event.rb +30 -3
- data/lib/sentry/transport.rb +11 -3
- data/lib/sentry/utils/argument_checking_helper.rb +9 -3
- data/lib/sentry/version.rb +1 -1
- data/lib/sentry-ruby.rb +69 -2
- metadata +9 -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: 857c6d99b1c5d9378a2522ffa1e466f91869500ae425f9d1add4aae399f1852c
|
4
|
+
data.tar.gz: 726793c0ae09ce3b137cdc7f48f6745c55176a83c8f651b8b493ee5d1290b522
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 13ccb78050835c829d738550bc9838347c71abc2139089c29ab466796059259740207d21504bee7cc6f4ca07dbcc982e12be05ebc0b955a4274a4a30bd0470ee
|
7
|
+
data.tar.gz: d6b4edd6c562b787b9fe652b6ba6ddb3bf16bca937bacbd22fcc44be746643a77e3595460263f72e3e76e73a7b92ff09577d7c665cfac2520886c3a62a62a2ab
|
data/Gemfile
CHANGED
@@ -10,6 +10,8 @@ gem "rack", "~> #{Gem::Version.new(rack_version)}" unless rack_version == "0"
|
|
10
10
|
redis_rb_version = ENV.fetch("REDIS_RB_VERSION", "5.0")
|
11
11
|
gem "redis", "~> #{redis_rb_version}"
|
12
12
|
|
13
|
+
gem "puma"
|
14
|
+
|
13
15
|
gem "rake", "~> 12.0"
|
14
16
|
gem "rspec", "~> 3.0"
|
15
17
|
gem "rspec-retry"
|
@@ -17,9 +19,19 @@ gem "timecop"
|
|
17
19
|
gem "simplecov"
|
18
20
|
gem "simplecov-cobertura", "~> 1.4"
|
19
21
|
gem "rexml"
|
22
|
+
gem "stackprof" unless RUBY_PLATFORM == "java"
|
23
|
+
|
24
|
+
ruby_version = Gem::Version.new(RUBY_VERSION)
|
25
|
+
|
26
|
+
if ruby_version >= Gem::Version.new("2.6.0")
|
27
|
+
gem "debug", github: "ruby/debug", platform: :ruby
|
28
|
+
gem "irb"
|
29
|
+
|
30
|
+
if ruby_version >= Gem::Version.new("3.0.0")
|
31
|
+
gem "ruby-lsp-rspec"
|
32
|
+
end
|
33
|
+
end
|
20
34
|
|
21
|
-
gem "object_tracer"
|
22
|
-
gem "debug", github: "ruby/debug", platform: :ruby if RUBY_VERSION.to_f >= 2.6
|
23
35
|
gem "pry"
|
24
36
|
|
25
37
|
gem "benchmark-ips"
|
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
|
|
data/Rakefile
CHANGED
@@ -8,6 +8,13 @@ require "rspec/core/rake_task"
|
|
8
8
|
|
9
9
|
RSpec::Core::RakeTask.new(:spec).tap do |task|
|
10
10
|
task.rspec_opts = "--order rand"
|
11
|
+
task.exclude_pattern = "spec/isolated/**/*_spec.rb"
|
11
12
|
end
|
12
13
|
|
13
|
-
task :
|
14
|
+
task :isolated_specs do
|
15
|
+
Dir["spec/isolated/*"].each do |file|
|
16
|
+
sh "bundle exec rspec #{file}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
task :default => [:spec, :isolated_specs]
|
data/lib/sentry/backtrace.rb
CHANGED
data/lib/sentry/baggage.rb
CHANGED
@@ -8,17 +8,6 @@ module Sentry
|
|
8
8
|
SENTRY_PREFIX = 'sentry-'
|
9
9
|
SENTRY_PREFIX_REGEX = /^sentry-/.freeze
|
10
10
|
|
11
|
-
DSC_KEYS = %w(
|
12
|
-
trace_id
|
13
|
-
public_key
|
14
|
-
sample_rate
|
15
|
-
release
|
16
|
-
environment
|
17
|
-
transaction
|
18
|
-
user_id
|
19
|
-
user_segment
|
20
|
-
).freeze
|
21
|
-
|
22
11
|
# @return [Hash]
|
23
12
|
attr_reader :items
|
24
13
|
|
@@ -68,7 +57,7 @@ module Sentry
|
|
68
57
|
# hash to be used in the trace envelope header.
|
69
58
|
# @return [Hash]
|
70
59
|
def dynamic_sampling_context
|
71
|
-
@items
|
60
|
+
@items
|
72
61
|
end
|
73
62
|
|
74
63
|
# Serialize the Baggage object back to a string.
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal
|
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
@@ -76,7 +76,10 @@ module Sentry
|
|
76
76
|
# @param hint [Hash] the hint data that'll be passed to `before_send` callback and the scope's event processors.
|
77
77
|
# @return [Event, nil]
|
78
78
|
def event_from_exception(exception, hint = {})
|
79
|
-
return unless @configuration.sending_allowed?
|
79
|
+
return unless @configuration.sending_allowed?
|
80
|
+
|
81
|
+
ignore_exclusions = hint.delete(:ignore_exclusions) { false }
|
82
|
+
return if !ignore_exclusions && !@configuration.exception_class_allowed?(exception)
|
80
83
|
|
81
84
|
integration_meta = Sentry.integrations[hint[:integration]]
|
82
85
|
|
@@ -101,6 +104,37 @@ module Sentry
|
|
101
104
|
event
|
102
105
|
end
|
103
106
|
|
107
|
+
# Initializes a CheckInEvent object with the given options.
|
108
|
+
#
|
109
|
+
# @param slug [String] identifier of this monitor
|
110
|
+
# @param status [Symbol] status of this check-in, one of {CheckInEvent::VALID_STATUSES}
|
111
|
+
# @param hint [Hash] the hint data that'll be passed to `before_send` callback and the scope's event processors.
|
112
|
+
# @param duration [Integer, nil] seconds elapsed since this monitor started
|
113
|
+
# @param monitor_config [Cron::MonitorConfig, nil] configuration for this monitor
|
114
|
+
# @param check_in_id [String, nil] for updating the status of an existing monitor
|
115
|
+
#
|
116
|
+
# @return [Event]
|
117
|
+
def event_from_check_in(
|
118
|
+
slug,
|
119
|
+
status,
|
120
|
+
hint = {},
|
121
|
+
duration: nil,
|
122
|
+
monitor_config: nil,
|
123
|
+
check_in_id: nil
|
124
|
+
)
|
125
|
+
return unless configuration.sending_allowed?
|
126
|
+
|
127
|
+
CheckInEvent.new(
|
128
|
+
configuration: configuration,
|
129
|
+
integration_meta: Sentry.integrations[hint[:integration]],
|
130
|
+
slug: slug,
|
131
|
+
status: status,
|
132
|
+
duration: duration,
|
133
|
+
monitor_config: monitor_config,
|
134
|
+
check_in_id: check_in_id
|
135
|
+
)
|
136
|
+
end
|
137
|
+
|
104
138
|
# Initializes an Event object with the given Transaction object.
|
105
139
|
# @param transaction [Transaction] the transaction to be recorded.
|
106
140
|
# @return [TransactionEvent]
|
@@ -145,6 +179,8 @@ module Sentry
|
|
145
179
|
raise
|
146
180
|
end
|
147
181
|
|
182
|
+
# @deprecated use Sentry.get_traceparent instead.
|
183
|
+
#
|
148
184
|
# Generates a Sentry trace for distribted tracing from the given Span.
|
149
185
|
# Returns `nil` if `config.propagate_traces` is `false`.
|
150
186
|
# @param span [Span] the span to generate trace from.
|
@@ -157,7 +193,9 @@ module Sentry
|
|
157
193
|
trace
|
158
194
|
end
|
159
195
|
|
160
|
-
#
|
196
|
+
# @deprecated Use Sentry.get_baggage instead.
|
197
|
+
#
|
198
|
+
# Generates a W3C Baggage header for distributed tracing from the given Span.
|
161
199
|
# Returns `nil` if `config.propagate_traces` is `false`.
|
162
200
|
# @param span [Span] the span to generate trace from.
|
163
201
|
# @return [String, nil]
|
data/lib/sentry/configuration.rb
CHANGED
@@ -14,6 +14,8 @@ module Sentry
|
|
14
14
|
class Configuration
|
15
15
|
include CustomInspection
|
16
16
|
include LoggingHelper
|
17
|
+
include ArgumentCheckingHelper
|
18
|
+
|
17
19
|
# Directories to be recognized as part of your app. e.g. if you
|
18
20
|
# have an `engines` dir at the root of your project, you may want
|
19
21
|
# to set this to something like /(app|config|engines|lib)/
|
@@ -179,7 +181,7 @@ module Sentry
|
|
179
181
|
# Release tag to be passed with every event sent to Sentry.
|
180
182
|
# We automatically try to set this to a git SHA or Capistrano release.
|
181
183
|
# @return [String]
|
182
|
-
|
184
|
+
attr_reader :release
|
183
185
|
|
184
186
|
# The sampling factor to apply to events. A value of 0.0 will not send
|
185
187
|
# any events, and a value of 1.0 will send 100% of events.
|
@@ -214,8 +216,8 @@ module Sentry
|
|
214
216
|
attr_reader :transport
|
215
217
|
|
216
218
|
# Take a float between 0.0 and 1.0 as the sample rate for tracing events (transactions).
|
217
|
-
# @return [Float]
|
218
|
-
|
219
|
+
# @return [Float, nil]
|
220
|
+
attr_reader :traces_sample_rate
|
219
221
|
|
220
222
|
# Take a Proc that controls the sample rate for every tracing event, e.g.
|
221
223
|
# @example
|
@@ -227,6 +229,11 @@ module Sentry
|
|
227
229
|
# @return [Proc]
|
228
230
|
attr_accessor :traces_sampler
|
229
231
|
|
232
|
+
# Easier way to use performance tracing
|
233
|
+
# If set to true, will set traces_sample_rate to 1.0
|
234
|
+
# @return [Boolean, nil]
|
235
|
+
attr_reader :enable_tracing
|
236
|
+
|
230
237
|
# Send diagnostic client reports about dropped events, true by default
|
231
238
|
# tries to attach to an existing envelope max once every 30s
|
232
239
|
# @return [Boolean]
|
@@ -236,14 +243,34 @@ module Sentry
|
|
236
243
|
# @return [Boolean]
|
237
244
|
attr_accessor :auto_session_tracking
|
238
245
|
|
246
|
+
# Allowlist of outgoing request targets to which sentry-trace and baggage headers are attached.
|
247
|
+
# Default is all (/.*/)
|
248
|
+
# @return [Array<String, Regexp>]
|
249
|
+
attr_accessor :trace_propagation_targets
|
250
|
+
|
239
251
|
# The instrumenter to use, :sentry or :otel
|
240
252
|
# @return [Symbol]
|
241
253
|
attr_reader :instrumenter
|
242
254
|
|
255
|
+
# Take a float between 0.0 and 1.0 as the sample rate for capturing profiles.
|
256
|
+
# Note that this rate is relative to traces_sample_rate / traces_sampler,
|
257
|
+
# i.e. the profile is sampled by this rate after the transaction is sampled.
|
258
|
+
# @return [Float, nil]
|
259
|
+
attr_reader :profiles_sample_rate
|
260
|
+
|
243
261
|
# these are not config options
|
244
262
|
# @!visibility private
|
245
263
|
attr_reader :errors, :gem_specs
|
246
264
|
|
265
|
+
# These exceptions could enter Puma's `lowlevel_error_handler` callback and the SDK's Puma integration
|
266
|
+
# But they are mostly considered as noise and should be ignored by default
|
267
|
+
# Please see https://github.com/getsentry/sentry-ruby/pull/2026 for more information
|
268
|
+
PUMA_IGNORE_DEFAULT = [
|
269
|
+
'Puma::MiniSSL::SSLError',
|
270
|
+
'Puma::HttpParserError',
|
271
|
+
'Puma::HttpParserError501'
|
272
|
+
].freeze
|
273
|
+
|
247
274
|
# Most of these errors generate 4XX responses. In general, Sentry clients
|
248
275
|
# only automatically report 5xx responses.
|
249
276
|
IGNORE_DEFAULT = [
|
@@ -268,6 +295,8 @@ module Sentry
|
|
268
295
|
|
269
296
|
INSTRUMENTERS = [:sentry, :otel]
|
270
297
|
|
298
|
+
PROPAGATION_TARGETS_MATCH_ALL = /.*/.freeze
|
299
|
+
|
271
300
|
class << self
|
272
301
|
# Post initialization callbacks are called at the end of initialization process
|
273
302
|
# allowing extending the configuration of sentry-ruby by multiple extensions
|
@@ -293,7 +322,7 @@ module Sentry
|
|
293
322
|
self.environment = environment_from_env
|
294
323
|
self.enabled_environments = []
|
295
324
|
self.exclude_loggers = []
|
296
|
-
self.excluded_exceptions = IGNORE_DEFAULT
|
325
|
+
self.excluded_exceptions = IGNORE_DEFAULT + PUMA_IGNORE_DEFAULT
|
297
326
|
self.inspect_exception_causes_for_exclusion = true
|
298
327
|
self.linecache = ::Sentry::LineCache.new
|
299
328
|
self.logger = ::Sentry::Logger.new(STDOUT)
|
@@ -310,12 +339,13 @@ module Sentry
|
|
310
339
|
self.dsn = ENV['SENTRY_DSN']
|
311
340
|
self.server_name = server_name_from_env
|
312
341
|
self.instrumenter = :sentry
|
342
|
+
self.trace_propagation_targets = [PROPAGATION_TARGETS_MATCH_ALL]
|
313
343
|
|
314
344
|
self.before_send = nil
|
315
345
|
self.before_send_transaction = nil
|
316
346
|
self.rack_env_whitelist = RACK_ENV_WHITELIST_DEFAULT
|
317
|
-
self.traces_sample_rate = nil
|
318
347
|
self.traces_sampler = nil
|
348
|
+
self.enable_tracing = nil
|
319
349
|
|
320
350
|
@transport = Transport::Configuration.new
|
321
351
|
@gem_specs = Hash[Gem::Specification.map { |spec| [spec.name, spec.version.to_s] }] if Gem::Specification.respond_to?(:map)
|
@@ -329,6 +359,12 @@ module Sentry
|
|
329
359
|
|
330
360
|
alias server= dsn=
|
331
361
|
|
362
|
+
def release=(value)
|
363
|
+
check_argument_type!(value, String, NilClass)
|
364
|
+
|
365
|
+
@release = value
|
366
|
+
end
|
367
|
+
|
332
368
|
def async=(value)
|
333
369
|
check_callable!("async", value)
|
334
370
|
|
@@ -384,6 +420,26 @@ module Sentry
|
|
384
420
|
@instrumenter = INSTRUMENTERS.include?(instrumenter) ? instrumenter : :sentry
|
385
421
|
end
|
386
422
|
|
423
|
+
def enable_tracing=(enable_tracing)
|
424
|
+
@enable_tracing = enable_tracing
|
425
|
+
@traces_sample_rate ||= 1.0 if enable_tracing
|
426
|
+
end
|
427
|
+
|
428
|
+
def is_numeric_or_nil?(value)
|
429
|
+
value.is_a?(Numeric) || value.nil?
|
430
|
+
end
|
431
|
+
|
432
|
+
def traces_sample_rate=(traces_sample_rate)
|
433
|
+
raise ArgumentError, "traces_sample_rate must be a Numeric or nil" unless is_numeric_or_nil?(traces_sample_rate)
|
434
|
+
@traces_sample_rate = traces_sample_rate
|
435
|
+
end
|
436
|
+
|
437
|
+
def profiles_sample_rate=(profiles_sample_rate)
|
438
|
+
raise ArgumentError, "profiles_sample_rate must be a Numeric or nil" unless is_numeric_or_nil?(profiles_sample_rate)
|
439
|
+
log_info("Please make sure to include the 'stackprof' gem in your Gemfile to use Profiling with Sentry.") unless defined?(StackProf)
|
440
|
+
@profiles_sample_rate = profiles_sample_rate
|
441
|
+
end
|
442
|
+
|
387
443
|
def sending_allowed?
|
388
444
|
@errors = []
|
389
445
|
|
@@ -413,8 +469,21 @@ module Sentry
|
|
413
469
|
enabled_environments.empty? || enabled_environments.include?(environment)
|
414
470
|
end
|
415
471
|
|
472
|
+
def valid_sample_rate?(sample_rate)
|
473
|
+
return false unless sample_rate.is_a?(Numeric)
|
474
|
+
sample_rate >= 0.0 && sample_rate <= 1.0
|
475
|
+
end
|
476
|
+
|
416
477
|
def tracing_enabled?
|
417
|
-
!!((@traces_sample_rate
|
478
|
+
valid_sampler = !!((valid_sample_rate?(@traces_sample_rate)) || @traces_sampler)
|
479
|
+
|
480
|
+
(@enable_tracing != false) && valid_sampler && sending_allowed?
|
481
|
+
end
|
482
|
+
|
483
|
+
def profiling_enabled?
|
484
|
+
valid_sampler = !!(valid_sample_rate?(@profiles_sample_rate))
|
485
|
+
|
486
|
+
tracing_enabled? && valid_sampler && sending_allowed?
|
418
487
|
end
|
419
488
|
|
420
489
|
# @return [String, nil]
|
@@ -442,7 +511,7 @@ module Sentry
|
|
442
511
|
def detect_release
|
443
512
|
return unless sending_allowed?
|
444
513
|
|
445
|
-
|
514
|
+
@release ||= ReleaseDetector.detect_release(project_root: project_root, running_on_heroku: running_on_heroku?)
|
446
515
|
|
447
516
|
if running_on_heroku? && release.nil?
|
448
517
|
log_warn(HEROKU_DYNO_METADATA_MESSAGE)
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Sentry
|
2
|
+
module Cron
|
3
|
+
module MonitorCheckIns
|
4
|
+
module Patch
|
5
|
+
def perform(*args)
|
6
|
+
slug = self.class.sentry_monitor_slug || self.class.name
|
7
|
+
monitor_config = self.class.sentry_monitor_config
|
8
|
+
|
9
|
+
check_in_id = Sentry.capture_check_in(slug,
|
10
|
+
:in_progress,
|
11
|
+
monitor_config: monitor_config)
|
12
|
+
|
13
|
+
start = Sentry.utc_now.to_i
|
14
|
+
ret = super
|
15
|
+
duration = Sentry.utc_now.to_i - start
|
16
|
+
|
17
|
+
Sentry.capture_check_in(slug,
|
18
|
+
:ok,
|
19
|
+
check_in_id: check_in_id,
|
20
|
+
duration: duration,
|
21
|
+
monitor_config: monitor_config)
|
22
|
+
|
23
|
+
ret
|
24
|
+
rescue Exception
|
25
|
+
duration = Sentry.utc_now.to_i - start
|
26
|
+
|
27
|
+
Sentry.capture_check_in(slug,
|
28
|
+
:error,
|
29
|
+
check_in_id: check_in_id,
|
30
|
+
duration: duration,
|
31
|
+
monitor_config: monitor_config)
|
32
|
+
|
33
|
+
raise
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module ClassMethods
|
38
|
+
def sentry_monitor_check_ins(slug: nil, monitor_config: nil)
|
39
|
+
@sentry_monitor_slug = slug
|
40
|
+
@sentry_monitor_config = monitor_config
|
41
|
+
|
42
|
+
prepend Patch
|
43
|
+
end
|
44
|
+
|
45
|
+
def sentry_monitor_slug
|
46
|
+
@sentry_monitor_slug
|
47
|
+
end
|
48
|
+
|
49
|
+
def sentry_monitor_config
|
50
|
+
@sentry_monitor_config
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
extend ClassMethods
|
55
|
+
|
56
|
+
def self.included(base)
|
57
|
+
base.extend(ClassMethods)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal
|
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
|
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
@@ -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
|