rack-healthcheck 0.1.0 → 0.2.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 +5 -5
- data/.circleci/config.yml +27 -0
- data/.gitignore +0 -1
- data/.rubocop.yml +15 -0
- data/Gemfile +5 -1
- data/Gemfile.lock +69 -0
- data/README.md +7 -6
- data/Rakefile +1 -1
- data/lib/rack/healthcheck.rb +9 -7
- data/lib/rack/healthcheck/action.rb +20 -18
- data/lib/rack/healthcheck/actions/base.rb +18 -14
- data/lib/rack/healthcheck/actions/complete.rb +30 -26
- data/lib/rack/healthcheck/actions/load_balancer.rb +34 -30
- data/lib/rack/healthcheck/checks/active_record.rb +23 -19
- data/lib/rack/healthcheck/checks/base.rb +45 -40
- data/lib/rack/healthcheck/checks/http_request.rb +33 -29
- data/lib/rack/healthcheck/checks/mongo_db.rb +23 -19
- data/lib/rack/healthcheck/checks/rabbit_mq.rb +30 -26
- data/lib/rack/healthcheck/checks/redis.rb +28 -24
- data/lib/rack/healthcheck/configuration.rb +20 -17
- data/lib/rack/healthcheck/middleware.rb +15 -13
- data/lib/rack/healthcheck/type.rb +13 -11
- data/lib/rack/healthcheck/version.rb +1 -1
- data/rack-healthcheck.gemspec +6 -8
- metadata +27 -27
- data/.travis.yml +0 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 55f7401bb085249aa484584b5039563de4fe088aabe3c1ffdee18702c4264cca
|
|
4
|
+
data.tar.gz: 1207b6dbe3841eb60a65097a6107ac9ae499b619e76b9937b13abb7493907ee6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d36444308315c557f82631839024f0dff86f81e1d660b868bccc5065a2d8c1fd7b46d9a600952f952cc224e3b121329a6929d27fefbf1e9067d01dfa933df23e
|
|
7
|
+
data.tar.gz: 761fabb11e9415903536a7f1e3595a1063f6d6dc7cf1d3597c7c25dcc5844f3839345fee98903b1087623353479a15f1f25e9fc31f37e95a7fee4f37f4baec5e
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
version: 2.1
|
|
2
|
+
jobs:
|
|
3
|
+
build:
|
|
4
|
+
docker:
|
|
5
|
+
- image: circleci/ruby:2.5.3
|
|
6
|
+
environment:
|
|
7
|
+
- CC_TEST_REPORTER_ID: af1d9f6682174286b1e088c76e70d86f889270e130a678001ec2cd586ce9ce2f
|
|
8
|
+
steps:
|
|
9
|
+
- checkout
|
|
10
|
+
- run:
|
|
11
|
+
name: Install dependencies
|
|
12
|
+
command: bundle install
|
|
13
|
+
- run:
|
|
14
|
+
name: Rubocop
|
|
15
|
+
command: rubocop -D
|
|
16
|
+
- run:
|
|
17
|
+
name: Setup Code Climate test-reporter
|
|
18
|
+
command: |
|
|
19
|
+
mkdir -p tmp/
|
|
20
|
+
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./tmp/cc-test-reporter
|
|
21
|
+
chmod +x ./tmp/cc-test-reporter
|
|
22
|
+
- run:
|
|
23
|
+
name: Run tests
|
|
24
|
+
command: |
|
|
25
|
+
./tmp/cc-test-reporter before-build
|
|
26
|
+
bundle exec rspec
|
|
27
|
+
./tmp/cc-test-reporter after-build --coverage-input-type simplecov --exit-code $?
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
data/Gemfile
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
source
|
|
1
|
+
source "https://rubygems.org"
|
|
2
2
|
|
|
3
3
|
# Specify your gem's dependencies in rack-healthcheck.gemspec
|
|
4
4
|
gemspec
|
|
@@ -7,3 +7,7 @@ group :test do
|
|
|
7
7
|
gem "pry"
|
|
8
8
|
gem "timecop"
|
|
9
9
|
end
|
|
10
|
+
|
|
11
|
+
group :development do
|
|
12
|
+
gem "rubocop", "~> 0.61.1", require: false
|
|
13
|
+
end
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
rack-healthcheck (0.2.0)
|
|
5
|
+
|
|
6
|
+
GEM
|
|
7
|
+
remote: https://rubygems.org/
|
|
8
|
+
specs:
|
|
9
|
+
ast (2.4.0)
|
|
10
|
+
coderay (1.1.2)
|
|
11
|
+
diff-lcs (1.3)
|
|
12
|
+
docile (1.3.1)
|
|
13
|
+
jaro_winkler (1.5.1)
|
|
14
|
+
json (2.1.0)
|
|
15
|
+
method_source (0.9.2)
|
|
16
|
+
parallel (1.12.1)
|
|
17
|
+
parser (2.5.3.0)
|
|
18
|
+
ast (~> 2.4.0)
|
|
19
|
+
powerpack (0.1.2)
|
|
20
|
+
pry (0.12.2)
|
|
21
|
+
coderay (~> 1.1.0)
|
|
22
|
+
method_source (~> 0.9.0)
|
|
23
|
+
rainbow (3.0.0)
|
|
24
|
+
rake (12.3.2)
|
|
25
|
+
rspec (3.8.0)
|
|
26
|
+
rspec-core (~> 3.8.0)
|
|
27
|
+
rspec-expectations (~> 3.8.0)
|
|
28
|
+
rspec-mocks (~> 3.8.0)
|
|
29
|
+
rspec-core (3.8.0)
|
|
30
|
+
rspec-support (~> 3.8.0)
|
|
31
|
+
rspec-expectations (3.8.2)
|
|
32
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
33
|
+
rspec-support (~> 3.8.0)
|
|
34
|
+
rspec-mocks (3.8.0)
|
|
35
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
36
|
+
rspec-support (~> 3.8.0)
|
|
37
|
+
rspec-support (3.8.0)
|
|
38
|
+
rubocop (0.61.1)
|
|
39
|
+
jaro_winkler (~> 1.5.1)
|
|
40
|
+
parallel (~> 1.10)
|
|
41
|
+
parser (>= 2.5, != 2.5.1.1)
|
|
42
|
+
powerpack (~> 0.1)
|
|
43
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
44
|
+
ruby-progressbar (~> 1.7)
|
|
45
|
+
unicode-display_width (~> 1.4.0)
|
|
46
|
+
ruby-progressbar (1.10.0)
|
|
47
|
+
simplecov (0.16.1)
|
|
48
|
+
docile (~> 1.1)
|
|
49
|
+
json (>= 1.8, < 3)
|
|
50
|
+
simplecov-html (~> 0.10.0)
|
|
51
|
+
simplecov-html (0.10.2)
|
|
52
|
+
timecop (0.9.1)
|
|
53
|
+
unicode-display_width (1.4.0)
|
|
54
|
+
|
|
55
|
+
PLATFORMS
|
|
56
|
+
ruby
|
|
57
|
+
|
|
58
|
+
DEPENDENCIES
|
|
59
|
+
bundler (~> 1.17, >= 1.17.2)
|
|
60
|
+
pry
|
|
61
|
+
rack-healthcheck!
|
|
62
|
+
rake (~> 12.3, >= 12.3.2)
|
|
63
|
+
rspec (~> 3.8)
|
|
64
|
+
rubocop (~> 0.61.1)
|
|
65
|
+
simplecov (~> 0.16.1)
|
|
66
|
+
timecop
|
|
67
|
+
|
|
68
|
+
BUNDLED WITH
|
|
69
|
+
1.17.2
|
data/README.md
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
[](https://travis-ci.org/downgba/rack-healthcheck)
|
|
2
|
-
[](https://codeclimate.com/github/downgba/rack-healthcheck/test_coverage)
|
|
3
|
+
[](https://codeclimate.com/github/downgba/rack-healthcheck/maintainability)
|
|
3
4
|
|
|
4
5
|
# Rack::Healthcheck
|
|
5
6
|
|
|
6
|
-
Is a middleware that verifies if your app and all resources that it needs
|
|
7
|
+
Is a middleware that verifies if your app and all resources that it needs are available.
|
|
7
8
|
|
|
8
9
|
## Installation
|
|
9
10
|
|
|
@@ -65,7 +66,7 @@ Rack::Healthcheck.configure do |config|
|
|
|
65
66
|
end
|
|
66
67
|
```
|
|
67
68
|
|
|
68
|
-
##### Available checks
|
|
69
|
+
##### Available checks
|
|
69
70
|
|
|
70
71
|
* Rack::Healthcheck::Checks::ActiveRecord.new(name, config = {})
|
|
71
72
|
* Rack::Healthcheck::Checks::MongoDB.new(name, config = {})
|
|
@@ -73,7 +74,7 @@ end
|
|
|
73
74
|
* Rack::Healthcheck::Checks::Redis.new(name, config = {})
|
|
74
75
|
* Rack::Healthcheck::Checks::HTTPRequest.new(name, config = {})
|
|
75
76
|
|
|
76
|
-
You can inform if one of your checks is optional, so this check will be disregarded in final result.
|
|
77
|
+
You can inform if one of your checks is optional, so this check will be disregarded in final result.
|
|
77
78
|
To do that you just need to pass a hash with `:optional` key.
|
|
78
79
|
|
|
79
80
|
```ruby
|
|
@@ -87,7 +88,7 @@ Rack::Healthcheck::Checks::ActiveRecord.new("Test", {optional: true, url: "http:
|
|
|
87
88
|
```
|
|
88
89
|
### Routes
|
|
89
90
|
|
|
90
|
-
By default this gem creates two routes `/healthcheck` and `/healthcheck/complete`.
|
|
91
|
+
By default this gem creates two routes `/healthcheck` and `/healthcheck/complete`.
|
|
91
92
|
|
|
92
93
|
The `/healthcheck` route doesn't verify the services used by application. This is the fastest way to tell to load balancer if it should or not keep the machine in the pool.
|
|
93
94
|
These are the available HTTP methods for this route:
|
|
@@ -96,7 +97,7 @@ These are the available HTTP methods for this route:
|
|
|
96
97
|
* POST -> Changes the current status to LIVE
|
|
97
98
|
* DELETE -> Changes the current status to DEAD
|
|
98
99
|
|
|
99
|
-
The `/healthcheck/complete` performs all configured checks and returns a JSON with a lot of
|
|
100
|
+
The `/healthcheck/complete` performs all configured checks and returns a JSON with a lot of information (elapsed time, status for each service, global status considering only required services).
|
|
100
101
|
Example:
|
|
101
102
|
```json
|
|
102
103
|
{
|
data/Rakefile
CHANGED
data/lib/rack/healthcheck.rb
CHANGED
|
@@ -2,14 +2,16 @@ require "rack/healthcheck/version"
|
|
|
2
2
|
require "rack/healthcheck/middleware"
|
|
3
3
|
require "rack/healthcheck/configuration"
|
|
4
4
|
|
|
5
|
-
module Rack
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
module Rack
|
|
6
|
+
module Healthcheck
|
|
7
|
+
class << self
|
|
8
|
+
def configuration
|
|
9
|
+
@configuration ||= Configuration.new
|
|
10
|
+
end
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
def configure
|
|
13
|
+
yield(configuration)
|
|
14
|
+
end
|
|
13
15
|
end
|
|
14
16
|
end
|
|
15
17
|
end
|
|
@@ -1,30 +1,32 @@
|
|
|
1
1
|
require "rack/healthcheck/actions/load_balancer"
|
|
2
2
|
require "rack/healthcheck/actions/complete"
|
|
3
3
|
|
|
4
|
-
module Rack
|
|
5
|
-
|
|
6
|
-
class
|
|
4
|
+
module Rack
|
|
5
|
+
module Healthcheck
|
|
6
|
+
class Action
|
|
7
|
+
class InvalidAction < RuntimeError; end
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
@mount_at = "healthcheck"
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
class << self
|
|
12
|
+
attr_accessor :mount_at
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
def get(path, request_method)
|
|
15
|
+
raise InvalidAction, "Unknown action" unless available_actions.key?(path)
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
available_actions[path].send(:new, path, request_method)
|
|
18
|
+
end
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
def available_actions
|
|
21
|
+
route = @mount_at.gsub(%r{^/}, "")
|
|
22
|
+
{
|
|
23
|
+
"/#{route}" => Rack::Healthcheck::Actions::LoadBalancer,
|
|
24
|
+
"/#{route}/complete" => Rack::Healthcheck::Actions::Complete
|
|
25
|
+
}
|
|
26
|
+
end
|
|
25
27
|
end
|
|
26
|
-
end
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
private_class_method :new
|
|
30
|
+
end
|
|
29
31
|
end
|
|
30
32
|
end
|
|
@@ -1,23 +1,27 @@
|
|
|
1
|
-
module Rack
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
module Rack
|
|
2
|
+
module Healthcheck
|
|
3
|
+
module Actions
|
|
4
|
+
class Base
|
|
5
|
+
class InvalidRequestMethod < RuntimeError; end
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
VALID_REQUEST_METHODS = [:get].freeze
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
attr_accessor :path, :request_method
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
def initialize(path, request_method)
|
|
12
|
+
method = request_method.downcase.to_sym
|
|
13
|
+
raise InvalidRequestMethod, "Method not allowed" unless valid_request_method?(method)
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
@path = path
|
|
16
|
+
@request_method = method
|
|
17
|
+
end
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
protected
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
def valid_request_method?(method)
|
|
22
|
+
self.class::VALID_REQUEST_METHODS.include?(method)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
21
25
|
end
|
|
22
26
|
end
|
|
23
27
|
end
|
|
@@ -6,37 +6,41 @@ require "rack/healthcheck/checks/rabbit_mq"
|
|
|
6
6
|
require "rack/healthcheck/checks/redis"
|
|
7
7
|
require "rack/healthcheck/checks/http_request"
|
|
8
8
|
|
|
9
|
-
module Rack
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
module Rack
|
|
10
|
+
module Healthcheck
|
|
11
|
+
module Actions
|
|
12
|
+
class Complete < Base
|
|
13
|
+
def get
|
|
14
|
+
perform
|
|
15
|
+
["200", { "Content-Type" => "application/json" }, [result.to_json]]
|
|
16
|
+
end
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
private
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
def result
|
|
21
|
+
results = []
|
|
22
|
+
status = true
|
|
23
|
+
Rack::Healthcheck.configuration.checks.each do |check|
|
|
24
|
+
status = (status == true && check.keep_in_pool?)
|
|
25
|
+
results << check.to_hash
|
|
26
|
+
end
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
{
|
|
29
|
+
name: Rack::Healthcheck.configuration.app_name,
|
|
30
|
+
status: status,
|
|
31
|
+
version: Rack::Healthcheck.configuration.app_version,
|
|
32
|
+
checks: results
|
|
33
|
+
}
|
|
34
|
+
end
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
def perform
|
|
37
|
+
threads = Rack::Healthcheck.configuration.checks.map do |check|
|
|
38
|
+
Thread.new { check.run }
|
|
39
|
+
end
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
threads.each(&:join)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
40
44
|
end
|
|
41
45
|
end
|
|
42
46
|
end
|
|
@@ -1,41 +1,45 @@
|
|
|
1
1
|
require "rack/healthcheck/actions/base"
|
|
2
2
|
|
|
3
|
-
module Rack
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
module Rack
|
|
4
|
+
module Healthcheck
|
|
5
|
+
module Actions
|
|
6
|
+
class LoadBalancer < Base
|
|
7
|
+
LIVE = "LIVE".freeze
|
|
8
|
+
DEAD = "DEAD".freeze
|
|
9
|
+
VALID_REQUEST_METHODS = %i[get post delete].freeze
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
@status = LIVE
|
|
12
|
+
class << self
|
|
13
|
+
attr_accessor :status
|
|
14
|
+
end
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
# Returns the current status to load balancer
|
|
17
|
+
# When status is LIVE the load balancer keeps the machine in pool
|
|
18
|
+
# When status is DEAD the load balancer removes the machine from pool
|
|
19
|
+
def get
|
|
20
|
+
response
|
|
21
|
+
end
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
# Change current status to LIVE
|
|
24
|
+
# This method is used to add the machine in pool
|
|
25
|
+
def post
|
|
26
|
+
self.class.status = LIVE
|
|
27
|
+
response
|
|
28
|
+
end
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
# Change current status to DEAD
|
|
31
|
+
# This method is used to remove the machine from pool
|
|
32
|
+
def delete
|
|
33
|
+
self.class.status = DEAD
|
|
34
|
+
response
|
|
35
|
+
end
|
|
34
36
|
|
|
35
|
-
|
|
37
|
+
private
|
|
36
38
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
def response
|
|
40
|
+
["200", { "Content-Type" => "text/plain" }, [self.class.status]]
|
|
41
|
+
end
|
|
42
|
+
end
|
|
39
43
|
end
|
|
40
44
|
end
|
|
41
45
|
end
|
|
@@ -1,27 +1,31 @@
|
|
|
1
1
|
require "rack/healthcheck/checks/base"
|
|
2
2
|
require "rack/healthcheck/type"
|
|
3
3
|
|
|
4
|
-
module Rack
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
4
|
+
module Rack
|
|
5
|
+
module Healthcheck
|
|
6
|
+
module Checks
|
|
7
|
+
class ActiveRecord < Base
|
|
8
|
+
# @param name [String]
|
|
9
|
+
# @param config [Hash<Symbol, Object>] Hash with optional configs
|
|
10
|
+
# @example
|
|
11
|
+
# name = Database
|
|
12
|
+
# config {
|
|
13
|
+
# optional: false,
|
|
14
|
+
# url: "mydatabase.com"
|
|
15
|
+
# }
|
|
16
|
+
def initialize(name, config = {})
|
|
17
|
+
super(name, Rack::Healthcheck::Type::DATABASE, config[:optional], config[:url])
|
|
18
|
+
end
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
private
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
def check
|
|
23
|
+
::ActiveRecord::Migrator.current_version
|
|
24
|
+
@status = true
|
|
25
|
+
rescue StandardError => _
|
|
26
|
+
@status = false
|
|
27
|
+
end
|
|
28
|
+
end
|
|
25
29
|
end
|
|
26
30
|
end
|
|
27
31
|
end
|
|
@@ -1,43 +1,48 @@
|
|
|
1
|
-
module Rack
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
1
|
+
module Rack
|
|
2
|
+
module Healthcheck
|
|
3
|
+
module Checks
|
|
4
|
+
class Base
|
|
5
|
+
class InvalidType < RuntimeError; end
|
|
6
|
+
|
|
7
|
+
attr_accessor :name, :optional, :url
|
|
8
|
+
attr_reader :type, :status, :elapsed_time
|
|
9
|
+
|
|
10
|
+
def initialize(name, type, optional, url)
|
|
11
|
+
unless Rack::Healthcheck::Type::ALL.include?(type)
|
|
12
|
+
raise InvalidType, "Type must be one of these options #{Rack::Healthcheck::Type::ALL.join(', ')}"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
@name = name
|
|
16
|
+
@optional = optional || false
|
|
17
|
+
@url = url
|
|
18
|
+
@type = type
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def run
|
|
22
|
+
start = Time.now
|
|
23
|
+
check
|
|
24
|
+
@elapsed_time = Time.now - start
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def to_hash
|
|
28
|
+
{
|
|
29
|
+
name: name,
|
|
30
|
+
type: type,
|
|
31
|
+
status: status,
|
|
32
|
+
optional: optional,
|
|
33
|
+
time: elapsed_time,
|
|
34
|
+
url: url
|
|
35
|
+
}.reject { |_key, value| value.nil? }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def keep_in_pool?
|
|
39
|
+
(!optional && status == true) || optional
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def check; end
|
|
45
|
+
end
|
|
41
46
|
end
|
|
42
47
|
end
|
|
43
48
|
end
|
|
@@ -3,40 +3,44 @@ require "rack/healthcheck/type"
|
|
|
3
3
|
require "uri"
|
|
4
4
|
require "net/http"
|
|
5
5
|
|
|
6
|
-
module Rack
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
module Rack
|
|
7
|
+
module Healthcheck
|
|
8
|
+
module Checks
|
|
9
|
+
class HTTPRequest < Base
|
|
10
|
+
class InvalidURL < RuntimeError; end
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
attr_reader :config
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
14
|
+
# @param name [String]
|
|
15
|
+
# @param config [Hash<Symbol, Object>] Hash with configs
|
|
16
|
+
# @example
|
|
17
|
+
# name = Ceph or Another system
|
|
18
|
+
# config = {
|
|
19
|
+
# url: localhost,
|
|
20
|
+
# headers: {"Host" => "something"},
|
|
21
|
+
# service_type: "INTERNAL_SERVICE",
|
|
22
|
+
# expected_result: "LIVE",
|
|
23
|
+
# optional: true
|
|
24
|
+
# }
|
|
25
|
+
# @see Rack::Healthcheck::Type
|
|
26
|
+
def initialize(name, config)
|
|
27
|
+
raise InvalidURL, "Expected :url to be a http or https endpoint" if config[:url].match(%r{^(http://|https://)}).nil?
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
super(name, config[:service_type], config[:optional], config[:url])
|
|
30
|
+
@config = config
|
|
31
|
+
end
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
private
|
|
32
34
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
def check
|
|
36
|
+
uri = URI(url)
|
|
37
|
+
http = Net::HTTP.new(uri.host)
|
|
38
|
+
response = http.get(uri.path, config[:headers])
|
|
39
|
+
@status = response.body.delete("\n") == config[:expected_result]
|
|
40
|
+
rescue StandardError => _
|
|
41
|
+
@status = false
|
|
42
|
+
end
|
|
43
|
+
end
|
|
40
44
|
end
|
|
41
45
|
end
|
|
42
46
|
end
|
|
@@ -1,27 +1,31 @@
|
|
|
1
1
|
require "rack/healthcheck/checks/base"
|
|
2
2
|
require "rack/healthcheck/type"
|
|
3
3
|
|
|
4
|
-
module Rack
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
4
|
+
module Rack
|
|
5
|
+
module Healthcheck
|
|
6
|
+
module Checks
|
|
7
|
+
class MongoDB < Base
|
|
8
|
+
# @param name [String]
|
|
9
|
+
# @param config [Hash<Symbol, Object>] Hash with optional configs
|
|
10
|
+
# @example
|
|
11
|
+
# name = Database
|
|
12
|
+
# config {
|
|
13
|
+
# optional: false,
|
|
14
|
+
# url: "mymongodb.com"
|
|
15
|
+
# }
|
|
16
|
+
def initialize(name, config = {})
|
|
17
|
+
super(name, Rack::Healthcheck::Type::DATABASE, config[:optional], config[:url])
|
|
18
|
+
end
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
private
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
def check
|
|
23
|
+
Mongoid::Sessions.with_name(:default).command(dbStats: 1)["db"]
|
|
24
|
+
@status = true
|
|
25
|
+
rescue StandardError => _
|
|
26
|
+
@status = false
|
|
27
|
+
end
|
|
28
|
+
end
|
|
25
29
|
end
|
|
26
30
|
end
|
|
27
31
|
end
|
|
@@ -1,35 +1,39 @@
|
|
|
1
1
|
require "rack/healthcheck/checks/base"
|
|
2
2
|
require "rack/healthcheck/type"
|
|
3
3
|
|
|
4
|
-
module Rack
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
module Rack
|
|
5
|
+
module Healthcheck
|
|
6
|
+
module Checks
|
|
7
|
+
class RabbitMQ < Base
|
|
8
|
+
attr_reader :config
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
10
|
+
# @param name [String]
|
|
11
|
+
# @param config [Hash<Symbol,Object>] Hash with configs
|
|
12
|
+
# @example
|
|
13
|
+
# name = RabbitMQ
|
|
14
|
+
# config = {
|
|
15
|
+
# hosts: [localhost],
|
|
16
|
+
# port: 5672,
|
|
17
|
+
# user: guest,
|
|
18
|
+
# pass: guest,
|
|
19
|
+
# optional: true
|
|
20
|
+
# }
|
|
21
|
+
def initialize(name, config)
|
|
22
|
+
super(name, Rack::Healthcheck::Type::MESSAGING, config[:optional], config[:hosts])
|
|
23
|
+
@config = config
|
|
24
|
+
end
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
private
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
def check
|
|
29
|
+
connection = Bunny.new(config)
|
|
30
|
+
connection.start
|
|
31
|
+
connection.close
|
|
32
|
+
@status = true
|
|
33
|
+
rescue StandardError => _
|
|
34
|
+
@status = false
|
|
35
|
+
end
|
|
36
|
+
end
|
|
33
37
|
end
|
|
34
38
|
end
|
|
35
39
|
end
|
|
@@ -1,33 +1,37 @@
|
|
|
1
1
|
require "rack/healthcheck/checks/base"
|
|
2
2
|
require "rack/healthcheck/type"
|
|
3
3
|
|
|
4
|
-
module Rack
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
module Rack
|
|
5
|
+
module Healthcheck
|
|
6
|
+
module Checks
|
|
7
|
+
class Redis < Base
|
|
8
|
+
attr_reader :config
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
10
|
+
# @param name [String]
|
|
11
|
+
# @param config [Hash<Symbol,String>] Hash with configs
|
|
12
|
+
# @param optional [Boolean] Flag used to inform if this service is optional
|
|
13
|
+
# @example
|
|
14
|
+
# name = Redis
|
|
15
|
+
# config = {
|
|
16
|
+
# url: "redis://localhost:6379",
|
|
17
|
+
# password: "pass",
|
|
18
|
+
# optional: true
|
|
19
|
+
# }
|
|
20
|
+
def initialize(name, config)
|
|
21
|
+
super(name, Rack::Healthcheck::Type::CACHE, config[:optional], config[:url])
|
|
22
|
+
@config = config
|
|
23
|
+
end
|
|
22
24
|
|
|
23
|
-
|
|
25
|
+
private
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
def check
|
|
28
|
+
redis = ::Redis.new(config)
|
|
29
|
+
redis.info
|
|
30
|
+
@status = true
|
|
31
|
+
rescue StandardError => _
|
|
32
|
+
@status = false
|
|
33
|
+
end
|
|
34
|
+
end
|
|
31
35
|
end
|
|
32
36
|
end
|
|
33
37
|
end
|
|
@@ -1,21 +1,24 @@
|
|
|
1
|
-
module Rack
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
module Rack
|
|
2
|
+
module Healthcheck
|
|
3
|
+
# This class is responsible by keep all services that the healthcheck needs to verify
|
|
4
|
+
#
|
|
5
|
+
# app_name [String] This value is used only in complete check result
|
|
6
|
+
# app_version [String] This value is used only in complete check result
|
|
7
|
+
# checks [Array] Array that contains all services that healthcheck needs to verify
|
|
8
|
+
# @example
|
|
9
|
+
# app_name = "Rack Healthcheck"
|
|
10
|
+
# app_version = 1.0
|
|
11
|
+
# checks = [
|
|
12
|
+
# Rack::Healthcheck::Checks::ActiveRecord.new("database"),
|
|
13
|
+
# Rack::Healthcheck::Checks::Redis.new("redis", {})
|
|
14
|
+
# ]
|
|
15
|
+
class Configuration
|
|
16
|
+
attr_accessor :app_name, :app_version
|
|
17
|
+
attr_writer :checks
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
def checks
|
|
20
|
+
@checks || {}
|
|
21
|
+
end
|
|
19
22
|
end
|
|
20
23
|
end
|
|
21
24
|
end
|
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
require "rack/healthcheck/action"
|
|
2
2
|
|
|
3
|
-
module Rack
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
module Rack
|
|
4
|
+
module Healthcheck
|
|
5
|
+
class Middleware
|
|
6
|
+
def initialize(app, mount_at = nil)
|
|
7
|
+
@app = app
|
|
8
|
+
Rack::Healthcheck::Action.mount_at = mount_at unless mount_at.nil?
|
|
9
|
+
end
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
def call(env)
|
|
12
|
+
path = env["PATH_INFO"]
|
|
13
|
+
request_method = env["REQUEST_METHOD"]
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
action = Rack::Healthcheck::Action.get(path, request_method)
|
|
16
|
+
action.send(request_method.downcase)
|
|
17
|
+
rescue Rack::Healthcheck::Action::InvalidAction, Rack::Healthcheck::Actions::Base::InvalidRequestMethod
|
|
18
|
+
@app.call(env)
|
|
19
|
+
end
|
|
18
20
|
end
|
|
19
21
|
end
|
|
20
22
|
end
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
module Rack
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
module Rack
|
|
2
|
+
module Healthcheck
|
|
3
|
+
class Type
|
|
4
|
+
ALL = [
|
|
5
|
+
CACHE = "CACHE".freeze,
|
|
6
|
+
EXTERNAL_SERVICE = "EXTERNAL_SERVICE".freeze,
|
|
7
|
+
INTERNAL_SERVICE = "INTERNAL_SERVICE".freeze,
|
|
8
|
+
STORAGE = "STORAGE".freeze,
|
|
9
|
+
MESSAGING = "MESSAGING".freeze,
|
|
10
|
+
DATABASE = "DATABASE".freeze,
|
|
11
|
+
FILE = "FILE".freeze
|
|
12
|
+
].freeze
|
|
13
|
+
end
|
|
12
14
|
end
|
|
13
15
|
end
|
data/rack-healthcheck.gemspec
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
|
1
|
+
lib = File.expand_path("lib", __dir__)
|
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
-
require
|
|
3
|
+
require "rack/healthcheck/version"
|
|
5
4
|
|
|
6
5
|
Gem::Specification.new do |spec|
|
|
7
6
|
spec.name = "rack-healthcheck"
|
|
@@ -19,9 +18,8 @@ Gem::Specification.new do |spec|
|
|
|
19
18
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
20
19
|
spec.require_paths = ["lib"]
|
|
21
20
|
|
|
22
|
-
spec.add_development_dependency "bundler", "~> 1.
|
|
23
|
-
spec.add_development_dependency "
|
|
24
|
-
spec.add_development_dependency "
|
|
25
|
-
spec.add_development_dependency "
|
|
26
|
-
spec.add_development_dependency "rspec", "~> 3.0"
|
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.17", ">= 1.17.2"
|
|
22
|
+
spec.add_development_dependency "rake", "~> 12.3", ">= 12.3.2"
|
|
23
|
+
spec.add_development_dependency "rspec", "~> 3.8"
|
|
24
|
+
spec.add_development_dependency "simplecov", "~> 0.16.1"
|
|
27
25
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rack-healthcheck
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Leandro Maduro
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2018-12-15 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -16,70 +16,68 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '1.
|
|
20
|
-
type: :development
|
|
21
|
-
prerelease: false
|
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
-
requirements:
|
|
24
|
-
- - "~>"
|
|
25
|
-
- !ruby/object:Gem::Version
|
|
26
|
-
version: '1.12'
|
|
27
|
-
- !ruby/object:Gem::Dependency
|
|
28
|
-
name: coveralls
|
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
|
30
|
-
requirements:
|
|
19
|
+
version: '1.17'
|
|
31
20
|
- - ">="
|
|
32
21
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
22
|
+
version: 1.17.2
|
|
34
23
|
type: :development
|
|
35
24
|
prerelease: false
|
|
36
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
26
|
requirements:
|
|
27
|
+
- - "~>"
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: '1.17'
|
|
38
30
|
- - ">="
|
|
39
31
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
32
|
+
version: 1.17.2
|
|
41
33
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name:
|
|
34
|
+
name: rake
|
|
43
35
|
requirement: !ruby/object:Gem::Requirement
|
|
44
36
|
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '12.3'
|
|
45
40
|
- - ">="
|
|
46
41
|
- !ruby/object:Gem::Version
|
|
47
|
-
version:
|
|
42
|
+
version: 12.3.2
|
|
48
43
|
type: :development
|
|
49
44
|
prerelease: false
|
|
50
45
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
46
|
requirements:
|
|
47
|
+
- - "~>"
|
|
48
|
+
- !ruby/object:Gem::Version
|
|
49
|
+
version: '12.3'
|
|
52
50
|
- - ">="
|
|
53
51
|
- !ruby/object:Gem::Version
|
|
54
|
-
version:
|
|
52
|
+
version: 12.3.2
|
|
55
53
|
- !ruby/object:Gem::Dependency
|
|
56
|
-
name:
|
|
54
|
+
name: rspec
|
|
57
55
|
requirement: !ruby/object:Gem::Requirement
|
|
58
56
|
requirements:
|
|
59
57
|
- - "~>"
|
|
60
58
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
59
|
+
version: '3.8'
|
|
62
60
|
type: :development
|
|
63
61
|
prerelease: false
|
|
64
62
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
63
|
requirements:
|
|
66
64
|
- - "~>"
|
|
67
65
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '
|
|
66
|
+
version: '3.8'
|
|
69
67
|
- !ruby/object:Gem::Dependency
|
|
70
|
-
name:
|
|
68
|
+
name: simplecov
|
|
71
69
|
requirement: !ruby/object:Gem::Requirement
|
|
72
70
|
requirements:
|
|
73
71
|
- - "~>"
|
|
74
72
|
- !ruby/object:Gem::Version
|
|
75
|
-
version:
|
|
73
|
+
version: 0.16.1
|
|
76
74
|
type: :development
|
|
77
75
|
prerelease: false
|
|
78
76
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
77
|
requirements:
|
|
80
78
|
- - "~>"
|
|
81
79
|
- !ruby/object:Gem::Version
|
|
82
|
-
version:
|
|
80
|
+
version: 0.16.1
|
|
83
81
|
description: A healthcheck interface for Sinatra and Rails framework
|
|
84
82
|
email:
|
|
85
83
|
- leandromaduro1@gmail.com
|
|
@@ -87,10 +85,12 @@ executables: []
|
|
|
87
85
|
extensions: []
|
|
88
86
|
extra_rdoc_files: []
|
|
89
87
|
files:
|
|
88
|
+
- ".circleci/config.yml"
|
|
90
89
|
- ".gitignore"
|
|
91
90
|
- ".rspec"
|
|
92
|
-
- ".
|
|
91
|
+
- ".rubocop.yml"
|
|
93
92
|
- Gemfile
|
|
93
|
+
- Gemfile.lock
|
|
94
94
|
- LICENSE.txt
|
|
95
95
|
- README.md
|
|
96
96
|
- Rakefile
|
|
@@ -132,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
132
132
|
version: '0'
|
|
133
133
|
requirements: []
|
|
134
134
|
rubyforge_project:
|
|
135
|
-
rubygems_version: 2.
|
|
135
|
+
rubygems_version: 2.7.8
|
|
136
136
|
signing_key:
|
|
137
137
|
specification_version: 4
|
|
138
138
|
summary: A healthcheck interface for Sinatra and Rails framework
|