sidekiq-vigil 0.1.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 +7 -0
- data/.rubocop.yml +39 -0
- data/LICENSE.txt +21 -0
- data/README.md +237 -0
- data/Rakefile +10 -0
- data/docs/redis_keys.md +18 -0
- data/docs/webhook_event.schema.json +41 -0
- data/docs/webhook_schema.md +64 -0
- data/exe/vigil +6 -0
- data/lib/generators/sidekiq_vigil/install_generator.rb +32 -0
- data/lib/generators/sidekiq_vigil/templates/sidekiq_vigil.rb +49 -0
- data/lib/sidekiq/vigil/version.rb +7 -0
- data/lib/sidekiq/vigil.rb +7 -0
- data/lib/sidekiq_vigil/alert/cron.rb +106 -0
- data/lib/sidekiq_vigil/alert/event.rb +110 -0
- data/lib/sidekiq_vigil/alert/grouping.rb +15 -0
- data/lib/sidekiq_vigil/alert/manager.rb +227 -0
- data/lib/sidekiq_vigil/alert/mute.rb +69 -0
- data/lib/sidekiq_vigil/alert/state.rb +51 -0
- data/lib/sidekiq_vigil/check/base.rb +52 -0
- data/lib/sidekiq_vigil/check/failure_rate.rb +45 -0
- data/lib/sidekiq_vigil/check/memory.rb +41 -0
- data/lib/sidekiq_vigil/check/process_alive.rb +64 -0
- data/lib/sidekiq_vigil/check/queue_latency.rb +21 -0
- data/lib/sidekiq_vigil/check/queue_size.rb +20 -0
- data/lib/sidekiq_vigil/check/redis_health.rb +55 -0
- data/lib/sidekiq_vigil/check/registry.rb +23 -0
- data/lib/sidekiq_vigil/check/scheduled_backlog.rb +21 -0
- data/lib/sidekiq_vigil/check/set_size.rb +76 -0
- data/lib/sidekiq_vigil/check/stuck_jobs.rb +44 -0
- data/lib/sidekiq_vigil/check/throughput_anomaly.rb +69 -0
- data/lib/sidekiq_vigil/check/utilization.rb +61 -0
- data/lib/sidekiq_vigil/checker.rb +149 -0
- data/lib/sidekiq_vigil/cli.rb +205 -0
- data/lib/sidekiq_vigil/collector.rb +74 -0
- data/lib/sidekiq_vigil/config.rb +267 -0
- data/lib/sidekiq_vigil/health_app.rb +64 -0
- data/lib/sidekiq_vigil/leader_election.rb +54 -0
- data/lib/sidekiq_vigil/middleware/server.rb +37 -0
- data/lib/sidekiq_vigil/notifier/base.rb +22 -0
- data/lib/sidekiq_vigil/notifier/http_transport.rb +32 -0
- data/lib/sidekiq_vigil/notifier/log.rb +14 -0
- data/lib/sidekiq_vigil/notifier/manager.rb +45 -0
- data/lib/sidekiq_vigil/notifier/slack.rb +192 -0
- data/lib/sidekiq_vigil/notifier/webhook.rb +25 -0
- data/lib/sidekiq_vigil/reporter.rb +103 -0
- data/lib/sidekiq_vigil/result.rb +43 -0
- data/lib/sidekiq_vigil/runtime.rb +44 -0
- data/lib/sidekiq_vigil/sidekiq_api.rb +40 -0
- data/lib/sidekiq_vigil/storage.rb +167 -0
- data/lib/sidekiq_vigil/timezone.rb +39 -0
- data/lib/sidekiq_vigil/version.rb +5 -0
- data/lib/sidekiq_vigil.rb +128 -0
- metadata +111 -0
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
|
|
5
|
+
module SidekiqVigil
|
|
6
|
+
class Storage
|
|
7
|
+
class MissingTTL < ArgumentError; end
|
|
8
|
+
class UnmanagedPersistentKey < ArgumentError; end
|
|
9
|
+
|
|
10
|
+
KeyDefinition = Data.define(:pattern, :type, :ttl, :owner)
|
|
11
|
+
KEY_CATALOG = [
|
|
12
|
+
KeyDefinition.new(pattern: "stats:{yyyymmddHHMM}", type: "hash", ttl: "8 days", owner: "Reporter"),
|
|
13
|
+
KeyDefinition.new(pattern: "exec:{queue}", type: "hash", ttl: "1 hour", owner: "Reporter"),
|
|
14
|
+
KeyDefinition.new(pattern: "alerts", type: "hash", ttl: "managed", owner: "Alert::Manager"),
|
|
15
|
+
KeyDefinition.new(pattern: "history:{alert_id}", type: "list", ttl: "24 hours", owner: "Alert::Manager"),
|
|
16
|
+
KeyDefinition.new(pattern: "snapshot", type: "string", ttl: "interval × 4", owner: "Checker"),
|
|
17
|
+
KeyDefinition.new(pattern: "leader", type: "string", ttl: "interval × 3", owner: "LeaderElection"),
|
|
18
|
+
KeyDefinition.new(pattern: "mem:{process_id}", type: "string", ttl: "flush interval × 3", owner: "Reporter"),
|
|
19
|
+
KeyDefinition.new(pattern: "config_digest", type: "hash", ttl: "1 hour", owner: "Reporter"),
|
|
20
|
+
KeyDefinition.new(pattern: "mute", type: "string", ttl: "requested duration", owner: "Alert::Mute"),
|
|
21
|
+
KeyDefinition.new(
|
|
22
|
+
pattern: "check_state:{check-specific-suffix}",
|
|
23
|
+
type: "string",
|
|
24
|
+
ttl: "check-specific",
|
|
25
|
+
owner: "Checks"
|
|
26
|
+
)
|
|
27
|
+
].freeze
|
|
28
|
+
|
|
29
|
+
attr_reader :prefix
|
|
30
|
+
|
|
31
|
+
def initialize(redis: nil, key_prefix: "default")
|
|
32
|
+
@redis = redis
|
|
33
|
+
@prefix = "vigil:#{key_prefix}:"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def key(suffix)
|
|
37
|
+
"#{prefix}#{suffix}"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def set(suffix, value, ttl:)
|
|
41
|
+
require_ttl!(ttl)
|
|
42
|
+
with_redis { |redis| redis.call("SET", key(suffix), value, "PX", ttl_ms(ttl)) }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def get(suffix)
|
|
46
|
+
with_redis { |redis| redis.call("GET", key(suffix)) }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def hash_write(suffix, values, ttl:)
|
|
50
|
+
require_ttl!(ttl)
|
|
51
|
+
return if values.empty?
|
|
52
|
+
|
|
53
|
+
with_redis do |redis|
|
|
54
|
+
redis.pipelined do |pipeline|
|
|
55
|
+
pipeline.call("HSET", key(suffix), *values.flatten)
|
|
56
|
+
pipeline.call("PEXPIRE", key(suffix), ttl_ms(ttl))
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def hash_increment(suffix, values, ttl:)
|
|
62
|
+
require_ttl!(ttl)
|
|
63
|
+
return if values.empty?
|
|
64
|
+
|
|
65
|
+
with_redis do |redis|
|
|
66
|
+
redis.pipelined do |pipeline|
|
|
67
|
+
values.each do |field, amount|
|
|
68
|
+
command = amount.is_a?(Integer) ? "HINCRBY" : "HINCRBYFLOAT"
|
|
69
|
+
pipeline.call(command, key(suffix), field, amount)
|
|
70
|
+
end
|
|
71
|
+
pipeline.call("PEXPIRE", key(suffix), ttl_ms(ttl))
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def managed_hash_write(suffix, field, value)
|
|
77
|
+
raise UnmanagedPersistentKey, "only alerts may be written without a ttl" unless suffix == "alerts"
|
|
78
|
+
|
|
79
|
+
with_redis { |redis| redis.call("HSET", key(suffix), field, value) }
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def hash_get_all(suffix)
|
|
83
|
+
with_redis { |redis| redis.call("HGETALL", key(suffix)) }
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def hash_delete(suffix, *fields)
|
|
87
|
+
return if fields.empty?
|
|
88
|
+
|
|
89
|
+
with_redis { |redis| redis.call("HDEL", key(suffix), *fields) }
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def list_push(suffix, value, ttl:, limit: 30)
|
|
93
|
+
require_ttl!(ttl)
|
|
94
|
+
with_redis do |redis|
|
|
95
|
+
redis.pipelined do |pipeline|
|
|
96
|
+
pipeline.call("RPUSH", key(suffix), value)
|
|
97
|
+
pipeline.call("LTRIM", key(suffix), -limit, -1)
|
|
98
|
+
pipeline.call("PEXPIRE", key(suffix), ttl_ms(ttl))
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def list_range(suffix)
|
|
104
|
+
with_redis { |redis| redis.call("LRANGE", key(suffix), 0, -1) }
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def delete(suffix)
|
|
108
|
+
with_redis { |redis| redis.call("DEL", key(suffix)) }
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def scan(pattern = "*")
|
|
112
|
+
with_redis do |redis|
|
|
113
|
+
cursor = "0"
|
|
114
|
+
keys = []
|
|
115
|
+
loop do
|
|
116
|
+
cursor, batch = redis.call("SCAN", cursor, "MATCH", key(pattern), "COUNT", 100)
|
|
117
|
+
keys.concat(batch)
|
|
118
|
+
break if cursor == "0"
|
|
119
|
+
end
|
|
120
|
+
keys
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def acquire_lock(suffix, token, ttl_ms:)
|
|
125
|
+
raise MissingTTL, "a positive ttl is required" unless ttl_ms.is_a?(Numeric) && ttl_ms.positive?
|
|
126
|
+
|
|
127
|
+
with_redis { |redis| redis.call("SET", key(suffix), token, "NX", "PX", ttl_ms) == "OK" }
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def eval(script, keys:, argv:)
|
|
131
|
+
namespaced_keys = keys.map { |item| key(item) }
|
|
132
|
+
with_redis { |redis| redis.call("EVAL", script, namespaced_keys.length, *namespaced_keys, *argv) }
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def ping
|
|
136
|
+
with_redis { |redis| redis.call("PING") }
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def info(section = nil)
|
|
140
|
+
with_redis { |redis| parse_info(redis.call("INFO", *Array(section))) }
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
private
|
|
144
|
+
|
|
145
|
+
def require_ttl!(ttl)
|
|
146
|
+
raise MissingTTL, "a positive ttl is required" unless ttl.is_a?(Numeric) && ttl.positive?
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def ttl_ms(ttl)
|
|
150
|
+
(ttl * 1_000).ceil
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def with_redis(&)
|
|
154
|
+
return yield @redis if @redis
|
|
155
|
+
|
|
156
|
+
Sidekiq.redis(&)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def parse_info(raw)
|
|
160
|
+
raw.each_line.filter_map do |line|
|
|
161
|
+
next if line.start_with?("#") || !line.include?(":")
|
|
162
|
+
|
|
163
|
+
line.strip.split(":", 2)
|
|
164
|
+
end.to_h
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "date"
|
|
4
|
+
|
|
5
|
+
module SidekiqVigil
|
|
6
|
+
module Timezone
|
|
7
|
+
MUTEX = Mutex.new
|
|
8
|
+
|
|
9
|
+
module_function
|
|
10
|
+
|
|
11
|
+
def local_time(time, zone)
|
|
12
|
+
return time.getutc if zone == "UTC"
|
|
13
|
+
return time.getlocal(zone) if zone.match?(/\A[+-]\d{2}:\d{2}\z/)
|
|
14
|
+
|
|
15
|
+
MUTEX.synchronize do
|
|
16
|
+
previous = ENV.fetch("TZ", nil)
|
|
17
|
+
ENV["TZ"] = zone
|
|
18
|
+
Time.at(time.to_f).localtime
|
|
19
|
+
ensure
|
|
20
|
+
ENV["TZ"] = previous
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def same_local_days_ago(time, days, zone)
|
|
25
|
+
local = local_time(time, zone)
|
|
26
|
+
date = local.to_date - days
|
|
27
|
+
return Time.utc(date.year, date.month, date.day, local.hour, local.min, local.sec) if zone == "UTC"
|
|
28
|
+
return Time.new(date.year, date.month, date.day, local.hour, local.min, local.sec, zone) if zone.match?(/\A[+-]\d{2}:\d{2}\z/)
|
|
29
|
+
|
|
30
|
+
MUTEX.synchronize do
|
|
31
|
+
previous = ENV.fetch("TZ", nil)
|
|
32
|
+
ENV["TZ"] = zone
|
|
33
|
+
Time.local(date.year, date.month, date.day, local.hour, local.min, local.sec)
|
|
34
|
+
ensure
|
|
35
|
+
ENV["TZ"] = previous
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "logger"
|
|
4
|
+
require "sidekiq"
|
|
5
|
+
require "sidekiq/api"
|
|
6
|
+
|
|
7
|
+
require_relative "sidekiq_vigil/version"
|
|
8
|
+
|
|
9
|
+
module SidekiqVigil
|
|
10
|
+
class Error < StandardError; end
|
|
11
|
+
|
|
12
|
+
class << self
|
|
13
|
+
attr_writer :logger
|
|
14
|
+
|
|
15
|
+
def configure
|
|
16
|
+
yield config
|
|
17
|
+
config.validate!
|
|
18
|
+
config
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def config
|
|
22
|
+
@config ||= Config.new
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def collector
|
|
26
|
+
@collector ||= Collector.new
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def logger
|
|
30
|
+
@logger ||= defined?(Sidekiq.logger) ? Sidekiq.logger : Logger.new($stdout)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def build_storage(configuration = config)
|
|
34
|
+
redis = if configuration.redis
|
|
35
|
+
options = configuration.redis.transform_keys(&:to_sym).compact
|
|
36
|
+
pool_size = options.delete(:pool_size) || 5
|
|
37
|
+
pool_timeout = options.delete(:pool_timeout) || 1
|
|
38
|
+
RedisClient.config(**options).new_pool(size: pool_size, timeout: pool_timeout)
|
|
39
|
+
end
|
|
40
|
+
Storage.new(redis:, key_prefix: configuration.key_prefix)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def install!
|
|
44
|
+
return if @installed
|
|
45
|
+
|
|
46
|
+
Sidekiq.configure_server do |server|
|
|
47
|
+
server.server_middleware { |chain| chain.add(Middleware::Server) }
|
|
48
|
+
server.on(:startup) { start_runtime }
|
|
49
|
+
server.on(:quiet) { @runtime&.quiet }
|
|
50
|
+
server.on(:shutdown) { stop_runtime }
|
|
51
|
+
end
|
|
52
|
+
@installed = true
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def start_runtime
|
|
56
|
+
@runtime ||= Runtime.new(config:, storage: build_storage)
|
|
57
|
+
@runtime.start
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def stop_runtime
|
|
61
|
+
@runtime&.stop
|
|
62
|
+
@runtime = nil
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def reset!
|
|
66
|
+
@config = Config.new
|
|
67
|
+
@collector = Collector.new
|
|
68
|
+
@logger = nil
|
|
69
|
+
@runtime = nil
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
require_relative "sidekiq_vigil/result"
|
|
75
|
+
require_relative "sidekiq_vigil/config"
|
|
76
|
+
require_relative "sidekiq_vigil/storage"
|
|
77
|
+
require_relative "sidekiq_vigil/sidekiq_api"
|
|
78
|
+
require_relative "sidekiq_vigil/timezone"
|
|
79
|
+
require_relative "sidekiq_vigil/check/base"
|
|
80
|
+
require_relative "sidekiq_vigil/check/registry"
|
|
81
|
+
require_relative "sidekiq_vigil/check/queue_latency"
|
|
82
|
+
require_relative "sidekiq_vigil/check/queue_size"
|
|
83
|
+
require_relative "sidekiq_vigil/check/set_size"
|
|
84
|
+
require_relative "sidekiq_vigil/check/process_alive"
|
|
85
|
+
require_relative "sidekiq_vigil/check/utilization"
|
|
86
|
+
require_relative "sidekiq_vigil/check/failure_rate"
|
|
87
|
+
require_relative "sidekiq_vigil/check/stuck_jobs"
|
|
88
|
+
require_relative "sidekiq_vigil/check/memory"
|
|
89
|
+
require_relative "sidekiq_vigil/check/redis_health"
|
|
90
|
+
require_relative "sidekiq_vigil/check/scheduled_backlog"
|
|
91
|
+
require_relative "sidekiq_vigil/check/throughput_anomaly"
|
|
92
|
+
require_relative "sidekiq_vigil/alert/state"
|
|
93
|
+
require_relative "sidekiq_vigil/alert/event"
|
|
94
|
+
require_relative "sidekiq_vigil/alert/cron"
|
|
95
|
+
require_relative "sidekiq_vigil/alert/mute"
|
|
96
|
+
require_relative "sidekiq_vigil/alert/grouping"
|
|
97
|
+
require_relative "sidekiq_vigil/alert/manager"
|
|
98
|
+
require_relative "sidekiq_vigil/notifier/base"
|
|
99
|
+
require_relative "sidekiq_vigil/notifier/log"
|
|
100
|
+
require_relative "sidekiq_vigil/notifier/http_transport"
|
|
101
|
+
require_relative "sidekiq_vigil/notifier/webhook"
|
|
102
|
+
require_relative "sidekiq_vigil/notifier/slack"
|
|
103
|
+
require_relative "sidekiq_vigil/notifier/manager"
|
|
104
|
+
require_relative "sidekiq_vigil/leader_election"
|
|
105
|
+
require_relative "sidekiq_vigil/collector"
|
|
106
|
+
require_relative "sidekiq_vigil/middleware/server"
|
|
107
|
+
require_relative "sidekiq_vigil/reporter"
|
|
108
|
+
require_relative "sidekiq_vigil/checker"
|
|
109
|
+
require_relative "sidekiq_vigil/runtime"
|
|
110
|
+
require_relative "sidekiq_vigil/health_app"
|
|
111
|
+
require_relative "sidekiq_vigil/cli"
|
|
112
|
+
|
|
113
|
+
SidekiqVigil::BUILT_IN_CHECKS = {
|
|
114
|
+
queue_latency: SidekiqVigil::Check::QueueLatency,
|
|
115
|
+
queue_size: SidekiqVigil::Check::QueueSize,
|
|
116
|
+
retry_set: SidekiqVigil::Check::RetrySet,
|
|
117
|
+
dead_set: SidekiqVigil::Check::DeadSet,
|
|
118
|
+
process_alive: SidekiqVigil::Check::ProcessAlive,
|
|
119
|
+
utilization: SidekiqVigil::Check::Utilization,
|
|
120
|
+
failure_rate: SidekiqVigil::Check::FailureRate,
|
|
121
|
+
stuck_jobs: SidekiqVigil::Check::StuckJobs,
|
|
122
|
+
memory: SidekiqVigil::Check::Memory,
|
|
123
|
+
redis_health: SidekiqVigil::Check::RedisHealth,
|
|
124
|
+
scheduled_backlog: SidekiqVigil::Check::ScheduledBacklog,
|
|
125
|
+
throughput_anomaly: SidekiqVigil::Check::ThroughputAnomaly
|
|
126
|
+
}.freeze
|
|
127
|
+
|
|
128
|
+
SidekiqVigil.install!
|
metadata
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: sidekiq-vigil
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Yudai Takada
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: sidekiq
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '7.0'
|
|
26
|
+
description: Monitors Sidekiq health with Redis-backed checks, alert lifecycles, and
|
|
27
|
+
pluggable notifications.
|
|
28
|
+
email:
|
|
29
|
+
- t.yudai92@gmail.com
|
|
30
|
+
executables:
|
|
31
|
+
- vigil
|
|
32
|
+
extensions: []
|
|
33
|
+
extra_rdoc_files: []
|
|
34
|
+
files:
|
|
35
|
+
- ".rubocop.yml"
|
|
36
|
+
- LICENSE.txt
|
|
37
|
+
- README.md
|
|
38
|
+
- Rakefile
|
|
39
|
+
- docs/redis_keys.md
|
|
40
|
+
- docs/webhook_event.schema.json
|
|
41
|
+
- docs/webhook_schema.md
|
|
42
|
+
- exe/vigil
|
|
43
|
+
- lib/generators/sidekiq_vigil/install_generator.rb
|
|
44
|
+
- lib/generators/sidekiq_vigil/templates/sidekiq_vigil.rb
|
|
45
|
+
- lib/sidekiq/vigil.rb
|
|
46
|
+
- lib/sidekiq/vigil/version.rb
|
|
47
|
+
- lib/sidekiq_vigil.rb
|
|
48
|
+
- lib/sidekiq_vigil/alert/cron.rb
|
|
49
|
+
- lib/sidekiq_vigil/alert/event.rb
|
|
50
|
+
- lib/sidekiq_vigil/alert/grouping.rb
|
|
51
|
+
- lib/sidekiq_vigil/alert/manager.rb
|
|
52
|
+
- lib/sidekiq_vigil/alert/mute.rb
|
|
53
|
+
- lib/sidekiq_vigil/alert/state.rb
|
|
54
|
+
- lib/sidekiq_vigil/check/base.rb
|
|
55
|
+
- lib/sidekiq_vigil/check/failure_rate.rb
|
|
56
|
+
- lib/sidekiq_vigil/check/memory.rb
|
|
57
|
+
- lib/sidekiq_vigil/check/process_alive.rb
|
|
58
|
+
- lib/sidekiq_vigil/check/queue_latency.rb
|
|
59
|
+
- lib/sidekiq_vigil/check/queue_size.rb
|
|
60
|
+
- lib/sidekiq_vigil/check/redis_health.rb
|
|
61
|
+
- lib/sidekiq_vigil/check/registry.rb
|
|
62
|
+
- lib/sidekiq_vigil/check/scheduled_backlog.rb
|
|
63
|
+
- lib/sidekiq_vigil/check/set_size.rb
|
|
64
|
+
- lib/sidekiq_vigil/check/stuck_jobs.rb
|
|
65
|
+
- lib/sidekiq_vigil/check/throughput_anomaly.rb
|
|
66
|
+
- lib/sidekiq_vigil/check/utilization.rb
|
|
67
|
+
- lib/sidekiq_vigil/checker.rb
|
|
68
|
+
- lib/sidekiq_vigil/cli.rb
|
|
69
|
+
- lib/sidekiq_vigil/collector.rb
|
|
70
|
+
- lib/sidekiq_vigil/config.rb
|
|
71
|
+
- lib/sidekiq_vigil/health_app.rb
|
|
72
|
+
- lib/sidekiq_vigil/leader_election.rb
|
|
73
|
+
- lib/sidekiq_vigil/middleware/server.rb
|
|
74
|
+
- lib/sidekiq_vigil/notifier/base.rb
|
|
75
|
+
- lib/sidekiq_vigil/notifier/http_transport.rb
|
|
76
|
+
- lib/sidekiq_vigil/notifier/log.rb
|
|
77
|
+
- lib/sidekiq_vigil/notifier/manager.rb
|
|
78
|
+
- lib/sidekiq_vigil/notifier/slack.rb
|
|
79
|
+
- lib/sidekiq_vigil/notifier/webhook.rb
|
|
80
|
+
- lib/sidekiq_vigil/reporter.rb
|
|
81
|
+
- lib/sidekiq_vigil/result.rb
|
|
82
|
+
- lib/sidekiq_vigil/runtime.rb
|
|
83
|
+
- lib/sidekiq_vigil/sidekiq_api.rb
|
|
84
|
+
- lib/sidekiq_vigil/storage.rb
|
|
85
|
+
- lib/sidekiq_vigil/timezone.rb
|
|
86
|
+
- lib/sidekiq_vigil/version.rb
|
|
87
|
+
homepage: https://github.com/ydah/sidekiq-vigil
|
|
88
|
+
licenses:
|
|
89
|
+
- MIT
|
|
90
|
+
metadata:
|
|
91
|
+
homepage_uri: https://github.com/ydah/sidekiq-vigil
|
|
92
|
+
source_code_uri: https://github.com/ydah/sidekiq-vigil/tree/main
|
|
93
|
+
rubygems_mfa_required: 'true'
|
|
94
|
+
rdoc_options: []
|
|
95
|
+
require_paths:
|
|
96
|
+
- lib
|
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
98
|
+
requirements:
|
|
99
|
+
- - ">="
|
|
100
|
+
- !ruby/object:Gem::Version
|
|
101
|
+
version: 3.2.0
|
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
103
|
+
requirements:
|
|
104
|
+
- - ">="
|
|
105
|
+
- !ruby/object:Gem::Version
|
|
106
|
+
version: '0'
|
|
107
|
+
requirements: []
|
|
108
|
+
rubygems_version: 4.0.6
|
|
109
|
+
specification_version: 4
|
|
110
|
+
summary: Battery-included monitoring and alerting for Sidekiq
|
|
111
|
+
test_files: []
|