sentry-ruby-core 7.1.0 → 7.2.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 +2 -0
- data/gemfiles/ruby-2.7_rack-2_redis-4.gemfile.lock +19 -7
- data/gemfiles/ruby-2.7_rack-3.1_redis-4.gemfile.lock +19 -7
- data/gemfiles/ruby-2.7_rack-3_redis-4.gemfile.lock +19 -7
- data/gemfiles/ruby-3.0_rack-2_redis-4.gemfile.lock +28 -12
- data/gemfiles/ruby-3.0_rack-3.1_redis-4.gemfile.lock +28 -12
- data/gemfiles/ruby-3.0_rack-3_redis-4.gemfile.lock +28 -12
- data/gemfiles/ruby-3.1_rack-2_redis-4.gemfile.lock +46 -23
- data/gemfiles/ruby-3.1_rack-3.1_redis-4.gemfile.lock +46 -23
- data/gemfiles/ruby-3.1_rack-3_redis-4.gemfile.lock +46 -23
- data/gemfiles/ruby-3.2_rack-0_redis-5.gemfile.lock +50 -27
- data/gemfiles/ruby-3.2_rack-2_redis-4.gemfile.lock +48 -25
- data/gemfiles/ruby-3.2_rack-2_redis-5.gemfile.lock +50 -27
- data/gemfiles/ruby-3.2_rack-3.1_redis-4.gemfile.lock +48 -25
- data/gemfiles/ruby-3.2_rack-3_redis-4.gemfile.lock +48 -25
- data/gemfiles/ruby-3.2_rack-3_redis-5.gemfile.lock +50 -27
- data/gemfiles/ruby-3.3_rack-2_redis-4.gemfile.lock +52 -29
- data/gemfiles/ruby-3.3_rack-3.1_redis-4.gemfile.lock +52 -29
- data/gemfiles/ruby-3.3_rack-3.1_redis-5.3.gemfile.lock +54 -31
- data/gemfiles/ruby-3.3_rack-3_redis-4.gemfile.lock +52 -29
- data/gemfiles/ruby-3.4_rack-2_redis-4.gemfile.lock +52 -29
- data/gemfiles/ruby-3.4_rack-3.1_redis-4.gemfile.lock +52 -29
- data/gemfiles/ruby-3.4_rack-3.1_redis-5.3.gemfile.lock +54 -31
- data/gemfiles/ruby-3.4_rack-3_redis-4.gemfile.lock +52 -29
- data/gemfiles/ruby-4.0_rack-2_redis-4.gemfile.lock +52 -29
- data/gemfiles/ruby-4.0_rack-3.1_redis-4.gemfile.lock +52 -29
- data/gemfiles/ruby-4.0_rack-3_redis-4.gemfile.lock +52 -29
- data/gemfiles/ruby-jruby-9.4.14.0_rack-2_redis-4.gemfile.lock +53 -35
- data/gemfiles/ruby-jruby-9.4.14.0_rack-3.1_redis-4.gemfile.lock +53 -35
- data/gemfiles/ruby-jruby-9.4.14.0_rack-3_redis-4.gemfile.lock +53 -35
- data/lib/sentry/configuration.rb +7 -2
- data/lib/sentry/cron/fugit_schedule.rb +117 -0
- data/lib/sentry/cron/monitor_check_ins.rb +33 -27
- data/lib/sentry/cron/slug.rb +18 -0
- data/lib/sentry/data_collection.rb +6 -1
- data/lib/sentry/rufus_scheduler.rb +120 -0
- data/lib/sentry/transport/debug_transport.rb +11 -2
- data/lib/sentry/transport/dummy_transport.rb +7 -4
- data/lib/sentry/transport/spotlight_transport.rb +2 -2
- data/lib/sentry/version.rb +1 -1
- data/lib/sentry-ruby.rb +3 -0
- metadata +6 -3
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sentry
|
|
4
|
+
module Cron
|
|
5
|
+
module Slug
|
|
6
|
+
module_function
|
|
7
|
+
|
|
8
|
+
# Returns nil when nothing usable is left.
|
|
9
|
+
def from(name)
|
|
10
|
+
slug = name.to_s.downcase.gsub(/[^a-z0-9_-]+/, "-").sub(/\A-+/, "")
|
|
11
|
+
slug = slug[0, MonitorCheckIns::MAX_SLUG_LENGTH]
|
|
12
|
+
# rindex instead of /-+\z/, which backtracks on long runs of dashes.
|
|
13
|
+
last = slug.rindex(/[^-]/)
|
|
14
|
+
last && slug[0..last]
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -131,6 +131,7 @@ module Sentry
|
|
|
131
131
|
def self.backfill(configuration)
|
|
132
132
|
data_collection = new
|
|
133
133
|
data_collection.backfill_stack_frame_variables(configuration)
|
|
134
|
+
data_collection.backfill_frame_context_lines(configuration)
|
|
134
135
|
return data_collection if configuration.send_default_pii
|
|
135
136
|
|
|
136
137
|
# TODO-neel-data map to exact ruby behaviour for backwards compat behavior
|
|
@@ -146,7 +147,6 @@ module Sentry
|
|
|
146
147
|
data_collection.graphql.variables = false
|
|
147
148
|
data_collection.database_query_data = false
|
|
148
149
|
data_collection.queues = false
|
|
149
|
-
data_collection.frame_context_lines = configuration.context_lines
|
|
150
150
|
data_collection
|
|
151
151
|
end
|
|
152
152
|
|
|
@@ -171,6 +171,11 @@ module Sentry
|
|
|
171
171
|
self.stack_frame_variables = configuration.include_local_variables
|
|
172
172
|
end
|
|
173
173
|
|
|
174
|
+
# Copies the legacy context_lines configuration.
|
|
175
|
+
def backfill_frame_context_lines(configuration)
|
|
176
|
+
self.frame_context_lines = configuration.context_lines
|
|
177
|
+
end
|
|
178
|
+
|
|
174
179
|
# Returns whether stack frame local variables should be captured.
|
|
175
180
|
def collect_stack_frame_variables?
|
|
176
181
|
stack_frame_variables.mode != :off
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sentry
|
|
4
|
+
# Sends Crons check-ins for rufus-scheduler `cron`, `every` and `interval` jobs.
|
|
5
|
+
# Enable with `config.enabled_patches << :rufus_scheduler`.
|
|
6
|
+
module RufusScheduler
|
|
7
|
+
module Job
|
|
8
|
+
protected
|
|
9
|
+
|
|
10
|
+
def do_call(time, do_rescue)
|
|
11
|
+
return super unless Sentry.initialized? && (monitor = sentry_monitor)
|
|
12
|
+
|
|
13
|
+
slug, monitor_config = monitor
|
|
14
|
+
check_in_id = Sentry.capture_check_in(slug, :in_progress, monitor_config: monitor_config)
|
|
15
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
16
|
+
|
|
17
|
+
begin
|
|
18
|
+
# Run without rufus's rescue so the error is seen, then handle it like Job#do_call.
|
|
19
|
+
ret = super(time, false)
|
|
20
|
+
rescue Exception => e
|
|
21
|
+
duration = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
|
|
22
|
+
Sentry.capture_check_in(slug, :error, check_in_id: check_in_id, duration: duration, monitor_config: monitor_config)
|
|
23
|
+
|
|
24
|
+
raise unless do_rescue && e.is_a?(StandardError)
|
|
25
|
+
return if e.is_a?(::Rufus::Scheduler::Job::KillSignal)
|
|
26
|
+
|
|
27
|
+
return @scheduler.on_error(self, e)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
duration = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
|
|
31
|
+
Sentry.capture_check_in(slug, :ok, check_in_id: check_in_id, duration: duration, monitor_config: monitor_config)
|
|
32
|
+
|
|
33
|
+
ret
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def sentry_monitor
|
|
39
|
+
return @sentry_monitor if defined?(@sentry_monitor)
|
|
40
|
+
|
|
41
|
+
@sentry_monitor = Sentry::RufusScheduler.monitor_for(self)
|
|
42
|
+
rescue StandardError => e
|
|
43
|
+
Sentry.sdk_logger.error(Sentry::LOGGER_PROGNAME) { "Not monitoring rufus-scheduler job #{id}: #{e.class}: #{e.message}" }
|
|
44
|
+
@sentry_monitor = nil
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
class << self
|
|
49
|
+
# Returns [slug, monitor_config], or nil for jobs that aren't monitored (like `at`/`in`).
|
|
50
|
+
def monitor_for(job)
|
|
51
|
+
return unless job.is_a?(::Rufus::Scheduler::RepeatJob)
|
|
52
|
+
return if job.opts[:sentry_monitor] == false
|
|
53
|
+
return if sidekiq_scheduler_job?(job)
|
|
54
|
+
|
|
55
|
+
slug = slug_for(job)
|
|
56
|
+
unless slug
|
|
57
|
+
Sentry.sdk_logger.warn(Sentry::LOGGER_PROGNAME) do
|
|
58
|
+
"Not monitoring rufus-scheduler job #{job.id} at #{job.source_location&.join(":")}: " \
|
|
59
|
+
"pass `name:` to give it a stable monitor slug."
|
|
60
|
+
end
|
|
61
|
+
return
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
[slug, monitor_config_for(job)]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
private
|
|
68
|
+
|
|
69
|
+
# sidekiq-scheduler jobs are monitored by the :sidekiq_scheduler patch.
|
|
70
|
+
def sidekiq_scheduler_job?(job)
|
|
71
|
+
file, _ = job.callable.source_location if job.callable.respond_to?(:source_location)
|
|
72
|
+
file&.end_with?("sidekiq-scheduler/scheduler.rb")
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Job ids are random per process and block paths change between deploys,
|
|
76
|
+
# so the slug comes from `name:`, then the handler method or class.
|
|
77
|
+
def slug_for(job)
|
|
78
|
+
handler = job.handler
|
|
79
|
+
source =
|
|
80
|
+
if job.name
|
|
81
|
+
job.name.to_s
|
|
82
|
+
elsif handler.is_a?(Method)
|
|
83
|
+
# The receiver's class, not the method owner, so inherited and mixin methods get distinct slugs.
|
|
84
|
+
namespace = handler.receiver.is_a?(Module) ? handler.receiver : handler.receiver.class
|
|
85
|
+
[namespace == Object ? nil : namespace.name, handler.name].compact.join("::")
|
|
86
|
+
elsif !handler.is_a?(Proc)
|
|
87
|
+
handler.class.name
|
|
88
|
+
end
|
|
89
|
+
return unless source
|
|
90
|
+
|
|
91
|
+
Sentry::Cron::Slug.from(source)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def monitor_config_for(job)
|
|
95
|
+
case job
|
|
96
|
+
when ::Rufus::Scheduler::CronJob
|
|
97
|
+
Sentry::Cron::FugitSchedule.from_cron(job.cron_line)
|
|
98
|
+
when ::Rufus::Scheduler::EveryJob
|
|
99
|
+
Sentry::Cron::FugitSchedule.from_seconds(job.frequency)
|
|
100
|
+
end
|
|
101
|
+
# IntervalJob waits `interval` after each run ends, so it has no fixed
|
|
102
|
+
# schedule to monitor against.
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
Sentry.register_patch(:rufus_scheduler) do |config|
|
|
109
|
+
# Load rufus-scheduler in case it's required after Sentry.init.
|
|
110
|
+
begin
|
|
111
|
+
require "rufus-scheduler"
|
|
112
|
+
rescue LoadError
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
if defined?(::Rufus::Scheduler::RepeatJob)
|
|
116
|
+
::Rufus::Scheduler::Job.prepend(Sentry::RufusScheduler::Job) unless ::Rufus::Scheduler::Job.ancestors.include?(Sentry::RufusScheduler::Job)
|
|
117
|
+
else
|
|
118
|
+
config.sdk_logger.warn(Sentry::LOGGER_PROGNAME) { "You tried to enable the rufus-scheduler integration but the `rufus-scheduler` gem was not detected." }
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -27,6 +27,11 @@ module Sentry
|
|
|
27
27
|
backend.send_event(event)
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
def send_envelope(envelope)
|
|
31
|
+
log_envelope(envelope)
|
|
32
|
+
backend.send_envelope(envelope)
|
|
33
|
+
end
|
|
34
|
+
|
|
30
35
|
def log_envelope(envelope)
|
|
31
36
|
envelope_json = {
|
|
32
37
|
timestamp: Time.now.utc.iso8601,
|
|
@@ -36,13 +41,13 @@ module Sentry
|
|
|
36
41
|
end
|
|
37
42
|
}
|
|
38
43
|
|
|
39
|
-
File.open(log_file, "a") { |file| file
|
|
44
|
+
File.open(log_file, "a") { |file| file.write("#{JSON.dump(envelope_json)}\n") }
|
|
40
45
|
end
|
|
41
46
|
|
|
42
47
|
def logged_envelopes
|
|
43
48
|
return [] unless File.exist?(log_file)
|
|
44
49
|
|
|
45
|
-
File.readlines(log_file).map do |line|
|
|
50
|
+
File.readlines(log_file).select { |line| fully_written?(line) }.map do |line|
|
|
46
51
|
JSON.parse(line)
|
|
47
52
|
end
|
|
48
53
|
end
|
|
@@ -54,6 +59,10 @@ module Sentry
|
|
|
54
59
|
|
|
55
60
|
private
|
|
56
61
|
|
|
62
|
+
def fully_written?(line)
|
|
63
|
+
line.end_with?("\n")
|
|
64
|
+
end
|
|
65
|
+
|
|
57
66
|
def initialize_backend(configuration)
|
|
58
67
|
backend = configuration.dsn.local? ? DummyTransport : HTTPTransport
|
|
59
68
|
backend.new(configuration)
|
|
@@ -8,22 +8,25 @@ module Sentry
|
|
|
8
8
|
super
|
|
9
9
|
@events = []
|
|
10
10
|
@envelopes = []
|
|
11
|
+
@mutex = Mutex.new
|
|
11
12
|
end
|
|
12
13
|
|
|
13
14
|
def send_event(event)
|
|
14
|
-
@events << event
|
|
15
|
+
@mutex.synchronize { @events << event }
|
|
15
16
|
super
|
|
16
17
|
end
|
|
17
18
|
|
|
18
19
|
def send_envelope(envelope)
|
|
19
|
-
@envelopes << envelope
|
|
20
|
+
@mutex.synchronize { @envelopes << envelope }
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
# Empties the captured events and envelopes so `TestHelper.clear_sentry_events`
|
|
23
24
|
# also clears the dummy transport instance
|
|
24
25
|
def clear
|
|
25
|
-
@
|
|
26
|
-
|
|
26
|
+
@mutex.synchronize do
|
|
27
|
+
@events.clear
|
|
28
|
+
@envelopes.clear
|
|
29
|
+
end
|
|
27
30
|
end
|
|
28
31
|
end
|
|
29
32
|
end
|
|
@@ -39,11 +39,11 @@ module Sentry
|
|
|
39
39
|
@failed += 1
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
# Similar to HTTPTransport connection, but does not support Proxy
|
|
42
|
+
# Similar to HTTPTransport connection, but does not support Proxy
|
|
43
43
|
def conn
|
|
44
44
|
sidecar = URI(@sidecar_url)
|
|
45
45
|
connection = ::Net::HTTP.new(sidecar.hostname, sidecar.port, nil)
|
|
46
|
-
connection.use_ssl =
|
|
46
|
+
connection.use_ssl = sidecar.scheme == "https"
|
|
47
47
|
connection
|
|
48
48
|
end
|
|
49
49
|
end
|
data/lib/sentry/version.rb
CHANGED
data/lib/sentry-ruby.rb
CHANGED
|
@@ -27,6 +27,8 @@ require "sentry/threaded_periodic_worker"
|
|
|
27
27
|
require "sentry/session_flusher"
|
|
28
28
|
require "sentry/backpressure_monitor"
|
|
29
29
|
require "sentry/cron/monitor_check_ins"
|
|
30
|
+
require "sentry/cron/fugit_schedule"
|
|
31
|
+
require "sentry/cron/slug"
|
|
30
32
|
require "sentry/vernier/profiler"
|
|
31
33
|
require "sentry/metrics"
|
|
32
34
|
|
|
@@ -793,3 +795,4 @@ require "sentry/graphql"
|
|
|
793
795
|
require "sentry/faraday"
|
|
794
796
|
require "sentry/excon"
|
|
795
797
|
require "sentry/std_lib_logger"
|
|
798
|
+
require "sentry/rufus_scheduler"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sentry-ruby-core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 7.
|
|
4
|
+
version: 7.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sentry Team
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 7.
|
|
18
|
+
version: 7.2.0
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - '='
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 7.
|
|
25
|
+
version: 7.2.0
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: concurrent-ruby
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -102,9 +102,11 @@ files:
|
|
|
102
102
|
- lib/sentry/core_ext/object/deep_dup.rb
|
|
103
103
|
- lib/sentry/core_ext/object/duplicable.rb
|
|
104
104
|
- lib/sentry/cron/configuration.rb
|
|
105
|
+
- lib/sentry/cron/fugit_schedule.rb
|
|
105
106
|
- lib/sentry/cron/monitor_check_ins.rb
|
|
106
107
|
- lib/sentry/cron/monitor_config.rb
|
|
107
108
|
- lib/sentry/cron/monitor_schedule.rb
|
|
109
|
+
- lib/sentry/cron/slug.rb
|
|
108
110
|
- lib/sentry/data_collection.rb
|
|
109
111
|
- lib/sentry/data_collection/key_value_collection.rb
|
|
110
112
|
- lib/sentry/debug_structured_logger.rb
|
|
@@ -146,6 +148,7 @@ files:
|
|
|
146
148
|
- lib/sentry/redis.rb
|
|
147
149
|
- lib/sentry/release_detector.rb
|
|
148
150
|
- lib/sentry/rspec.rb
|
|
151
|
+
- lib/sentry/rufus_scheduler.rb
|
|
149
152
|
- lib/sentry/scope.rb
|
|
150
153
|
- lib/sentry/sequel.rb
|
|
151
154
|
- lib/sentry/session.rb
|