wellness 1.0.2 → 2.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/.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
|