wellness 1.0.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/.travis.yml +2 -1
- data/README.md +118 -50
- data/Rakefile +24 -3
- data/lib/wellness/detail.rb +6 -7
- data/lib/wellness/detailed_report.rb +64 -0
- data/lib/wellness/middleware.rb +6 -3
- data/lib/wellness/service.rb +17 -0
- data/lib/wellness/services/base.rb +3 -30
- data/lib/wellness/services/postgres_service.rb +18 -20
- data/lib/wellness/services/redis_service.rb +13 -19
- data/lib/wellness/services/sidekiq_service.rb +23 -20
- data/lib/wellness/simple_report.rb +53 -0
- data/lib/wellness/system.rb +9 -38
- data/lib/wellness/version.rb +2 -2
- data/lib/wellness.rb +5 -4
- data/spec/spec_helper.rb +4 -7
- data/test/test_helper.rb +10 -0
- data/test/wellness/detail_test.rb +26 -0
- data/test/wellness/detailed_report_test.rb +127 -0
- data/test/wellness/simple_report_test.rb +127 -0
- data/test/wellness/system_test.rb +54 -0
- data/wellness.gemspec +0 -2
- metadata +32 -69
- data/.rspec +0 -2
- data/lib/wellness/factory.rb +0 -14
- data/lib/wellness/report.rb +0 -59
- data/lib/wellness/services.rb +0 -6
- data/spec/support/services_support.rb +0 -17
- data/spec/wellness/detail_spec.rb +0 -26
- data/spec/wellness/middleware_spec.rb +0 -69
- data/spec/wellness/report_spec.rb +0 -87
- data/spec/wellness/services/base_spec.rb +0 -51
- data/spec/wellness/services/postgres_service_spec.rb +0 -5
- data/spec/wellness/services/redis_service_spec.rb +0 -31
- data/spec/wellness/services/sidekiq_service_spec.rb +0 -5
- data/spec/wellness/system_spec.rb +0 -78
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 83d31bae5ada6170c0a1c9349df2e637c5cb2acf
|
4
|
+
data.tar.gz: 7e3d8a4b30dced90941b21c3c5c246e1e44c4a9a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2fb50394b50629a867c2cf8c1e4744850cfc4872bbb68944b9ba612711de715a3a0117c78b50f9decc0f0c137e2db2151bc09b6be5de4adb2306a873e34c1eae
|
7
|
+
data.tar.gz: 558bb60650dc8653edf5fd9eba21e122c4e1b271db52e0fc1ee8bb6eb8c11d7f2a588e2ab5c817c8748a5d5db3ad8689f02aa56e16ba7e30c615daba26adfc34
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.1.2
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -14,22 +14,26 @@ However, you must require them when you need them. This is because they have
|
|
14
14
|
external dependencies that need to be loaded, that your application may not
|
15
15
|
necessarily have.
|
16
16
|
|
17
|
-
```
|
18
|
-
|
19
|
-
|
20
|
-
system
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
})
|
28
|
-
system.
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
17
|
+
```ruby
|
18
|
+
module MySuperCoolApplication
|
19
|
+
class Application < Rails::Application
|
20
|
+
system = Wellness::System.new('my-super-cool-app')
|
21
|
+
service = Wellness::Services::PostgresService.new({
|
22
|
+
host: ENV['POSTGRESQL_HOST'],
|
23
|
+
port: ENV['POSTGRESQL_PORT'],
|
24
|
+
database: ENV['POSTGRESQL_DATABASE'],
|
25
|
+
user: ENV['POSTGRESQL_USERNAME'],
|
26
|
+
password: ENV['POSTGRESQL_PASSWORD']
|
27
|
+
})
|
28
|
+
system.add_service('database', service, { critical: true })
|
29
|
+
service = Wellness::Services::RedisService.new({
|
30
|
+
host: ENV['REDIS_HOST']
|
31
|
+
})
|
32
|
+
system.add_service('redis', service, { critical: false})
|
33
|
+
|
34
|
+
config.middleware.insert_before('::ActiveRecord::QueryCache', 'Wellness::Middleware', system)
|
35
|
+
end
|
36
|
+
end
|
33
37
|
```
|
34
38
|
|
35
39
|
## Usage - Sinatra
|
@@ -37,28 +41,32 @@ config.middleware.insert_before('::ActiveRecord::QueryCache', 'Wellness::Middlew
|
|
37
41
|
```ruby
|
38
42
|
require 'wellness'
|
39
43
|
|
40
|
-
system
|
41
|
-
|
44
|
+
system = Wellness::System.new('my-super-cool-app')
|
45
|
+
service = Wellness::Services::PostgresService.new({
|
42
46
|
host: ENV['POSTGRESQL_HOST'],
|
43
47
|
port: ENV['POSTGRESQL_PORT'],
|
44
48
|
database: ENV['POSTGRESQL_DATABASE'],
|
45
49
|
user: ENV['POSTGRESQL_USERNAME'],
|
46
50
|
password: ENV['POSTGRESQL_PASSWORD']
|
47
51
|
})
|
48
|
-
system.
|
52
|
+
system.add_service('database', service, { critical: true })
|
53
|
+
service = Wellness::Services::RedisService.new({
|
49
54
|
host: ENV['REDIS_HOST']
|
50
55
|
})
|
56
|
+
system.add_service('redis', service, { critical: false})
|
51
57
|
|
52
58
|
use(Wellness::Middleware, system)
|
53
59
|
```
|
54
60
|
|
55
|
-
## Example
|
61
|
+
## Example Responses
|
56
62
|
|
57
63
|
```json
|
58
64
|
{
|
59
|
-
"status":"UNHEALTHY",
|
60
|
-
"details":{
|
61
|
-
|
65
|
+
"status": "UNHEALTHY",
|
66
|
+
"details": {
|
67
|
+
"git" : {
|
68
|
+
"revision" : "1234567"
|
69
|
+
}
|
62
70
|
},
|
63
71
|
"dependencies":{
|
64
72
|
"database":{
|
@@ -89,58 +97,118 @@ use(Wellness::Middleware, system)
|
|
89
97
|
}
|
90
98
|
```
|
91
99
|
|
100
|
+
```json
|
101
|
+
{
|
102
|
+
"status": "HEALTHY",
|
103
|
+
"services": {
|
104
|
+
"postgresql": {
|
105
|
+
"status": "HEALTHY",
|
106
|
+
"details": { }
|
107
|
+
},
|
108
|
+
"mysql": {
|
109
|
+
"status": "HEALTHY",
|
110
|
+
"details": { }
|
111
|
+
}
|
112
|
+
},
|
113
|
+
"details": {
|
114
|
+
"git": {
|
115
|
+
"revision": "1234567"
|
116
|
+
}
|
117
|
+
}
|
118
|
+
}
|
119
|
+
```
|
120
|
+
|
92
121
|
## Custom Services
|
93
122
|
|
94
|
-
Creating custom
|
95
|
-
`
|
123
|
+
Creating a custom service is super easy. As long as the service responds to
|
124
|
+
`#call`, you are just fine. Passing a `lambda` or `Proc` is perfectly
|
125
|
+
acceptable.
|
96
126
|
|
97
|
-
|
127
|
+
### Requirements
|
98
128
|
|
99
|
-
|
100
|
-
|
101
|
-
|
129
|
+
This interface has a few requirements.
|
130
|
+
|
131
|
+
1. A service **MUST** respond to `#call`
|
132
|
+
2. A hash **MUST** be returned
|
133
|
+
3. The hash returned **MUST** contain a `status` key at the root level.
|
134
|
+
4. Status can **ONLY** be `HEALTHY`, `UNHEALTHY`, and `DEGRADED`
|
135
|
+
5. All hash keys **MUST** be strings
|
136
|
+
|
137
|
+
### Example
|
102
138
|
|
103
139
|
```ruby
|
104
|
-
|
105
|
-
class
|
106
|
-
|
107
|
-
|
140
|
+
module MyServices
|
141
|
+
class MySQLService
|
142
|
+
def initialize(args={})
|
143
|
+
@connection_options = {
|
144
|
+
host: args[:host],
|
145
|
+
port: args[:port],
|
146
|
+
database: args[:database],
|
147
|
+
username: args[:username],
|
148
|
+
password: args[:password]
|
149
|
+
}
|
150
|
+
end
|
151
|
+
|
152
|
+
def healthy(details={})
|
108
153
|
{
|
109
|
-
'status'
|
154
|
+
'status' => 'HEALTHY',
|
155
|
+
'details' => details
|
110
156
|
}
|
111
|
-
|
157
|
+
end
|
158
|
+
|
159
|
+
def unhealthy(details={})
|
112
160
|
{
|
113
|
-
'status'
|
161
|
+
'status' => 'UNHEALTHY',
|
162
|
+
'details' => details
|
114
163
|
}
|
115
164
|
end
|
165
|
+
|
166
|
+
def call
|
167
|
+
connection = Mysql2::Client.new(@connection_options)
|
168
|
+
connection.ping ? healthy : unhealthy
|
169
|
+
rescue Mysql2::Error => error
|
170
|
+
unhealthy('error' => error.message)
|
171
|
+
end
|
116
172
|
end
|
117
173
|
end
|
118
174
|
|
119
|
-
# Initialize the wellness system
|
120
175
|
system = Wellness::System.new('my-app')
|
121
|
-
system.use(
|
122
|
-
|
123
|
-
|
124
|
-
use(Wellness::Middleware, system)
|
176
|
+
system.use('mysql', MyServices::MySQLService.new({
|
177
|
+
# ... configuration ...
|
178
|
+
}))
|
125
179
|
```
|
126
180
|
|
127
181
|
## Custom Details
|
128
182
|
|
183
|
+
Details are useful if you want to display information on an application like the
|
184
|
+
current git revision, or how many requests have been serviced by the application.
|
185
|
+
|
186
|
+
### Requirements
|
187
|
+
|
188
|
+
1. A detail **MUST** respond to `#call`
|
189
|
+
2. A hash **MUST** be returned
|
190
|
+
3. All hash keys **MUST** be strings
|
191
|
+
|
192
|
+
### Example
|
193
|
+
|
129
194
|
```ruby
|
130
195
|
# Your custom detail component
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
196
|
+
module MyDetails
|
197
|
+
class GitRevisionDetail
|
198
|
+
def call
|
199
|
+
{
|
200
|
+
'revision' => revision
|
201
|
+
}
|
202
|
+
end
|
203
|
+
|
204
|
+
def revision
|
205
|
+
`git rev-parse --short HEAD`.chomp
|
206
|
+
end
|
138
207
|
end
|
139
208
|
end
|
140
|
-
|
141
209
|
# Initialize the wellness system
|
142
210
|
system = Wellness::System.new('my-app')
|
143
|
-
system.use(
|
211
|
+
system.use('git', MyDetails::GitRevisionDetail.new)
|
144
212
|
|
145
213
|
# Load it into your rack
|
146
214
|
use(Wellness::Middleware, system)
|
data/Rakefile
CHANGED
@@ -1,5 +1,26 @@
|
|
1
1
|
require 'bundler/gem_tasks'
|
2
|
-
require 'rspec/core/rake_task'
|
3
2
|
|
4
|
-
|
5
|
-
task :
|
3
|
+
namespace :test do
|
4
|
+
task :env do
|
5
|
+
$LOAD_PATH.unshift('lib', 'spec', 'test')
|
6
|
+
end
|
7
|
+
|
8
|
+
desc 'Runs only the units in this project'
|
9
|
+
task :units => [:env] do
|
10
|
+
Dir.glob('./test/**/*_test.rb') { |f| require f }
|
11
|
+
end
|
12
|
+
|
13
|
+
desc 'Runs only the specs in this project'
|
14
|
+
task :specs => [:env] do
|
15
|
+
Dir.glob('./spec/**/*_spec.rb') { |f| require f }
|
16
|
+
end
|
17
|
+
|
18
|
+
desc 'Runs all of the tests within this project'
|
19
|
+
task :all => [:units, :specs]
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'Runs all of the tests within this project'
|
23
|
+
task :test => ['test:units']
|
24
|
+
task :spec => ['test:specs']
|
25
|
+
|
26
|
+
task(:default => 'test:all')
|
data/lib/wellness/detail.rb
CHANGED
@@ -1,19 +1,18 @@
|
|
1
1
|
module Wellness
|
2
2
|
# The parent class of all details that need to run.
|
3
3
|
#
|
4
|
+
# @deprecated This is simply here help with migrating
|
5
|
+
#
|
4
6
|
# @author Matthew A. Johnston (warmwaffles)
|
5
7
|
class Detail
|
6
|
-
attr_reader :
|
8
|
+
attr_reader :options
|
7
9
|
|
8
|
-
def initialize(
|
9
|
-
@name = name
|
10
|
+
def initialize(options={})
|
10
11
|
@options = options
|
11
|
-
@result = {}
|
12
12
|
end
|
13
13
|
|
14
14
|
def call
|
15
|
-
|
16
|
-
self
|
15
|
+
self.check
|
17
16
|
end
|
18
17
|
|
19
18
|
# @return [Hash]
|
@@ -21,4 +20,4 @@ module Wellness
|
|
21
20
|
{}
|
22
21
|
end
|
23
22
|
end
|
24
|
-
end
|
23
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Wellness
|
4
|
+
class DetailedReport
|
5
|
+
STATUSES = {
|
6
|
+
'HEALTHY' => 200,
|
7
|
+
'DEGRADED' => 500,
|
8
|
+
'UNHEALTHY' => 500
|
9
|
+
}
|
10
|
+
|
11
|
+
def initialize(system)
|
12
|
+
@system = system
|
13
|
+
end
|
14
|
+
|
15
|
+
def call
|
16
|
+
non_criticals = []
|
17
|
+
criticals = []
|
18
|
+
|
19
|
+
services = {}
|
20
|
+
@system.services.each do |name, service|
|
21
|
+
services[name] = service.call
|
22
|
+
|
23
|
+
if service.critical?
|
24
|
+
criticals << services[name]['status']
|
25
|
+
else
|
26
|
+
non_criticals << services[name]['status']
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
details = {}
|
31
|
+
@system.details.each do |name, detail|
|
32
|
+
details[name] = detail.call
|
33
|
+
end
|
34
|
+
|
35
|
+
healthy = criticals.all? { |s| s == 'HEALTHY' }
|
36
|
+
degraded = non_criticals.any? { |s| s == 'UNHEALTHY' }
|
37
|
+
|
38
|
+
if healthy
|
39
|
+
if degraded
|
40
|
+
status = 'DEGRADED'
|
41
|
+
else
|
42
|
+
status = 'HEALTHY'
|
43
|
+
end
|
44
|
+
else
|
45
|
+
status = 'UNHEALTHY'
|
46
|
+
end
|
47
|
+
|
48
|
+
results = {
|
49
|
+
'status' => status,
|
50
|
+
'services' => services,
|
51
|
+
'details' => details
|
52
|
+
}
|
53
|
+
|
54
|
+
render({json: results, status: STATUSES[status]})
|
55
|
+
end
|
56
|
+
|
57
|
+
def render(options={})
|
58
|
+
status = options[:status] || 200
|
59
|
+
response = JSON.dump(options[:json])
|
60
|
+
|
61
|
+
[status, { 'Content-Type' => 'application/json' }, [response]]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/wellness/middleware.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'wellness/simple_report'
|
2
|
+
require 'wellness/detailed_report'
|
3
|
+
|
1
4
|
module Wellness
|
2
5
|
# This is to be put into the Rack environment.
|
3
6
|
#
|
@@ -20,12 +23,12 @@ module Wellness
|
|
20
23
|
def call(env)
|
21
24
|
case env['PATH_INFO']
|
22
25
|
when health_status_path
|
23
|
-
@system.
|
26
|
+
Wellness::SimpleReport.new(@system).call
|
24
27
|
when health_details_path
|
25
|
-
@system.
|
28
|
+
Wellness::DetailedReport.new(@system).call
|
26
29
|
else
|
27
30
|
@app.call(env)
|
28
31
|
end
|
29
32
|
end
|
30
33
|
end
|
31
|
-
end
|
34
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Wellness
|
2
|
+
# Wraps a callable object.
|
3
|
+
class Service
|
4
|
+
def initialize(callable, options={})
|
5
|
+
@callable = callable
|
6
|
+
@critical = options.fetch(:critical, true)
|
7
|
+
end
|
8
|
+
|
9
|
+
def critical?
|
10
|
+
!!@critical
|
11
|
+
end
|
12
|
+
|
13
|
+
def call
|
14
|
+
@callable.call
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -2,8 +2,6 @@ module Wellness
|
|
2
2
|
module Services
|
3
3
|
# @author Matthew A. Johnston
|
4
4
|
class Base
|
5
|
-
attr_reader :params, :result, :name
|
6
|
-
|
7
5
|
# Load dependencies when the class is loaded. This makes putting requires
|
8
6
|
# at the top of the file unnecessary. It plays nicely with the
|
9
7
|
# auto loader.
|
@@ -11,39 +9,14 @@ module Wellness
|
|
11
9
|
yield if block_given?
|
12
10
|
end
|
13
11
|
|
14
|
-
|
15
|
-
def initialize(name, params={})
|
16
|
-
@name = name
|
17
|
-
@params = params
|
18
|
-
@result = {}
|
19
|
-
end
|
20
|
-
|
21
|
-
# Returns true if the service is healthy, otherwise false
|
22
|
-
# @return [TrueClass,FalseClass]
|
23
|
-
def healthy?
|
24
|
-
@result.fetch(:status, 'UNHEALTHY') == 'HEALTHY'
|
25
|
-
end
|
26
|
-
|
27
|
-
def passed_check
|
28
|
-
warn('#passed_check has been deprecated')
|
12
|
+
def initialize(args={})
|
29
13
|
end
|
30
14
|
|
31
|
-
def failed_check
|
32
|
-
warn('#failed_check has been deprecated')
|
33
|
-
end
|
34
|
-
|
35
|
-
# @return [Wellness::Services::Base]
|
36
15
|
def call
|
37
|
-
@result = self.check
|
38
|
-
self
|
39
|
-
end
|
40
|
-
|
41
|
-
# @return [Hash]
|
42
|
-
def check
|
43
16
|
{
|
44
|
-
status
|
17
|
+
'status' => 'HEALTHY'
|
45
18
|
}
|
46
19
|
end
|
47
20
|
end
|
48
21
|
end
|
49
|
-
end
|
22
|
+
end
|
@@ -2,15 +2,24 @@ require 'wellness/services/base'
|
|
2
2
|
|
3
3
|
module Wellness
|
4
4
|
module Services
|
5
|
-
# @author Matthew A. Johnston
|
6
5
|
class PostgresService < Base
|
7
6
|
dependency do
|
8
|
-
require
|
7
|
+
require 'pg'
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(args={})
|
11
|
+
@connection_options = {
|
12
|
+
host: args[:host],
|
13
|
+
port: args[:port],
|
14
|
+
dbname: args[:database],
|
15
|
+
user: args[:user],
|
16
|
+
password: args[:password]
|
17
|
+
}
|
9
18
|
end
|
10
19
|
|
11
20
|
# @return [Hash]
|
12
|
-
def
|
13
|
-
case PG::Connection.ping(connection_options)
|
21
|
+
def call
|
22
|
+
case PG::Connection.ping(@connection_options)
|
14
23
|
when PG::Constants::PQPING_NO_ATTEMPT
|
15
24
|
ping_failed('no attempt made to ping')
|
16
25
|
when PG::Constants::PQPING_NO_RESPONSE
|
@@ -24,24 +33,13 @@ module Wellness
|
|
24
33
|
|
25
34
|
private
|
26
35
|
|
27
|
-
# @return [Hash]
|
28
|
-
def connection_options
|
29
|
-
{
|
30
|
-
host: self.params[:host],
|
31
|
-
port: self.params[:port],
|
32
|
-
dbname: self.params[:database],
|
33
|
-
user: self.params[:user],
|
34
|
-
password: self.params[:password]
|
35
|
-
}
|
36
|
-
end
|
37
|
-
|
38
36
|
# @param message [String] the reason it failed
|
39
37
|
# @return [Hash]
|
40
38
|
def ping_failed(message)
|
41
39
|
{
|
42
|
-
status
|
43
|
-
details
|
44
|
-
error
|
40
|
+
'status' => 'UNHEALTHY',
|
41
|
+
'details' => {
|
42
|
+
'error' => message
|
45
43
|
}
|
46
44
|
}
|
47
45
|
end
|
@@ -49,8 +47,8 @@ module Wellness
|
|
49
47
|
# @return [Hash]
|
50
48
|
def ping_successful
|
51
49
|
{
|
52
|
-
status
|
53
|
-
details
|
50
|
+
'status' => 'HEALTHY',
|
51
|
+
'details' => {
|
54
52
|
}
|
55
53
|
}
|
56
54
|
end
|
@@ -20,37 +20,31 @@ module Wellness
|
|
20
20
|
'uptime_in_days'
|
21
21
|
]
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
def initialize(args={})
|
24
|
+
@params = args
|
25
25
|
end
|
26
26
|
|
27
27
|
# @return [Hash]
|
28
|
-
def
|
29
|
-
client
|
28
|
+
def call
|
29
|
+
client = Redis.new(@params)
|
30
30
|
details = client.info.select { |k, _| KEYS.include?(k) }
|
31
|
-
|
31
|
+
client.disconnect
|
32
|
+
|
33
|
+
{
|
34
|
+
'status' => 'HEALTHY',
|
35
|
+
'details' => details
|
36
|
+
}
|
32
37
|
rescue Redis::BaseError => error
|
33
38
|
failed(error)
|
34
39
|
rescue Exception => error
|
35
40
|
failed(error)
|
36
41
|
end
|
37
42
|
|
38
|
-
def build_client
|
39
|
-
Redis.new(self.params)
|
40
|
-
end
|
41
|
-
|
42
|
-
def passed(details)
|
43
|
-
{
|
44
|
-
status: 'HEALTHY',
|
45
|
-
details: details
|
46
|
-
}
|
47
|
-
end
|
48
|
-
|
49
43
|
def failed(error)
|
50
44
|
{
|
51
|
-
status
|
52
|
-
details
|
53
|
-
error
|
45
|
+
'status' => 'UNHEALTHY',
|
46
|
+
'details' => {
|
47
|
+
'error' => error.message
|
54
48
|
}
|
55
49
|
}
|
56
50
|
end
|
@@ -6,40 +6,43 @@ module Wellness
|
|
6
6
|
class SidekiqService < Base
|
7
7
|
KEYS = %w(redis_stats uptime_in_days connected_clients used_memory_human used_memory_peak_human)
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
require 'sidekiq'
|
9
|
+
def initialize(args={})
|
10
|
+
@params = args
|
12
11
|
end
|
13
12
|
|
14
13
|
# @return [Hash]
|
15
|
-
def
|
14
|
+
def call
|
16
15
|
sidekiq_stats = Sidekiq::Stats.new
|
16
|
+
|
17
17
|
queue = Sidekiq::Queue.new
|
18
|
-
redis = Redis.new(
|
19
|
-
|
18
|
+
redis = Redis.new(@params.fetch(:redis))
|
19
|
+
|
20
|
+
redis_stats = redis.info.select { |k, _| KEYS.include?(k) }
|
20
21
|
workers_size = redis.scard('workers').to_i
|
21
22
|
|
23
|
+
redis.disconnect
|
24
|
+
|
22
25
|
{
|
23
|
-
status
|
24
|
-
details
|
25
|
-
processed
|
26
|
-
failed
|
27
|
-
busy
|
28
|
-
enqueued
|
29
|
-
scheduled
|
30
|
-
retries
|
31
|
-
default_latency
|
32
|
-
redis
|
26
|
+
'status' => 'HEALTHY',
|
27
|
+
'details' => {
|
28
|
+
'processed' => sidekiq_stats.processed,
|
29
|
+
'failed' => sidekiq_stats.failed,
|
30
|
+
'busy' => workers_size,
|
31
|
+
'enqueued' => sidekiq_stats.enqueued,
|
32
|
+
'scheduled' => sidekiq_stats.scheduled_size,
|
33
|
+
'retries' => sidekiq_stats.retry_size,
|
34
|
+
'default_latency' => queue.latency,
|
35
|
+
'redis' => redis_stats
|
33
36
|
}
|
34
37
|
}
|
35
38
|
rescue => error
|
36
39
|
{
|
37
|
-
status
|
38
|
-
details
|
39
|
-
error
|
40
|
+
'status' => 'UNHEALTHY',
|
41
|
+
'details' => {
|
42
|
+
'error' => error.message
|
40
43
|
}
|
41
44
|
}
|
42
45
|
end
|
43
46
|
end
|
44
47
|
end
|
45
|
-
end
|
48
|
+
end
|