sentry-ruby 5.8.0 → 5.12.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
| [![Gem Version](https://img.shields.io/gem/v/sentry-ruby?label=sentry-ruby)](https://rubygems.org/gems/sentry-ruby)
|
19
|
-
| [![Gem Version](https://img.shields.io/gem/v/sentry-rails?label=sentry-rails)](https://rubygems.org/gems/sentry-rails)
|
20
|
-
| [![Gem Version](https://img.shields.io/gem/v/sentry-sidekiq?label=sentry-sidekiq)](https://rubygems.org/gems/sentry-sidekiq)
|
21
|
-
| [![Gem Version](https://img.shields.io/gem/v/sentry-delayed_job?label=sentry-delayed_job)](https://rubygems.org/gems/sentry-delayed_job)
|
22
|
-
| [![Gem Version](https://img.shields.io/gem/v/sentry-resque?label=sentry-resque)](https://rubygems.org/gems/sentry-resque)
|
23
|
-
| [![Gem Version](https://img.shields.io/gem/v/sentry-opentelemetry?label=sentry-opentelemetry)](https://rubygems.org/gems/sentry-opentelemetry) | [![Build Status](https://github.com/getsentry/sentry-ruby/workflows/
|
16
|
+
| current version | build | coverage | downloads |
|
17
|
+
| --- | ----- | -------- | --------- |
|
18
|
+
| [![Gem Version](https://img.shields.io/gem/v/sentry-ruby?label=sentry-ruby)](https://rubygems.org/gems/sentry-ruby) | [![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_ruby_test.yml/badge.svg)](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_ruby_test.yml) | [![Coverage Status](https://img.shields.io/codecov/c/github/getsentry/sentry-ruby/master?logo=codecov)](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [![Downloads](https://img.shields.io/gem/dt/sentry-ruby.svg)](https://rubygems.org/gems/sentry-ruby/) |
|
19
|
+
| [![Gem Version](https://img.shields.io/gem/v/sentry-rails?label=sentry-rails)](https://rubygems.org/gems/sentry-rails) | [![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_rails_test.yml/badge.svg)](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_rails_test.yml) | [![Coverage Status](https://img.shields.io/codecov/c/github/getsentry/sentry-ruby/master?logo=codecov)](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [![Downloads](https://img.shields.io/gem/dt/sentry-rails.svg)](https://rubygems.org/gems/sentry-rails/) |
|
20
|
+
| [![Gem Version](https://img.shields.io/gem/v/sentry-sidekiq?label=sentry-sidekiq)](https://rubygems.org/gems/sentry-sidekiq) | [![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_sidekiq_test.yml/badge.svg)](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_sidekiq_test.yml) | [![Coverage Status](https://img.shields.io/codecov/c/github/getsentry/sentry-ruby/master?logo=codecov)](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [![Downloads](https://img.shields.io/gem/dt/sentry-sidekiq.svg)](https://rubygems.org/gems/sentry-sidekiq/) |
|
21
|
+
| [![Gem Version](https://img.shields.io/gem/v/sentry-delayed_job?label=sentry-delayed_job)](https://rubygems.org/gems/sentry-delayed_job) | [![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_delayed_job_test.yml/badge.svg)](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_delayed_job_test.yml) | [![Coverage Status](https://img.shields.io/codecov/c/github/getsentry/sentry-ruby/master?logo=codecov)](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [![Downloads](https://img.shields.io/gem/dt/sentry-delayed_job.svg)](https://rubygems.org/gems/sentry-delayed_job/) |
|
22
|
+
| [![Gem Version](https://img.shields.io/gem/v/sentry-resque?label=sentry-resque)](https://rubygems.org/gems/sentry-resque) | [![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_resque_test.yml/badge.svg)](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_resque_test.yml) | [![Coverage Status](https://img.shields.io/codecov/c/github/getsentry/sentry-ruby/master?logo=codecov)](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [![Downloads](https://img.shields.io/gem/dt/sentry-resque.svg)](https://rubygems.org/gems/sentry-resque/) |
|
23
|
+
| [![Gem Version](https://img.shields.io/gem/v/sentry-opentelemetry?label=sentry-opentelemetry)](https://rubygems.org/gems/sentry-opentelemetry) | [![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_opentelemetry_test.yml/badge.svg)](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_opentelemetry_test.yml) | [![Coverage Status](https://img.shields.io/codecov/c/github/getsentry/sentry-ruby/master?logo=codecov)](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [![Downloads](https://img.shields.io/gem/dt/sentry-opentelemetry.svg)](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
|