middleware_healthcheck 0.2.1
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/MIT-LICENSE +20 -0
- data/README.md +97 -0
- data/Rakefile +23 -0
- data/lib/middleware_healthcheck.rb +19 -0
- data/lib/middleware_healthcheck/configuration.rb +31 -0
- data/lib/middleware_healthcheck/default_checkers.rb +8 -0
- data/lib/middleware_healthcheck/default_checkers/active_record_checker.rb +31 -0
- data/lib/middleware_healthcheck/main_checker.rb +103 -0
- data/lib/middleware_healthcheck/middleware.rb +17 -0
- data/lib/middleware_healthcheck/rails.rb +11 -0
- data/lib/middleware_healthcheck/version.rb +3 -0
- data/lib/tasks/middleware_healthcheck_tasks.rake +4 -0
- metadata +116 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 38b91fef5d4a3905b2813f39042c793f360204d0b9c628f4f924d659ff192a2d
|
4
|
+
data.tar.gz: e147717615b025caeea300ad09aaf6d340018b28a740f61cd818a7f38e7fdfd1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bffd5928ca999c46a20c7d6af18302899818b0b91aad1e6a2d5040bb02c28bb3d94d191febdf20376e820407b3785d22d03b63177275c1614c7265d8bdff5f24
|
7
|
+
data.tar.gz: b5798095104d400611081987408e5e4b19f1f2f4c3f13de21ab010c71d0746fe20d77497f434562d7280fec3adc449ae03d2ff4839a1302a36db7d34093480cc
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2017 Adam Wieczorkowski
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
# MiddlewareHealthcheck
|
2
|
+
|
3
|
+
## Installation
|
4
|
+
Add this line to your application's Gemfile:
|
5
|
+
```ruby
|
6
|
+
gem 'middleware_healthcheck'
|
7
|
+
```
|
8
|
+
|
9
|
+
And then execute:
|
10
|
+
```bash
|
11
|
+
$ bundle
|
12
|
+
```
|
13
|
+
|
14
|
+
Or install it yourself as:
|
15
|
+
```bash
|
16
|
+
$ gem install middleware_healthcheck
|
17
|
+
```
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
Run basic check (without running any advanced checkers):
|
21
|
+
```
|
22
|
+
/healthcheck
|
23
|
+
```
|
24
|
+
|
25
|
+
To run all available checkers, add `full` parameter:
|
26
|
+
```
|
27
|
+
/healthcheck?full=1
|
28
|
+
```
|
29
|
+
|
30
|
+
To run selected checkers, add `checks` parameter, where the value is the name of checkers separated by a comma:
|
31
|
+
```
|
32
|
+
/healthcheck?checks=active_record,second_checker,another_checker
|
33
|
+
```
|
34
|
+
|
35
|
+
To change default path and parameters see Configuration section
|
36
|
+
|
37
|
+
## Configuration
|
38
|
+
Create ``config/initializers/middleware_healthcheck.rb`` file
|
39
|
+
```ruby
|
40
|
+
MiddlewareHealthcheck.configure do |config|
|
41
|
+
config.healthcheck_path = "my_custom_path"
|
42
|
+
...
|
43
|
+
end
|
44
|
+
```
|
45
|
+
Available options:
|
46
|
+
```
|
47
|
+
healthcheck_path
|
48
|
+
full_check_param_name
|
49
|
+
selected_check_param_name
|
50
|
+
error_response_status
|
51
|
+
success_response_status
|
52
|
+
success_response_body
|
53
|
+
errors_delimiter
|
54
|
+
selected_check_param_split_delimiter
|
55
|
+
```
|
56
|
+
|
57
|
+
## Custom Checkers
|
58
|
+
Your Custom Checker class should look like this:
|
59
|
+
```ruby
|
60
|
+
class MyCustomChecker
|
61
|
+
attr_accessor :error
|
62
|
+
|
63
|
+
def initialize(_app, _env)
|
64
|
+
end
|
65
|
+
|
66
|
+
def healthy?
|
67
|
+
if everything_ok?
|
68
|
+
true
|
69
|
+
else
|
70
|
+
self.error = 'Error message'
|
71
|
+
false
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
To include Custom Checker, just add
|
78
|
+
```ruby
|
79
|
+
HealthcheckMiddleware.configure do |config|
|
80
|
+
config.checkers << MyCustomChecker
|
81
|
+
end
|
82
|
+
```
|
83
|
+
in initializer.
|
84
|
+
|
85
|
+
## Development
|
86
|
+
|
87
|
+
```
|
88
|
+
# build the docker containers
|
89
|
+
docker-compose build
|
90
|
+
|
91
|
+
# run the specs
|
92
|
+
docker-compose run --rm app bundle exec rspec
|
93
|
+
|
94
|
+
```
|
95
|
+
|
96
|
+
## License
|
97
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'MiddlewareHealthcheck'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
require 'bundler/gem_tasks'
|
23
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "middleware_healthcheck/rails" if defined? Rails::Railtie
|
2
|
+
require "middleware_healthcheck/default_checkers"
|
3
|
+
require "middleware_healthcheck/configuration"
|
4
|
+
require "middleware_healthcheck/main_checker"
|
5
|
+
require "middleware_healthcheck/middleware"
|
6
|
+
|
7
|
+
module MiddlewareHealthcheck
|
8
|
+
class << self
|
9
|
+
attr_accessor :configuration
|
10
|
+
|
11
|
+
def configuration
|
12
|
+
@configuration ||= Configuration.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def configure
|
16
|
+
yield configuration
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module MiddlewareHealthcheck
|
2
|
+
class Configuration
|
3
|
+
DEFAULT_HEALTHCHECK_PATH = '/healthcheck'.freeze
|
4
|
+
DEFAULT_FULL_CHECK_PARAM_NAME = 'full'.freeze
|
5
|
+
DEFAULT_SELECTED_CHECK_PARAM_NAME = 'checks'.freeze
|
6
|
+
DEFAULT_ERROR_RESPONSE_STATUS = 422
|
7
|
+
DEFAULT_SUCCESS_RESPONSE_STATUS = 200
|
8
|
+
DEFAULT_SUCCESS_RESPONSE_BODY = "It's alive!".freeze
|
9
|
+
DEFAULT_ERRORS_DELIMITER = '; '.freeze
|
10
|
+
DEFAULT_SELECTED_CHECK_PARAM_SPLIT_DELIMITER = ','.freeze
|
11
|
+
|
12
|
+
attr_accessor :healthcheck_path, :full_check_param_name, :selected_check_param_name,
|
13
|
+
:error_response_status, :success_response_status, :success_response_body,
|
14
|
+
:errors_delimiter, :selected_check_param_split_delimiter, :checkers
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
self.healthcheck_path = DEFAULT_HEALTHCHECK_PATH
|
18
|
+
self.full_check_param_name = DEFAULT_FULL_CHECK_PARAM_NAME
|
19
|
+
self.selected_check_param_name = DEFAULT_SELECTED_CHECK_PARAM_NAME
|
20
|
+
self.error_response_status = DEFAULT_ERROR_RESPONSE_STATUS
|
21
|
+
self.success_response_status = DEFAULT_SUCCESS_RESPONSE_STATUS
|
22
|
+
self.success_response_body = DEFAULT_SUCCESS_RESPONSE_BODY
|
23
|
+
self.errors_delimiter = DEFAULT_ERRORS_DELIMITER
|
24
|
+
self.selected_check_param_split_delimiter = DEFAULT_SELECTED_CHECK_PARAM_SPLIT_DELIMITER
|
25
|
+
self.checkers = MiddlewareHealthcheck::DefaultCheckers.constants.map do |const|
|
26
|
+
klass = MiddlewareHealthcheck::DefaultCheckers.const_get(const)
|
27
|
+
klass if klass.is_a? Class
|
28
|
+
end.compact
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module MiddlewareHealthcheck
|
2
|
+
module DefaultCheckers
|
3
|
+
class ActiveRecordChecker
|
4
|
+
NOT_CONNECTED_ERROR = "Can't connect to database.".freeze
|
5
|
+
EXCEPTION_REGEXP = /^ActiveRecord::/.freeze
|
6
|
+
|
7
|
+
attr_accessor :error
|
8
|
+
|
9
|
+
def initialize(_app, _env)
|
10
|
+
end
|
11
|
+
|
12
|
+
def healthy?
|
13
|
+
ActiveRecord::Base.establish_connection
|
14
|
+
ActiveRecord::Base.connection
|
15
|
+
if ActiveRecord::Base.connected?
|
16
|
+
true
|
17
|
+
else
|
18
|
+
self.error = NOT_CONNECTED_ERROR
|
19
|
+
false
|
20
|
+
end
|
21
|
+
rescue => e
|
22
|
+
if e.class.to_s.match EXCEPTION_REGEXP
|
23
|
+
self.error = e.message
|
24
|
+
false
|
25
|
+
else
|
26
|
+
raise e
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module MiddlewareHealthcheck
|
2
|
+
class MainChecker
|
3
|
+
QUERY_STRING_KEY = "QUERY_STRING".freeze
|
4
|
+
UNDEFINED_CHECKER_ERROR = "Can't find checker: ".freeze
|
5
|
+
|
6
|
+
attr_accessor :app, :env
|
7
|
+
|
8
|
+
def initialize(app, env)
|
9
|
+
self.app = app
|
10
|
+
self.env = env
|
11
|
+
end
|
12
|
+
|
13
|
+
def check_health
|
14
|
+
if full_check?
|
15
|
+
run_all_checkers
|
16
|
+
elsif selected_check?
|
17
|
+
run_selected_checkers
|
18
|
+
end
|
19
|
+
|
20
|
+
build_response
|
21
|
+
end
|
22
|
+
|
23
|
+
def build_response
|
24
|
+
if errors.present?
|
25
|
+
build_error_response
|
26
|
+
else
|
27
|
+
build_success_response
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def build_success_response
|
32
|
+
build_text_response(
|
33
|
+
configuration.success_response_status,
|
34
|
+
configuration.success_response_body
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
def build_error_response
|
39
|
+
build_text_response(
|
40
|
+
configuration.error_response_status,
|
41
|
+
errors.join(configuration.errors_delimiter)
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
def build_text_response(status, body)
|
46
|
+
[ status, { "Content-Type" => "text/plain" }, [body] ]
|
47
|
+
end
|
48
|
+
|
49
|
+
def run_all_checkers
|
50
|
+
run_checkers(configuration.checkers)
|
51
|
+
end
|
52
|
+
|
53
|
+
def run_selected_checkers
|
54
|
+
run_checkers(selected_checkers)
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
def run_checkers(checkers)
|
59
|
+
checkers.each do |checker|
|
60
|
+
checker_instance = checker.new(@app, @env)
|
61
|
+
errors.push(checker_instance.error) unless checker_instance.healthy?
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def selected_checkers
|
66
|
+
selected_checkers_names.map do |checker_name|
|
67
|
+
find_checker_by_name(checker_name)
|
68
|
+
end.compact
|
69
|
+
end
|
70
|
+
|
71
|
+
def find_checker_by_name(name)
|
72
|
+
configuration.checkers.each do |checker|
|
73
|
+
return checker if checker.to_s.demodulize.underscore.gsub(/_checker$/, '') == name
|
74
|
+
end
|
75
|
+
errors.push(UNDEFINED_CHECKER_ERROR + name.camelize)
|
76
|
+
nil
|
77
|
+
end
|
78
|
+
|
79
|
+
def selected_checkers_names
|
80
|
+
@selected_check_param_names ||= params[configuration.selected_check_param_name]
|
81
|
+
.split(configuration.selected_check_param_split_delimiter)
|
82
|
+
end
|
83
|
+
|
84
|
+
def params
|
85
|
+
@params ||= Rack::Utils.parse_nested_query(@env[QUERY_STRING_KEY])
|
86
|
+
end
|
87
|
+
|
88
|
+
def errors
|
89
|
+
@errors ||= []
|
90
|
+
end
|
91
|
+
|
92
|
+
def full_check?
|
93
|
+
params[configuration.full_check_param_name].present?
|
94
|
+
end
|
95
|
+
def selected_check?
|
96
|
+
params[configuration.selected_check_param_name].present?
|
97
|
+
end
|
98
|
+
|
99
|
+
def configuration
|
100
|
+
@configuration ||= MiddlewareHealthcheck.configuration
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module MiddlewareHealthcheck
|
2
|
+
class Middleware
|
3
|
+
PATH_INFO_KEY = "PATH_INFO".freeze
|
4
|
+
|
5
|
+
def initialize(app)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
if env[PATH_INFO_KEY] == MiddlewareHealthcheck.configuration.healthcheck_path
|
11
|
+
MainChecker.new(@app, env).check_health
|
12
|
+
else
|
13
|
+
@app.call(env)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module MiddlewareHealthcheck
|
2
|
+
class Railtie < Rails::Railtie
|
3
|
+
initializer "middleware_healthcheck.configure_rails_initialization" do
|
4
|
+
app.middleware.insert_after Rails::Rack::Logger, MiddlewareHealthcheck::Middleware
|
5
|
+
end
|
6
|
+
|
7
|
+
def app
|
8
|
+
Rails.application
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
metadata
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: middleware_healthcheck
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Adam Wieczorkowski
|
8
|
+
- Claudio Perez Gamayo
|
9
|
+
- Jan Wieczorkowski
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2019-03-21 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rails
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - ">="
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '4.0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '4.0'
|
29
|
+
- !ruby/object:Gem::Dependency
|
30
|
+
name: sqlite3
|
31
|
+
requirement: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
type: :development
|
37
|
+
prerelease: false
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
- !ruby/object:Gem::Dependency
|
44
|
+
name: rspec-rails
|
45
|
+
requirement: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
type: :development
|
51
|
+
prerelease: false
|
52
|
+
version_requirements: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
- !ruby/object:Gem::Dependency
|
58
|
+
name: pry-byebug
|
59
|
+
requirement: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
type: :development
|
65
|
+
prerelease: false
|
66
|
+
version_requirements: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
description: Rack middleware to provide a healthcheck endpoint, useful for load balancers
|
72
|
+
health checks.
|
73
|
+
email:
|
74
|
+
- adam.wieczorkowski@naturaily.com
|
75
|
+
- claudio@firefield.com
|
76
|
+
- jan.wieczorkowski@naturaily.com
|
77
|
+
executables: []
|
78
|
+
extensions: []
|
79
|
+
extra_rdoc_files: []
|
80
|
+
files:
|
81
|
+
- MIT-LICENSE
|
82
|
+
- README.md
|
83
|
+
- Rakefile
|
84
|
+
- lib/middleware_healthcheck.rb
|
85
|
+
- lib/middleware_healthcheck/configuration.rb
|
86
|
+
- lib/middleware_healthcheck/default_checkers.rb
|
87
|
+
- lib/middleware_healthcheck/default_checkers/active_record_checker.rb
|
88
|
+
- lib/middleware_healthcheck/main_checker.rb
|
89
|
+
- lib/middleware_healthcheck/middleware.rb
|
90
|
+
- lib/middleware_healthcheck/rails.rb
|
91
|
+
- lib/middleware_healthcheck/version.rb
|
92
|
+
- lib/tasks/middleware_healthcheck_tasks.rake
|
93
|
+
homepage: ''
|
94
|
+
licenses:
|
95
|
+
- MIT
|
96
|
+
metadata: {}
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options: []
|
99
|
+
require_paths:
|
100
|
+
- lib
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
requirements: []
|
112
|
+
rubygems_version: 3.0.1
|
113
|
+
signing_key:
|
114
|
+
specification_version: 4
|
115
|
+
summary: Rack middleware to provide a healthcheck endpoint.
|
116
|
+
test_files: []
|