sidekiq 8.0.0.beta2 → 8.0.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/Changes.md +13 -2
- data/README.md +1 -1
- data/lib/sidekiq/job_logger.rb +4 -4
- data/lib/sidekiq/logger.rb +17 -64
- data/lib/sidekiq/metrics/shared.rb +4 -4
- data/lib/sidekiq/redis_connection.rb +14 -3
- data/lib/sidekiq/version.rb +1 -1
- data/lib/sidekiq/web/application.rb +4 -4
- data/lib/sidekiq/web/config.rb +2 -1
- data/lib/sidekiq/web.rb +1 -2
- data/sidekiq.gemspec +1 -2
- metadata +4 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e6ce813e475bd69e3cb05f0ebe216e1dcbd6b4865584a4761c889a97761d5fe1
|
4
|
+
data.tar.gz: 855e4b4db0b7c080f9a4347c338eff1c4b62be91e233d0e20447b15a3251756a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 20f3dfd6b5e9aba7f8d2a0ef0fb9bef6ee7918aa31a8deee0bc592dcd957e44c08ca5d6a30e16064c81a5f68bc571fe8585c2e3ba453a81db0d565862e67454b
|
7
|
+
data.tar.gz: cdfea6f26e591ac0fb7c4bfe8874d8272615b27bfdd91daef13d1620e902fd5ba8a3c818d70a5729a89104c6ae7ac576c0f0df65717f514999d5c1c651605bd8
|
data/Changes.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[Sidekiq Changes](https://github.com/sidekiq/sidekiq/blob/main/Changes.md) | [Sidekiq Pro Changes](https://github.com/sidekiq/sidekiq/blob/main/Pro-Changes.md) | [Sidekiq Enterprise Changes](https://github.com/sidekiq/sidekiq/blob/main/Ent-Changes.md)
|
4
4
|
|
5
|
-
|
5
|
+
8.0.0
|
6
6
|
----------
|
7
7
|
|
8
8
|
- **WARNING** The underlying class name for Active Jobs has changed from `ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper` to `Sidekiq::ActiveJob::Wrapper`.
|
@@ -26,14 +26,25 @@ HEAD / main
|
|
26
26
|
- Job tags now allow custom CSS display [#6595]
|
27
27
|
- The Web UI's language picker now shows options in the native language
|
28
28
|
- Remove global variable usage within the codebase
|
29
|
+
- Colorize and adjust logging for easier reading
|
29
30
|
- Adjust Sidekiq's default thread priority to -1 for a 50ms timeslice.
|
30
31
|
This can help avoid TimeoutErrors when Sidekiq is overloaded. [#6543]
|
31
|
-
-
|
32
|
+
- Use `Logger#with_level`, remove Sidekiq's custom impl
|
33
|
+
- Remove `base64` gem dependency
|
34
|
+
- Support: (Dragonfly 1.27+, Valkey 7.2+, Redis 7.2+), Ruby 3.2+, Rails 7.0+
|
35
|
+
|
36
|
+
7.3.10
|
37
|
+
----------
|
38
|
+
|
39
|
+
- Deprecate Redis :password as a String to avoid log disclosure. [#6625]
|
40
|
+
Use a Proc instead: `config.redis = { password: ->(username) { "password" } }`
|
32
41
|
|
33
42
|
7.3.9
|
34
43
|
----------
|
35
44
|
|
36
45
|
- Only require activejob if necessary [#6584]
|
46
|
+
You might get `uninitialized constant Sidekiq::ActiveJob` if you
|
47
|
+
`require 'sidekiq'` before `require 'rails'`.
|
37
48
|
- Fix iterable job cancellation [#6589]
|
38
49
|
- Web UI accessibility improvements [#6604]
|
39
50
|
|
data/README.md
CHANGED
@@ -13,7 +13,7 @@ same process. Sidekiq can be used by any Ruby application.
|
|
13
13
|
Requirements
|
14
14
|
-----------------
|
15
15
|
|
16
|
-
- Redis: Redis 7.2+, Valkey 7.2+ or Dragonfly 1.
|
16
|
+
- Redis: Redis 7.2+, Valkey 7.2+ or Dragonfly 1.27+
|
17
17
|
- Ruby: MRI 3.2+ or JRuby 9.4+.
|
18
18
|
|
19
19
|
Sidekiq 8.0 supports Rails and Active Job 7.0+.
|
data/lib/sidekiq/job_logger.rb
CHANGED
@@ -26,16 +26,16 @@ module Sidekiq
|
|
26
26
|
# If we're using a wrapper class, like ActiveJob, use the "wrapped"
|
27
27
|
# attribute to expose the underlying thing.
|
28
28
|
h = {
|
29
|
-
|
30
|
-
|
29
|
+
jid: job_hash["jid"],
|
30
|
+
class: job_hash["display_class"] || job_hash["wrapped"] || job_hash["class"]
|
31
31
|
}
|
32
32
|
h[:bid] = job_hash["bid"] if job_hash.has_key?("bid")
|
33
33
|
h[:tags] = job_hash["tags"] if job_hash.has_key?("tags")
|
34
34
|
|
35
35
|
Thread.current[:sidekiq_context] = h
|
36
36
|
level = job_hash["log_level"]
|
37
|
-
if level
|
38
|
-
@logger.
|
37
|
+
if level
|
38
|
+
@logger.with_level(level, &block)
|
39
39
|
else
|
40
40
|
yield
|
41
41
|
end
|
data/lib/sidekiq/logger.rb
CHANGED
@@ -22,88 +22,41 @@ module Sidekiq
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
module LoggingUtils
|
26
|
-
LEVELS = {
|
27
|
-
"debug" => 0,
|
28
|
-
"info" => 1,
|
29
|
-
"warn" => 2,
|
30
|
-
"error" => 3,
|
31
|
-
"fatal" => 4
|
32
|
-
}
|
33
|
-
LEVELS.default_proc = proc do |_, level|
|
34
|
-
puts("Invalid log level: #{level.inspect}")
|
35
|
-
nil
|
36
|
-
end
|
37
|
-
|
38
|
-
LEVELS.each do |level, numeric_level|
|
39
|
-
define_method(:"#{level}?") do
|
40
|
-
local_level.nil? ? super() : local_level <= numeric_level
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def local_level
|
45
|
-
Thread.current[:sidekiq_log_level]
|
46
|
-
end
|
47
|
-
|
48
|
-
def local_level=(level)
|
49
|
-
case level
|
50
|
-
when Integer
|
51
|
-
Thread.current[:sidekiq_log_level] = level
|
52
|
-
when Symbol, String
|
53
|
-
Thread.current[:sidekiq_log_level] = LEVELS[level.to_s]
|
54
|
-
when nil
|
55
|
-
Thread.current[:sidekiq_log_level] = nil
|
56
|
-
else
|
57
|
-
raise ArgumentError, "Invalid log level: #{level.inspect}"
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def level
|
62
|
-
local_level || super
|
63
|
-
end
|
64
|
-
|
65
|
-
# Change the thread-local level for the duration of the given block.
|
66
|
-
def log_at(level)
|
67
|
-
old_local_level = local_level
|
68
|
-
self.local_level = level
|
69
|
-
yield
|
70
|
-
ensure
|
71
|
-
self.local_level = old_local_level
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
25
|
class Logger < ::Logger
|
76
|
-
include LoggingUtils
|
77
|
-
|
78
26
|
module Formatters
|
27
|
+
COLORS = {
|
28
|
+
"DEBUG" => "\e[1;32mDEBUG\e[0m", # green
|
29
|
+
"INFO" => "\e[1;34mINFO \e[0m", # blue
|
30
|
+
"WARN" => "\e[1;33mWARN \e[0m", # yellow
|
31
|
+
"ERROR" => "\e[1;31mERROR\e[0m", # red
|
32
|
+
"FATAL" => "\e[1;35mFATAL\e[0m" # pink
|
33
|
+
}
|
79
34
|
class Base < ::Logger::Formatter
|
80
35
|
def tid
|
81
36
|
Thread.current["sidekiq_tid"] ||= (Thread.current.object_id ^ ::Process.pid).to_s(36)
|
82
37
|
end
|
83
38
|
|
84
39
|
def format_context(ctxt = Sidekiq::Context.current)
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
}.join(" ")
|
94
|
-
end
|
40
|
+
(ctxt.size == 0) ? "" : " #{ctxt.map { |k, v|
|
41
|
+
case v
|
42
|
+
when Array
|
43
|
+
"#{k}=#{v.join(",")}"
|
44
|
+
else
|
45
|
+
"#{k}=#{v}"
|
46
|
+
end
|
47
|
+
}.join(" ")}"
|
95
48
|
end
|
96
49
|
end
|
97
50
|
|
98
51
|
class Pretty < Base
|
99
52
|
def call(severity, time, program_name, message)
|
100
|
-
"#{time.utc.iso8601(3)} pid=#{::Process.pid} tid=#{tid}
|
53
|
+
"#{Formatters::COLORS[severity]} #{time.utc.iso8601(3)} pid=#{::Process.pid} tid=#{tid}#{format_context}: #{message}\n"
|
101
54
|
end
|
102
55
|
end
|
103
56
|
|
104
57
|
class WithoutTimestamp < Pretty
|
105
58
|
def call(severity, time, program_name, message)
|
106
|
-
"pid=#{::Process.pid} tid=#{tid} #{format_context}
|
59
|
+
"#{Formatters::COLORS[severity]} pid=#{::Process.pid} tid=#{tid} #{format_context}: #{message}\n"
|
107
60
|
end
|
108
61
|
end
|
109
62
|
|
@@ -85,15 +85,15 @@ module Sidekiq
|
|
85
85
|
end
|
86
86
|
|
87
87
|
def fetch(conn, now = Time.now)
|
88
|
-
window = now.utc.strftime("
|
89
|
-
key = "
|
88
|
+
window = now.utc.strftime("%-d-%-H:%-M")
|
89
|
+
key = "h|#{@klass}-#{window}"
|
90
90
|
conn.bitfield_ro(key, *FETCH)
|
91
91
|
end
|
92
92
|
|
93
93
|
def persist(conn, now = Time.now)
|
94
94
|
buckets, @buckets = @buckets, []
|
95
|
-
window = now.utc.strftime("
|
96
|
-
key = "
|
95
|
+
window = now.utc.strftime("%-d-%-H:%-M")
|
96
|
+
key = "h|#{@klass}-#{window}"
|
97
97
|
cmd = [key, "OVERFLOW", "SAT"]
|
98
98
|
buckets.each_with_index do |counter, idx|
|
99
99
|
val = counter.value
|
@@ -10,6 +10,8 @@ module Sidekiq
|
|
10
10
|
def create(options = {})
|
11
11
|
symbolized_options = deep_symbolize_keys(options)
|
12
12
|
symbolized_options[:url] ||= determine_redis_provider
|
13
|
+
symbolized_options[:password] = wrap(symbolized_options[:password]) if symbolized_options.key?(:password)
|
14
|
+
symbolized_options[:sentinel_password] = wrap(symbolized_options[:sentinel_password]) if symbolized_options.key?(:sentinel_password)
|
13
15
|
|
14
16
|
logger = symbolized_options.delete(:logger)
|
15
17
|
logger&.info { "Sidekiq #{Sidekiq::VERSION} connecting to Redis with options #{scrub(symbolized_options)}" }
|
@@ -38,6 +40,15 @@ module Sidekiq
|
|
38
40
|
|
39
41
|
private
|
40
42
|
|
43
|
+
# Wrap hard-coded passwords in a Proc to avoid logging the value
|
44
|
+
def wrap(pwd)
|
45
|
+
if pwd.is_a?(String)
|
46
|
+
->(username) { pwd }
|
47
|
+
else
|
48
|
+
pwd
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
41
52
|
def deep_symbolize_keys(object)
|
42
53
|
case object
|
43
54
|
when Hash
|
@@ -57,14 +68,14 @@ module Sidekiq
|
|
57
68
|
# Deep clone so we can muck with these options all we want and exclude
|
58
69
|
# params from dump-and-load that may contain objects that Marshal is
|
59
70
|
# unable to safely dump.
|
60
|
-
keys = options.keys - [:logger, :ssl_params]
|
71
|
+
keys = options.keys - [:logger, :ssl_params, :password, :sentinel_password]
|
61
72
|
scrubbed_options = Marshal.load(Marshal.dump(options.slice(*keys)))
|
62
73
|
if scrubbed_options[:url] && (uri = URI.parse(scrubbed_options[:url])) && uri.password
|
63
74
|
uri.password = redacted
|
64
75
|
scrubbed_options[:url] = uri.to_s
|
65
76
|
end
|
66
|
-
scrubbed_options[:password] = redacted if
|
67
|
-
scrubbed_options[:sentinel_password] = redacted if
|
77
|
+
scrubbed_options[:password] = redacted if options.key?(:password)
|
78
|
+
scrubbed_options[:sentinel_password] = redacted if options.key?(:sentinel_password)
|
68
79
|
scrubbed_options[:sentinels]&.each do |sentinel|
|
69
80
|
if sentinel.is_a?(String)
|
70
81
|
if (uri = URI(sentinel)) && uri.password
|
data/lib/sidekiq/version.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "base64"
|
4
3
|
require "sidekiq/paginator"
|
5
4
|
require "sidekiq/web/helpers"
|
6
5
|
|
@@ -50,7 +49,7 @@ module Sidekiq
|
|
50
49
|
end
|
51
50
|
|
52
51
|
get "/" do
|
53
|
-
@redis_info = redis_info.
|
52
|
+
@redis_info = redis_info.slice(*REDIS_KEYS)
|
54
53
|
days = (url_params("days") || 30).to_i
|
55
54
|
return halt(401) if days < 1 || days > 180
|
56
55
|
|
@@ -327,7 +326,7 @@ module Sidekiq
|
|
327
326
|
|
328
327
|
get "/stats" do
|
329
328
|
sidekiq_stats = Sidekiq::Stats.new
|
330
|
-
redis_stats = redis_info.
|
329
|
+
redis_stats = redis_info.slice(*REDIS_KEYS)
|
331
330
|
json(
|
332
331
|
sidekiq: {
|
333
332
|
processed: sidekiq_stats.processed,
|
@@ -368,7 +367,8 @@ module Sidekiq
|
|
368
367
|
{"Accept" => "application/vnd.firefox-profiler+json;version=1.0",
|
369
368
|
"User-Agent" => "Sidekiq #{Sidekiq::VERSION} job profiler"})
|
370
369
|
# https://raw.githubusercontent.com/firefox-devtools/profiler-server/master/tools/decode_jwt_payload.py
|
371
|
-
|
370
|
+
rawjson = resp.body.split(".")[1].unpack1("m")
|
371
|
+
sid = Sidekiq.load_json(rawjson)["profileToken"]
|
372
372
|
Sidekiq.redis { |c| c.hset(key, "sid", sid) }
|
373
373
|
end
|
374
374
|
url = config[:profile_view_url] % sid
|
data/lib/sidekiq/web/config.rb
CHANGED
@@ -14,7 +14,8 @@ module Sidekiq
|
|
14
14
|
#
|
15
15
|
# This should go in your `config/routes.rb` or similar. It
|
16
16
|
# does not belong in your initializer since Web should not be
|
17
|
-
# loaded in some processes (like an actual Sidekiq process)
|
17
|
+
# loaded in some processes (like an actual Sidekiq process).
|
18
|
+
# See `examples/webui-ext` for a sample web extension.
|
18
19
|
class Config
|
19
20
|
extend Forwardable
|
20
21
|
|
data/lib/sidekiq/web.rb
CHANGED
@@ -63,8 +63,7 @@ module Sidekiq
|
|
63
63
|
def use(*args, &block) = @@config.middlewares << [args, block]
|
64
64
|
|
65
65
|
def register(*args, **kw, &block)
|
66
|
-
|
67
|
-
puts "`Sidekiq::Web.register` is deprecated, use `Sidekiq::Web.configure {|cfg| cfg.register(...) }`"
|
66
|
+
Sidekiq.logger.warn { "`Sidekiq::Web.register` is deprecated, use `Sidekiq::Web.configure {|cfg| cfg.register(...) }`" }
|
68
67
|
@@config.register(*args, **kw, &block)
|
69
68
|
end
|
70
69
|
end
|
data/sidekiq.gemspec
CHANGED
@@ -27,6 +27,5 @@ Gem::Specification.new do |gem|
|
|
27
27
|
gem.add_dependency "connection_pool", ">= 2.5.0"
|
28
28
|
gem.add_dependency "rack", ">= 3.1.0"
|
29
29
|
gem.add_dependency "json", ">= 2.9.0"
|
30
|
-
gem.add_dependency "logger"
|
31
|
-
gem.add_dependency "base64"
|
30
|
+
gem.add_dependency "logger", ">= 1.6.2"
|
32
31
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 8.0.0
|
4
|
+
version: 8.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Perham
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-03-05 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: redis-client
|
@@ -71,28 +71,14 @@ dependencies:
|
|
71
71
|
requirements:
|
72
72
|
- - ">="
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
version:
|
74
|
+
version: 1.6.2
|
75
75
|
type: :runtime
|
76
76
|
prerelease: false
|
77
77
|
version_requirements: !ruby/object:Gem::Requirement
|
78
78
|
requirements:
|
79
79
|
- - ">="
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version:
|
82
|
-
- !ruby/object:Gem::Dependency
|
83
|
-
name: base64
|
84
|
-
requirement: !ruby/object:Gem::Requirement
|
85
|
-
requirements:
|
86
|
-
- - ">="
|
87
|
-
- !ruby/object:Gem::Version
|
88
|
-
version: '0'
|
89
|
-
type: :runtime
|
90
|
-
prerelease: false
|
91
|
-
version_requirements: !ruby/object:Gem::Requirement
|
92
|
-
requirements:
|
93
|
-
- - ">="
|
94
|
-
- !ruby/object:Gem::Version
|
95
|
-
version: '0'
|
81
|
+
version: 1.6.2
|
96
82
|
description: Simple, efficient background processing for Ruby.
|
97
83
|
email:
|
98
84
|
- info@contribsys.com
|