sentry-sidekiq 5.10.0 → 5.26.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 +26 -13
- data/Makefile +0 -4
- data/README.md +1 -1
- data/Rakefile +3 -1
- data/bin/console +1 -0
- data/example/Gemfile +2 -1
- data/example/error_worker.rb +2 -0
- data/lib/sentry/sidekiq/configuration.rb +14 -1
- data/lib/sentry/sidekiq/context_filter.rb +4 -2
- data/lib/sentry/sidekiq/cron/helpers.rb +23 -0
- data/lib/sentry/sidekiq/cron/job.rb +90 -0
- data/lib/sentry/sidekiq/error_handler.rb +39 -5
- data/lib/sentry/sidekiq/sentry_context_middleware.rb +70 -12
- data/lib/sentry/sidekiq/version.rb +3 -1
- data/lib/sentry/sidekiq-scheduler/scheduler.rb +68 -0
- data/lib/sentry-sidekiq.rb +7 -0
- data/sentry-sidekiq.gemspec +14 -6
- metadata +15 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ecef3da0594e364745ceaf67376f0acfd3d9053533f48354955716c4b0c8ea6c
|
4
|
+
data.tar.gz: 891089c3a64f091596ed2548cf1e90f1251b8923e7bcef71ff4dd183578545df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a45994cf24f8b52a5a7d68017073661d6bf313e69ffd84bf22eba1527a29fdc0d42a62f6de93930a947357f78770ad518ea6449e7d167c1d5d1ffe697c23095c
|
7
|
+
data.tar.gz: a053fca9ea3c8b24845baf054fb774a558de78de89b1d73efd1f51162c1e3150973900ee5ce493f3d9e4a978ad657948bf805bb4d7035c4f0f7d7b9d90d48b62
|
data/Gemfile
CHANGED
@@ -1,30 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
source "https://rubygems.org"
|
2
4
|
git_source(:github) { |name| "https://github.com/#{name}.git" }
|
3
5
|
|
6
|
+
eval_gemfile "../Gemfile"
|
7
|
+
|
4
8
|
# Specify your gem's dependencies in sentry-ruby.gemspec
|
5
9
|
gemspec
|
10
|
+
|
6
11
|
gem "sentry-ruby", path: "../sentry-ruby"
|
7
12
|
gem "sentry-rails", path: "../sentry-rails"
|
8
13
|
|
9
|
-
gem "rake", "~> 12.0"
|
10
|
-
gem "rspec", "~> 3.0"
|
11
|
-
gem 'simplecov'
|
12
|
-
gem "simplecov-cobertura", "~> 1.4"
|
13
|
-
gem "rexml"
|
14
14
|
# https://github.com/flavorjones/loofah/pull/267
|
15
15
|
# loofah changed the required ruby version in a patch so we need to explicitly pin it
|
16
16
|
gem "loofah", "2.20.0" if RUBY_VERSION.to_f < 2.5
|
17
17
|
|
18
|
-
|
19
|
-
|
18
|
+
if ENV["SIDEKIQ_MAIN"]
|
19
|
+
gem "sidekiq", github: "sidekiq/sidekiq", branch: "main"
|
20
|
+
sidekiq_version = "main"
|
21
|
+
else
|
22
|
+
sidekiq_version = ENV["SIDEKIQ_VERSION"]
|
23
|
+
sidekiq_version = "7.0" if sidekiq_version.nil?
|
24
|
+
sidekiq_version = Gem::Version.new(sidekiq_version)
|
20
25
|
|
21
|
-
gem "sidekiq", "~> #{sidekiq_version}"
|
22
|
-
|
26
|
+
gem "sidekiq", "~> #{sidekiq_version}"
|
27
|
+
end
|
28
|
+
|
29
|
+
if sidekiq_version == "main" || RUBY_VERSION.to_f >= 2.7 && sidekiq_version >= Gem::Version.new("6.0")
|
30
|
+
gem "sidekiq-cron"
|
23
31
|
|
24
|
-
if
|
25
|
-
|
26
|
-
|
32
|
+
if sidekiq_version == "main" || sidekiq_version >= Gem::Version.new("8.0")
|
33
|
+
gem "sidekiq-scheduler", "~> 6.0.0.beta"
|
34
|
+
else
|
35
|
+
gem "sidekiq-scheduler", "~> 5.0.0"
|
36
|
+
end
|
27
37
|
end
|
28
38
|
|
29
|
-
gem "
|
39
|
+
gem "rails", "> 5.0.0"
|
40
|
+
|
41
|
+
gem "timecop"
|
30
42
|
|
43
|
+
gem "vernier", platforms: :ruby if RUBY_VERSION >= "3.2.1"
|
data/Makefile
CHANGED
data/README.md
CHANGED
@@ -11,7 +11,7 @@
|
|
11
11
|
|
12
12
|
|
13
13
|
[](https://rubygems.org/gems/sentry-sidekiq)
|
14
|
-

|
15
15
|
[](https://codecov.io/gh/getsentry/sentry-ruby/branch/master)
|
16
16
|
[](https://rubygems.org/gems/sentry-sidekiq/)
|
17
17
|
[](https://dependabot.com/compatibility-score.html?dependency-name=sentry-sidekiq&package-manager=bundler&version-scheme=semver)
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
data/example/Gemfile
CHANGED
data/example/error_worker.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Sentry
|
2
4
|
class Configuration
|
3
5
|
attr_reader :sidekiq
|
@@ -9,15 +11,26 @@ module Sentry
|
|
9
11
|
end
|
10
12
|
|
11
13
|
module Sidekiq
|
12
|
-
IGNORE_DEFAULT = [
|
14
|
+
IGNORE_DEFAULT = [
|
15
|
+
"Sidekiq::JobRetry::Skip",
|
16
|
+
"Sidekiq::JobRetry::Handled"
|
17
|
+
]
|
13
18
|
|
14
19
|
class Configuration
|
15
20
|
# Set this option to true if you want Sentry to only capture the last job
|
16
21
|
# retry if it fails.
|
17
22
|
attr_accessor :report_after_job_retries
|
18
23
|
|
24
|
+
# Only report jobs that don't have `dead: false` set in the job's `sidekiq_options`
|
25
|
+
attr_accessor :report_only_dead_jobs
|
26
|
+
|
27
|
+
# Whether we should inject headers while enqueuing the job in order to have a connected trace
|
28
|
+
attr_accessor :propagate_traces
|
29
|
+
|
19
30
|
def initialize
|
20
31
|
@report_after_job_retries = false
|
32
|
+
@report_only_dead_jobs = false
|
33
|
+
@propagate_traces = true
|
21
34
|
end
|
22
35
|
end
|
23
36
|
end
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Sentry
|
2
4
|
module Sidekiq
|
3
5
|
class ContextFilter
|
4
|
-
ACTIVEJOB_RESERVED_PREFIX_REGEX = /^_aj_
|
5
|
-
SIDEKIQ_NAME = "Sidekiq"
|
6
|
+
ACTIVEJOB_RESERVED_PREFIX_REGEX = /^_aj_/
|
7
|
+
SIDEKIQ_NAME = "Sidekiq"
|
6
8
|
|
7
9
|
attr_reader :context
|
8
10
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sentry
|
4
|
+
module Sidekiq
|
5
|
+
module Cron
|
6
|
+
module Helpers
|
7
|
+
# This is used by Cron::Job and Scheduler
|
8
|
+
def self.monitor_config(cron)
|
9
|
+
cron_parts = cron.strip.split(" ")
|
10
|
+
|
11
|
+
if cron_parts.length > 5
|
12
|
+
timezone = cron_parts.pop
|
13
|
+
cron_without_timezone = cron_parts.join(" ")
|
14
|
+
|
15
|
+
Sentry::Cron::MonitorConfig.from_crontab(cron_without_timezone, timezone: timezone)
|
16
|
+
else
|
17
|
+
Sentry::Cron::MonitorConfig.from_crontab(cron)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Try requiring sidekiq-cron to ensure it's loaded before the integration.
|
4
|
+
# If sidekiq-cron is not available, do nothing.
|
5
|
+
begin
|
6
|
+
require "sidekiq-cron"
|
7
|
+
rescue LoadError
|
8
|
+
return
|
9
|
+
end
|
10
|
+
|
11
|
+
module Sentry
|
12
|
+
module Sidekiq
|
13
|
+
module Cron
|
14
|
+
module Job
|
15
|
+
def self.enqueueing_method
|
16
|
+
::Sidekiq::Cron::Job.instance_methods.include?(:enque!) ? :enque! : :enqueue!
|
17
|
+
end
|
18
|
+
|
19
|
+
define_method(enqueueing_method) do |*args|
|
20
|
+
# make sure the current thread has a clean hub
|
21
|
+
Sentry.clone_hub_to_current_thread
|
22
|
+
|
23
|
+
Sentry.with_scope do |scope|
|
24
|
+
Sentry.with_session_tracking do
|
25
|
+
begin
|
26
|
+
scope.set_transaction_name("#{name} (#{klass})")
|
27
|
+
|
28
|
+
transaction = start_transaction(scope)
|
29
|
+
scope.set_span(transaction) if transaction
|
30
|
+
super(*args)
|
31
|
+
|
32
|
+
finish_transaction(transaction, 200)
|
33
|
+
rescue
|
34
|
+
finish_transaction(transaction, 500)
|
35
|
+
raise
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def save
|
42
|
+
# validation failed, do nothing
|
43
|
+
return false unless super
|
44
|
+
|
45
|
+
# fail gracefully if can't find class
|
46
|
+
klass_const =
|
47
|
+
begin
|
48
|
+
if ::Sidekiq::Cron::Support.respond_to?(:safe_constantize)
|
49
|
+
::Sidekiq::Cron::Support.safe_constantize(klass.to_s)
|
50
|
+
else
|
51
|
+
::Sidekiq::Cron::Support.constantize(klass.to_s)
|
52
|
+
end
|
53
|
+
rescue NameError
|
54
|
+
return true
|
55
|
+
end
|
56
|
+
|
57
|
+
return true if klass_const.nil? # Sidekiq::Cron returns nil if class is not found
|
58
|
+
|
59
|
+
# only patch if not explicitly included in job by user
|
60
|
+
unless klass_const.send(:ancestors).include?(Sentry::Cron::MonitorCheckIns)
|
61
|
+
klass_const.send(:include, Sentry::Cron::MonitorCheckIns)
|
62
|
+
klass_const.send(:sentry_monitor_check_ins,
|
63
|
+
slug: name.to_s,
|
64
|
+
monitor_config: Sentry::Sidekiq::Cron::Helpers.monitor_config(parsed_cron.original))
|
65
|
+
end
|
66
|
+
|
67
|
+
true
|
68
|
+
end
|
69
|
+
|
70
|
+
def start_transaction(scope)
|
71
|
+
Sentry.start_transaction(
|
72
|
+
name: scope.transaction_name,
|
73
|
+
source: scope.transaction_source,
|
74
|
+
op: "queue.sidekiq-cron",
|
75
|
+
origin: "auto.queue.sidekiq.cron"
|
76
|
+
)
|
77
|
+
end
|
78
|
+
|
79
|
+
def finish_transaction(transaction, status_code)
|
80
|
+
return unless transaction
|
81
|
+
|
82
|
+
transaction.set_http_status(status_code)
|
83
|
+
transaction.finish
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
Sentry.register_patch(:sidekiq_cron, Sentry::Sidekiq::Cron::Job, ::Sidekiq::Cron::Job)
|
@@ -1,11 +1,19 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "sentry/sidekiq/context_filter"
|
2
4
|
|
3
5
|
module Sentry
|
4
6
|
module Sidekiq
|
5
7
|
class ErrorHandler
|
6
8
|
WITH_SIDEKIQ_7 = ::Gem::Version.new(::Sidekiq::VERSION) >= ::Gem::Version.new("7.0")
|
7
9
|
|
8
|
-
|
10
|
+
# @param ex [Exception] the exception / error that occured
|
11
|
+
# @param context [Hash or Array] Sidekiq error context
|
12
|
+
# @param sidekiq_config [Sidekiq::Config, Hash] Sidekiq configuration,
|
13
|
+
# Defaults to nil.
|
14
|
+
# Sidekiq will pass the config in starting Sidekiq 7.1.5, see
|
15
|
+
# https://github.com/sidekiq/sidekiq/pull/6051
|
16
|
+
def call(ex, context, sidekiq_config = nil)
|
9
17
|
return unless Sentry.initialized?
|
10
18
|
|
11
19
|
context_filter = Sentry::Sidekiq::ContextFilter.new(context)
|
@@ -13,13 +21,32 @@ module Sentry
|
|
13
21
|
scope = Sentry.get_current_scope
|
14
22
|
scope.set_transaction_name(context_filter.transaction_name, source: :task) unless scope.transaction_name
|
15
23
|
|
24
|
+
# If Sentry is configured to only report an error _after_ all retries have been exhausted,
|
25
|
+
# and if the job is retryable, and have not exceeded the retry_limit,
|
26
|
+
# return early.
|
16
27
|
if Sentry.configuration.sidekiq.report_after_job_retries && retryable?(context)
|
17
28
|
retry_count = context.dig(:job, "retry_count")
|
18
|
-
if retry_count.nil? || retry_count < retry_limit(context) - 1
|
29
|
+
if retry_count.nil? || retry_count < retry_limit(context, sidekiq_config) - 1
|
19
30
|
return
|
20
31
|
end
|
21
32
|
end
|
22
33
|
|
34
|
+
# See if we want to ignore jobs that have dead: false
|
35
|
+
return if Sentry.configuration.sidekiq.report_only_dead_jobs && context.dig(:job, "dead") == false
|
36
|
+
|
37
|
+
# Check if the retry count is below the attempt_threshold
|
38
|
+
attempt_threshold = context.dig(:job, "attempt_threshold")
|
39
|
+
if attempt_threshold && retryable?(context)
|
40
|
+
attempt_threshold = attempt_threshold.to_i
|
41
|
+
retry_count = context.dig(:job, "retry_count")
|
42
|
+
# attempt 1 - retry_count is nil
|
43
|
+
# attempt 2 - this is your first retry so retry_count is 0
|
44
|
+
# attempt 3 - you have retried once, retry_count is 1
|
45
|
+
attempt = retry_count.nil? ? 1 : retry_count.to_i + 2
|
46
|
+
|
47
|
+
return if attempt < attempt_threshold
|
48
|
+
end
|
49
|
+
|
23
50
|
Sentry::Sidekiq.capture_exception(
|
24
51
|
ex,
|
25
52
|
contexts: { sidekiq: context_filter.filtered },
|
@@ -37,7 +64,10 @@ module Sentry
|
|
37
64
|
retry_option == true || (retry_option.is_a?(Integer) && retry_option.positive?)
|
38
65
|
end
|
39
66
|
|
40
|
-
|
67
|
+
# @return [Integer] the number of retries allowed for the job
|
68
|
+
# Tries to fetch the retry limit from the job config first,
|
69
|
+
# then falls back to Sidekiq's configuration.
|
70
|
+
def retry_limit(context, sidekiq_config)
|
41
71
|
limit = context.dig(:job, "retry")
|
42
72
|
|
43
73
|
case limit
|
@@ -46,7 +76,11 @@ module Sentry
|
|
46
76
|
when TrueClass
|
47
77
|
max_retries =
|
48
78
|
if WITH_SIDEKIQ_7
|
49
|
-
|
79
|
+
# Sidekiq 7.1.5+ passes the config to the error handler, so we should use that.
|
80
|
+
# Sidekiq 7.0 -> 7.1.5 provides ::Sidekiq.default_configuration.
|
81
|
+
sidekiq_config.is_a?(::Sidekiq::Config) ?
|
82
|
+
sidekiq_config[:max_retries] :
|
83
|
+
::Sidekiq.default_configuration[:max_retries]
|
50
84
|
else
|
51
85
|
::Sidekiq.options[:max_retries]
|
52
86
|
end
|
@@ -1,11 +1,41 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "sentry/sidekiq/context_filter"
|
2
4
|
|
3
5
|
module Sentry
|
4
6
|
module Sidekiq
|
7
|
+
module Helpers
|
8
|
+
def set_span_data(span, id:, queue:, latency: nil, retry_count: nil)
|
9
|
+
return unless span
|
10
|
+
|
11
|
+
span.set_data(Span::DataConventions::MESSAGING_MESSAGE_ID, id)
|
12
|
+
span.set_data(Span::DataConventions::MESSAGING_DESTINATION_NAME, queue)
|
13
|
+
span.set_data(Span::DataConventions::MESSAGING_MESSAGE_RECEIVE_LATENCY, latency) if latency
|
14
|
+
span.set_data(Span::DataConventions::MESSAGING_MESSAGE_RETRY_COUNT, retry_count) if retry_count
|
15
|
+
end
|
16
|
+
|
17
|
+
if ::Gem::Version.new(::Sidekiq::VERSION) >= ::Gem::Version.new("8.0.0")
|
18
|
+
def calculate_latency(job)
|
19
|
+
now_in_ms - job["enqueued_at"] if job["enqueued_at"]
|
20
|
+
end
|
21
|
+
else
|
22
|
+
def calculate_latency(job)
|
23
|
+
((Time.now.to_f - job["enqueued_at"]) * 1000).round if job["enqueued_at"]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def now_in_ms
|
28
|
+
::Process.clock_gettime(::Process::CLOCK_REALTIME, :millisecond)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
5
32
|
class SentryContextServerMiddleware
|
6
|
-
|
33
|
+
include Sentry::Sidekiq::Helpers
|
34
|
+
|
35
|
+
OP_NAME = "queue.process"
|
36
|
+
SPAN_ORIGIN = "auto.queue.sidekiq"
|
7
37
|
|
8
|
-
def call(
|
38
|
+
def call(worker, job, queue)
|
9
39
|
return yield unless Sentry.initialized?
|
10
40
|
|
11
41
|
context_filter = Sentry::Sidekiq::ContextFilter.new(job)
|
@@ -19,8 +49,21 @@ module Sentry
|
|
19
49
|
scope.set_tags(build_tags(job["tags"]))
|
20
50
|
scope.set_contexts(sidekiq: job.merge("queue" => queue))
|
21
51
|
scope.set_transaction_name(context_filter.transaction_name, source: :task)
|
22
|
-
transaction = start_transaction(scope, job["
|
23
|
-
|
52
|
+
transaction = start_transaction(scope, job["trace_propagation_headers"])
|
53
|
+
|
54
|
+
if transaction
|
55
|
+
scope.set_span(transaction)
|
56
|
+
|
57
|
+
latency = calculate_latency(job)
|
58
|
+
|
59
|
+
set_span_data(
|
60
|
+
transaction,
|
61
|
+
id: job["jid"],
|
62
|
+
queue: queue,
|
63
|
+
latency: latency,
|
64
|
+
retry_count: job["retry_count"] || 0
|
65
|
+
)
|
66
|
+
end
|
24
67
|
|
25
68
|
begin
|
26
69
|
yield
|
@@ -39,9 +82,15 @@ module Sentry
|
|
39
82
|
Array(tags).each_with_object({}) { |name, tags_hash| tags_hash[:"sidekiq.#{name}"] = true }
|
40
83
|
end
|
41
84
|
|
42
|
-
def start_transaction(scope,
|
43
|
-
options = {
|
44
|
-
|
85
|
+
def start_transaction(scope, env)
|
86
|
+
options = {
|
87
|
+
name: scope.transaction_name,
|
88
|
+
source: scope.transaction_source,
|
89
|
+
op: OP_NAME,
|
90
|
+
origin: SPAN_ORIGIN
|
91
|
+
}
|
92
|
+
|
93
|
+
transaction = Sentry.continue_trace(env, **options)
|
45
94
|
Sentry.start_transaction(transaction: transaction, **options)
|
46
95
|
end
|
47
96
|
|
@@ -54,14 +103,23 @@ module Sentry
|
|
54
103
|
end
|
55
104
|
|
56
105
|
class SentryContextClientMiddleware
|
57
|
-
|
106
|
+
include Sentry::Sidekiq::Helpers
|
107
|
+
|
108
|
+
def call(worker_class, job, queue, _redis_pool)
|
58
109
|
return yield unless Sentry.initialized?
|
59
110
|
|
60
111
|
user = Sentry.get_current_scope.user
|
61
|
-
transaction = Sentry.get_current_scope.get_transaction
|
62
112
|
job["sentry_user"] = user unless user.empty?
|
63
|
-
|
64
|
-
|
113
|
+
|
114
|
+
if Sentry.configuration.sidekiq.propagate_traces
|
115
|
+
job["trace_propagation_headers"] ||= Sentry.get_trace_propagation_headers
|
116
|
+
end
|
117
|
+
|
118
|
+
Sentry.with_child_span(op: "queue.publish", description: worker_class.to_s) do |span|
|
119
|
+
set_span_data(span, id: job["jid"], queue: queue)
|
120
|
+
|
121
|
+
yield
|
122
|
+
end
|
65
123
|
end
|
66
124
|
end
|
67
125
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Try to require sidekiq-scheduler to make sure it's loaded before the integration.
|
4
|
+
begin
|
5
|
+
require "sidekiq-scheduler"
|
6
|
+
rescue LoadError
|
7
|
+
return
|
8
|
+
end
|
9
|
+
|
10
|
+
# If we've loaded sidekiq-scheduler, but the API changed,
|
11
|
+
# and the Scheduler class is not there, fail gracefully.
|
12
|
+
return unless defined?(::SidekiqScheduler::Scheduler)
|
13
|
+
|
14
|
+
module Sentry
|
15
|
+
module SidekiqScheduler
|
16
|
+
module Scheduler
|
17
|
+
def new_job(name, interval_type, config, schedule, options)
|
18
|
+
# Schedule the job upstream first
|
19
|
+
# SidekiqScheduler does not validate schedules
|
20
|
+
# It will fail with an error if the schedule in the config is invalid.
|
21
|
+
# If this errors out, let it fall through.
|
22
|
+
rufus_job = super
|
23
|
+
|
24
|
+
klass = config.fetch("class")
|
25
|
+
return rufus_job unless klass
|
26
|
+
|
27
|
+
# Constantize the job class, and fail gracefully if it could not be found
|
28
|
+
klass_const =
|
29
|
+
begin
|
30
|
+
Object.const_get(klass)
|
31
|
+
rescue NameError
|
32
|
+
return rufus_job
|
33
|
+
end
|
34
|
+
|
35
|
+
# For cron, every, or interval jobs — grab their schedule.
|
36
|
+
# Rufus::Scheduler::EveryJob stores it's frequency in seconds,
|
37
|
+
# so we convert it to minutes before passing in to the monitor.
|
38
|
+
monitor_config =
|
39
|
+
case interval_type
|
40
|
+
when "cron"
|
41
|
+
Sentry::Sidekiq::Cron::Helpers.monitor_config(schedule)
|
42
|
+
when "every", "interval"
|
43
|
+
Sentry::Cron::MonitorConfig.from_interval(rufus_job.frequency.to_i / 60, :minute)
|
44
|
+
end
|
45
|
+
|
46
|
+
# If we couldn't build a monitor config, it's either an error, or
|
47
|
+
# it's a one-time job (interval_type is in, or at), in which case
|
48
|
+
# we should not make a monitof for it automaticaly.
|
49
|
+
return rufus_job if monitor_config.nil?
|
50
|
+
|
51
|
+
# only patch if not explicitly included in job by user
|
52
|
+
unless klass_const.send(:ancestors).include?(Sentry::Cron::MonitorCheckIns)
|
53
|
+
klass_const.send(:include, Sentry::Cron::MonitorCheckIns)
|
54
|
+
slug = klass_const.send(:sentry_monitor_slug, name: name)
|
55
|
+
klass_const.send(:sentry_monitor_check_ins,
|
56
|
+
slug: slug,
|
57
|
+
monitor_config: monitor_config)
|
58
|
+
|
59
|
+
::Sidekiq.logger.info "Injected Sentry Crons monitor checkins into #{klass}"
|
60
|
+
end
|
61
|
+
|
62
|
+
rufus_job
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
Sentry.register_patch(:sidekiq_scheduler, Sentry::SidekiqScheduler::Scheduler, ::SidekiqScheduler::Scheduler)
|
data/lib/sentry-sidekiq.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "sidekiq"
|
2
4
|
require "sentry-ruby"
|
3
5
|
require "sentry/integrable"
|
@@ -39,3 +41,8 @@ Sidekiq.configure_client do |config|
|
|
39
41
|
chain.add Sentry::Sidekiq::SentryContextClientMiddleware
|
40
42
|
end
|
41
43
|
end
|
44
|
+
|
45
|
+
# patches
|
46
|
+
require "sentry/sidekiq/cron/helpers"
|
47
|
+
require "sentry/sidekiq/cron/job"
|
48
|
+
require "sentry/sidekiq-scheduler/scheduler"
|
data/sentry-sidekiq.gemspec
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "lib/sentry/sidekiq/version"
|
2
4
|
|
3
5
|
Gem::Specification.new do |spec|
|
@@ -7,21 +9,27 @@ Gem::Specification.new do |spec|
|
|
7
9
|
spec.description = spec.summary = "A gem that provides Sidekiq integration for the Sentry error logger"
|
8
10
|
spec.email = "accounts@sentry.io"
|
9
11
|
spec.license = 'MIT'
|
10
|
-
spec.homepage = "https://github.com/getsentry/sentry-ruby"
|
11
12
|
|
12
13
|
spec.platform = Gem::Platform::RUBY
|
13
14
|
spec.required_ruby_version = '>= 2.4'
|
14
15
|
spec.extra_rdoc_files = ["README.md", "LICENSE.txt"]
|
15
|
-
spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples)'`.split("\n")
|
16
|
+
spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples|\.rubocop\.yml)'`.split("\n")
|
17
|
+
|
18
|
+
github_root_uri = 'https://github.com/getsentry/sentry-ruby'
|
19
|
+
spec.homepage = "#{github_root_uri}/tree/#{spec.version}/#{spec.name}"
|
16
20
|
|
17
|
-
spec.metadata
|
18
|
-
|
19
|
-
|
21
|
+
spec.metadata = {
|
22
|
+
"homepage_uri" => spec.homepage,
|
23
|
+
"source_code_uri" => spec.homepage,
|
24
|
+
"changelog_uri" => "#{github_root_uri}/blob/#{spec.version}/CHANGELOG.md",
|
25
|
+
"bug_tracker_uri" => "#{github_root_uri}/issues",
|
26
|
+
"documentation_uri" => "http://www.rubydoc.info/gems/#{spec.name}/#{spec.version}"
|
27
|
+
}
|
20
28
|
|
21
29
|
spec.bindir = "exe"
|
22
30
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
31
|
spec.require_paths = ["lib"]
|
24
32
|
|
25
|
-
spec.add_dependency "sentry-ruby", "~> 5.
|
33
|
+
spec.add_dependency "sentry-ruby", "~> 5.26.0"
|
26
34
|
spec.add_dependency "sidekiq", ">= 3.0"
|
27
35
|
end
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sentry-sidekiq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.26.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sentry Team
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: sentry-ruby
|
@@ -16,14 +15,14 @@ dependencies:
|
|
16
15
|
requirements:
|
17
16
|
- - "~>"
|
18
17
|
- !ruby/object:Gem::Version
|
19
|
-
version: 5.
|
18
|
+
version: 5.26.0
|
20
19
|
type: :runtime
|
21
20
|
prerelease: false
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
23
22
|
requirements:
|
24
23
|
- - "~>"
|
25
24
|
- !ruby/object:Gem::Version
|
26
|
-
version: 5.
|
25
|
+
version: 5.26.0
|
27
26
|
- !ruby/object:Gem::Dependency
|
28
27
|
name: sidekiq
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
@@ -43,8 +42,8 @@ email: accounts@sentry.io
|
|
43
42
|
executables: []
|
44
43
|
extensions: []
|
45
44
|
extra_rdoc_files:
|
46
|
-
- README.md
|
47
45
|
- LICENSE.txt
|
46
|
+
- README.md
|
48
47
|
files:
|
49
48
|
- ".gitignore"
|
50
49
|
- ".rspec"
|
@@ -61,20 +60,24 @@ files:
|
|
61
60
|
- example/config/sidekiq.yml
|
62
61
|
- example/error_worker.rb
|
63
62
|
- lib/sentry-sidekiq.rb
|
63
|
+
- lib/sentry/sidekiq-scheduler/scheduler.rb
|
64
64
|
- lib/sentry/sidekiq/configuration.rb
|
65
65
|
- lib/sentry/sidekiq/context_filter.rb
|
66
|
+
- lib/sentry/sidekiq/cron/helpers.rb
|
67
|
+
- lib/sentry/sidekiq/cron/job.rb
|
66
68
|
- lib/sentry/sidekiq/error_handler.rb
|
67
69
|
- lib/sentry/sidekiq/sentry_context_middleware.rb
|
68
70
|
- lib/sentry/sidekiq/version.rb
|
69
71
|
- sentry-sidekiq.gemspec
|
70
|
-
homepage: https://github.com/getsentry/sentry-ruby
|
72
|
+
homepage: https://github.com/getsentry/sentry-ruby/tree/5.26.0/sentry-sidekiq
|
71
73
|
licenses:
|
72
74
|
- MIT
|
73
75
|
metadata:
|
74
|
-
homepage_uri: https://github.com/getsentry/sentry-ruby
|
75
|
-
source_code_uri: https://github.com/getsentry/sentry-ruby
|
76
|
-
changelog_uri: https://github.com/getsentry/sentry-ruby/blob/
|
77
|
-
|
76
|
+
homepage_uri: https://github.com/getsentry/sentry-ruby/tree/5.26.0/sentry-sidekiq
|
77
|
+
source_code_uri: https://github.com/getsentry/sentry-ruby/tree/5.26.0/sentry-sidekiq
|
78
|
+
changelog_uri: https://github.com/getsentry/sentry-ruby/blob/5.26.0/CHANGELOG.md
|
79
|
+
bug_tracker_uri: https://github.com/getsentry/sentry-ruby/issues
|
80
|
+
documentation_uri: http://www.rubydoc.info/gems/sentry-sidekiq/5.26.0
|
78
81
|
rdoc_options: []
|
79
82
|
require_paths:
|
80
83
|
- lib
|
@@ -89,8 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
92
|
- !ruby/object:Gem::Version
|
90
93
|
version: '0'
|
91
94
|
requirements: []
|
92
|
-
rubygems_version: 3.
|
93
|
-
signing_key:
|
95
|
+
rubygems_version: 3.6.7
|
94
96
|
specification_version: 4
|
95
97
|
summary: A gem that provides Sidekiq integration for the Sentry error logger
|
96
98
|
test_files: []
|