rack-ecg 0.0.5 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/main.yml +22 -0
- data/.rubocop.yml +21 -0
- data/.ruby-version +1 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +69 -0
- data/Gemfile +1 -0
- data/README.md +39 -31
- data/Rakefile +10 -1
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/examples/basic.ru +3 -2
- data/examples/checks.ru +3 -2
- data/examples/hook.ru +17 -0
- data/examples/mounted_path.ru +3 -2
- data/examples/parameters.ru +6 -5
- data/examples/stand_alone.ru +2 -1
- data/lib/rack-ecg.rb +1 -0
- data/lib/rack/ecg.rb +26 -12
- data/lib/rack/ecg/check.rb +23 -3
- data/lib/rack/ecg/check/active_record_connection.rb +4 -0
- data/lib/rack/ecg/check/error.rb +3 -3
- data/lib/rack/ecg/check/git_revision.rb +4 -1
- data/lib/rack/ecg/check/http.rb +3 -3
- data/lib/rack/ecg/check/migration_version.rb +4 -1
- data/lib/rack/ecg/check/redis_connection.rb +6 -0
- data/lib/rack/ecg/check/sequel_connection.rb +9 -2
- data/lib/rack/ecg/check_factory.rb +1 -0
- data/lib/rack/ecg/check_registry.rb +15 -2
- data/lib/rack/ecg/version.rb +3 -1
- data/rack-ecg.gemspec +31 -14
- metadata +79 -36
- data/.travis.yml +0 -28
- data/gemfiles/rack_v1.gemfile +0 -4
- data/spec/check_factory_spec.rb +0 -59
- data/spec/check_registry_spec.rb +0 -23
- data/spec/rack_middleware_spec.rb +0 -246
- data/spec/spec_helper.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: daea3d8ff855b734db9fc65f7ed6859114f1a89e095d06f7c26f907d011b65e9
|
4
|
+
data.tar.gz: b311a75d0c8555c21e9db5633bbbf3dc7304fd8dc42497dfeb9957edeb1f9233
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2cd8743e07657aaaf35ff83fde2d38d3ba836b0b2a2b439260f0547c6ce173d065e9812f46d1915811fc6bf41eb2ec2c30285d492639f5d75970167d36078b8e
|
7
|
+
data.tar.gz: f52644422ecd24cf6e072b4ddd5bd8edcc1de2a8653f65d2d0e230f9bea91fd5dfe18a1b96a035aa86aec61a125440d4a94125fc0b7c9a33c0e2665231ec4bd6
|
@@ -0,0 +1,22 @@
|
|
1
|
+
name: Ruby
|
2
|
+
|
3
|
+
on: [push,pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
test:
|
7
|
+
strategy:
|
8
|
+
matrix:
|
9
|
+
ruby: [2.5, 2.6, 2.7]
|
10
|
+
runs-on: ubuntu-latest
|
11
|
+
name: Test (Ruby ${{ matrix.ruby }})
|
12
|
+
steps:
|
13
|
+
- uses: actions/checkout@v2
|
14
|
+
- name: Set up Ruby
|
15
|
+
uses: ruby/setup-ruby@v1
|
16
|
+
with:
|
17
|
+
ruby-version: ${{ matrix.ruby }}
|
18
|
+
- name: Run the default task
|
19
|
+
run: |
|
20
|
+
gem install bundler -v 2.2.1
|
21
|
+
bundle install
|
22
|
+
bundle exec rake
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# The behavior of RuboCop can be controlled via the .rubocop.yml
|
2
|
+
# configuration file. It makes it possible to enable/disable
|
3
|
+
# certain cops (checks) and to alter their behavior if they accept
|
4
|
+
# any parameters. The file can be placed either in your home
|
5
|
+
# directory or in some project directory.
|
6
|
+
#
|
7
|
+
# RuboCop will start looking for the configuration file in the directory
|
8
|
+
# where the inspected file is and continue its way up to the root directory.
|
9
|
+
#
|
10
|
+
# See https://github.com/rubocop-hq/rubocop/blob/master/manual/configuration.md
|
11
|
+
|
12
|
+
inherit_gem:
|
13
|
+
rubocop-shopify: rubocop.yml
|
14
|
+
|
15
|
+
AllCops:
|
16
|
+
Exclude:
|
17
|
+
- 'vendor/**/*'
|
18
|
+
|
19
|
+
Naming/FileName:
|
20
|
+
Exclude:
|
21
|
+
- 'lib/rack-ecg.rb'
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.5.8
|
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--files lib/**/*.rb
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
# Changelog
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
|
4
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
5
|
+
|
6
|
+
## [Unreleased]
|
7
|
+
|
8
|
+
## [0.1.0] - 2020-12-16
|
9
|
+
|
10
|
+
### Added
|
11
|
+
|
12
|
+
- YARD-based gem documentation
|
13
|
+
|
14
|
+
### Changed
|
15
|
+
|
16
|
+
- **Breaking**: The Rack::ECG initializer now uses named options, instead of an options hash.
|
17
|
+
|
18
|
+
If you manually initialized an instance, you may need to use the `**` operator to pass these options. (e.g. `Rack::ECG.new(nil, **options)`)
|
19
|
+
|
20
|
+
### Removed
|
21
|
+
|
22
|
+
- **Breaking:** Dropped support for Ruby versions < 2.5.0
|
23
|
+
|
24
|
+
## [0.0.5] - 2017-05-12
|
25
|
+
|
26
|
+
### Added
|
27
|
+
|
28
|
+
- A new `sequel` check (#8), which checks if the Sequel database connection is active.
|
29
|
+
|
30
|
+
## [0.0.4] - 2017-05-04
|
31
|
+
|
32
|
+
### Added
|
33
|
+
|
34
|
+
- A new `active_record` check (#7), which checks if the ActiveRecord connection is active.
|
35
|
+
- A new `redis` check (#7), which checks if the Redis connection is active.
|
36
|
+
|
37
|
+
## [0.0.3] - 2017-02-13
|
38
|
+
|
39
|
+
### Added
|
40
|
+
|
41
|
+
- Accept a `hook` in configuration, which is run when all check results have been gathered (#6)
|
42
|
+
|
43
|
+
### Fixed
|
44
|
+
|
45
|
+
- Resolved an issue with the migration version check and MySQL connections (#3)
|
46
|
+
|
47
|
+
## [0.0.2] - 2015-06-17
|
48
|
+
|
49
|
+
### Added
|
50
|
+
|
51
|
+
- Support running Rack::ECG as a standalone application
|
52
|
+
- Support adding checks via the `CheckRegistry`
|
53
|
+
|
54
|
+
## [0.0.1] - 2015-04-09
|
55
|
+
|
56
|
+
### Added
|
57
|
+
|
58
|
+
- Base middleware to use in Rails or Rack apps
|
59
|
+
- `git_revision` check to return the current git revision
|
60
|
+
- `migration_version` check to return the current ActiveRecord migration version
|
61
|
+
|
62
|
+
[Unreleased]: https://github.com/envato/rack-ecg/compare/v0.1.0...HEAD
|
63
|
+
[0.1.0]: https://github.com/envato/rack-ecg/compare/v0.0.5...v0.1.0
|
64
|
+
[0.0.5]: https://github.com/envato/rack-ecg/compare/v0.0.4...v0.0.5
|
65
|
+
[0.0.4]: https://github.com/envato/rack-ecg/compare/v0.0.3...v0.0.4
|
66
|
+
[0.0.3]: https://github.com/envato/rack-ecg/compare/v0.0.2...v0.0.3
|
67
|
+
[0.0.2]: https://github.com/envato/rack-ecg/compare/v0.0.1...v0.0.2
|
68
|
+
[0.0.1]: https://github.com/envato/rack-ecg/releases/tag/v0.0.1
|
69
|
+
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,21 +1,23 @@
|
|
1
1
|
# Rack::ECG
|
2
2
|
|
3
|
-
|
4
|
-
health check endpoint that tells you vital life signs about your app. All
|
5
|
-
without the boilerplate service checking code you've written 10 times before.
|
3
|
+
[![Gem version](https://img.shields.io/gem/v/rack-ecg)][gem-page] [![Rubydoc](https://img.shields.io/badge/docs-rubydoc-success)][rubydoc]
|
6
4
|
|
7
|
-
|
8
|
-
|
5
|
+
Rack middleware for Ruby web apps, providing a simple and extensible health
|
6
|
+
check endpoint, with minimal configuration.
|
7
|
+
|
8
|
+
> Electrocardiogram (ECG): A recording of the electrical activity of the heart.
|
9
9
|
|
10
10
|
## Features
|
11
|
-
|
12
|
-
|
11
|
+
|
12
|
+
- Start with a single line in your `config.ru` or `config/application.rb` file.
|
13
13
|
- reports git revision status
|
14
14
|
- reports ActiveRecord migration schema version
|
15
15
|
- reports errors if any check can't be executed for whatever reason
|
16
16
|
- JSON output
|
17
17
|
|
18
|
-
## Development Status
|
18
|
+
## Development Status
|
19
|
+
|
20
|
+
[![Build Status](https://github.com/envato/rack-ecg/workflows/build/badge.svg?branch=main)](https://github.com/envato/rack-ecg/actions)
|
19
21
|
|
20
22
|
`Rack::ECG` is extracted from production code in use at
|
21
23
|
[Envato](http://envato.com). However, it is undergoing early development, and
|
@@ -23,23 +25,15 @@ APIs and features are almost certain to be in flux.
|
|
23
25
|
|
24
26
|
## Getting Started
|
25
27
|
|
26
|
-
Add this
|
28
|
+
Add this to your application's `Gemfile`:
|
27
29
|
|
28
30
|
```ruby
|
29
|
-
gem 'rack-ecg'
|
31
|
+
gem 'rack-ecg', '~> 0.0.5`
|
30
32
|
```
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
-
$ bundle
|
35
|
-
|
36
|
-
Or install it yourself as:
|
34
|
+
Then run `bundle install`.
|
37
35
|
|
38
|
-
|
39
|
-
|
40
|
-
### Rails
|
41
|
-
|
42
|
-
In Rails you can add `Rack::ECG` to your `config/application.rb` as a middleware
|
36
|
+
In Rails you can add `Rack::ECG` to your `config/application.rb` as a middleware:
|
43
37
|
|
44
38
|
```ruby
|
45
39
|
# config/application.rb
|
@@ -48,9 +42,7 @@ config.middleware.use Rack::ECG
|
|
48
42
|
# ...
|
49
43
|
```
|
50
44
|
|
51
|
-
|
52
|
-
|
53
|
-
In Rack apps, you can add `Rack::ECG` to your `config.ru`
|
45
|
+
In Rack apps, you can add `Rack::ECG` to your `config.ru`:
|
54
46
|
|
55
47
|
```ruby
|
56
48
|
# config.ru
|
@@ -61,6 +53,8 @@ use Rack::ECG
|
|
61
53
|
run MyRackApp
|
62
54
|
```
|
63
55
|
|
56
|
+
## Usage
|
57
|
+
|
64
58
|
You can now hit your app and get a basic health check response from `Rack::ECG`
|
65
59
|
|
66
60
|
```
|
@@ -185,11 +179,23 @@ a different path by setting the `at` option. e.g.
|
|
185
179
|
use Rack::ECG, at: "/health_check"
|
186
180
|
```
|
187
181
|
|
188
|
-
|
182
|
+
### `hook`
|
183
|
+
|
184
|
+
The `hook` option takes a `Proc` or equivalent, and calls it after the checks
|
185
|
+
have run, but before the response is complete.
|
186
|
+
|
187
|
+
```ruby
|
188
|
+
use Rack::ECG, hook: Proc.new { |success, _checks| puts "Is healthy? #{success}" }
|
189
|
+
```
|
190
|
+
|
191
|
+
- `success`: whether the response will indicate success
|
192
|
+
- `checks`: an array of the check names and values
|
193
|
+
|
194
|
+
More examples are provided in [/examples](https://github.com/envato/rack-ecg/tree/main/examples)
|
189
195
|
|
190
196
|
## Requirements
|
191
|
-
|
192
|
-
|
197
|
+
|
198
|
+
- Ruby >= 2.5
|
193
199
|
- Rack
|
194
200
|
- To use optional `git_revision` check, your deployed code needs to be in a git repo, and
|
195
201
|
`git` command must be accessible on the server
|
@@ -205,24 +211,24 @@ migrations stored in `schema_versions` table
|
|
205
211
|
|
206
212
|
## Maintainers
|
207
213
|
|
208
|
-
- [
|
209
|
-
- [Warren Seen](https://github.com/warrenseen)
|
214
|
+
- [Liam Dawson](https://github.com/liamdawson)
|
210
215
|
|
211
|
-
##
|
216
|
+
## Contributors
|
212
217
|
|
218
|
+
- [Tao Guo](https://github.com/taoza)
|
213
219
|
- [Julian Doherty](https://github.com/madlep)
|
214
220
|
- [Warren Seen](https://github.com/warrenseen)
|
215
221
|
|
216
222
|
## License
|
217
223
|
|
218
224
|
`Rack::ECG` uses MIT license. See
|
219
|
-
[`LICENSE.txt`](https://github.com/envato/rack-ecg/blob/
|
225
|
+
[`LICENSE.txt`](https://github.com/envato/rack-ecg/blob/main/LICENSE.txt) for
|
220
226
|
details.
|
221
227
|
|
222
228
|
## Code of conduct
|
223
229
|
|
224
230
|
We welcome contribution from everyone. Read more about it in
|
225
|
-
[`CODE_OF_CONDUCT.md`](https://github.com/envato/rack-ecg/blob/
|
231
|
+
[`CODE_OF_CONDUCT.md`](https://github.com/envato/rack-ecg/blob/main/CODE_OF_CONDUCT.md)
|
226
232
|
|
227
233
|
## Contributing
|
228
234
|
|
@@ -248,3 +254,5 @@ Encouraging the use and creation of open source software is one of the ways we s
|
|
248
254
|
[envato]: https://envato.com?utm_source=github
|
249
255
|
[oss]: http://opensource.envato.com//?utm_source=github
|
250
256
|
[careers]: http://careers.envato.com/?utm_source=github
|
257
|
+
[gem-page]: https://rubygems.org/gems/rack-ecg
|
258
|
+
[rubydoc]: https://www.rubydoc.info/gems/rack-ecg/
|
data/Rakefile
CHANGED
@@ -1,7 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require "bundler/gem_tasks"
|
2
3
|
|
3
4
|
require 'rspec/core/rake_task'
|
5
|
+
require 'rubocop/rake_task'
|
6
|
+
require 'yard'
|
4
7
|
|
5
8
|
RSpec::Core::RakeTask.new(:spec)
|
9
|
+
RuboCop::RakeTask.new(:rubocop)
|
10
|
+
YARD::Rake::YardocTask.new
|
6
11
|
|
7
|
-
task :
|
12
|
+
task(default: [:rubocop, :spec, :yard])
|
13
|
+
|
14
|
+
task(:watch_docs) do
|
15
|
+
sh "yard server --reload"
|
16
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "rack-ecg"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require "irb"
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/examples/basic.ru
CHANGED
data/examples/checks.ru
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'rack/ecg'
|
2
3
|
|
3
|
-
use
|
4
|
+
use(Rack::ECG, checks: [:git_revision, :migration_version])
|
4
5
|
|
5
|
-
run
|
6
|
+
run(-> (_env) { [200, {}, ["Hello, World"]] })
|
data/examples/hook.ru
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rack/ecg'
|
4
|
+
|
5
|
+
log_check_results = proc do |success, checks|
|
6
|
+
next if success
|
7
|
+
|
8
|
+
checks.each do |check_name, check_status|
|
9
|
+
next unless check_status[:status] == 'error'
|
10
|
+
|
11
|
+
puts "Check #{check_name} failed: #{check_status[:value]}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
use(Rack::ECG, checks: [:git_revision, :migration_version], hook: log_check_results)
|
16
|
+
|
17
|
+
run(->(_env) { [200, {}, ['Hello, World']] })
|
data/examples/mounted_path.ru
CHANGED
data/examples/parameters.ru
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'rack/ecg'
|
2
3
|
require 'sequel'
|
3
4
|
require 'sqlite3'
|
4
5
|
|
5
|
-
use
|
6
|
+
use(Rack::ECG, checks: [
|
6
7
|
:http,
|
7
|
-
[:sequel, {connection: 'sqlite://events.db', name: 'events'}],
|
8
|
-
[:sequel, {connection: 'sqlite://projections.db', name: 'projections'}]
|
9
|
-
]
|
8
|
+
[:sequel, { connection: 'sqlite://events.db', name: 'events' }],
|
9
|
+
[:sequel, { connection: 'sqlite://projections.db', name: 'projections' }],
|
10
|
+
])
|
10
11
|
|
11
|
-
run
|
12
|
+
run(-> (_env) { [200, {}, ["Hello, World"]] })
|
data/examples/stand_alone.ru
CHANGED
data/lib/rack-ecg.rb
CHANGED
data/lib/rack/ecg.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require "rack/ecg/version"
|
2
3
|
require "json"
|
3
4
|
require "open3"
|
@@ -5,34 +6,47 @@ require "rack/ecg/check_factory"
|
|
5
6
|
|
6
7
|
module Rack
|
7
8
|
class ECG
|
9
|
+
# Default mount path.
|
8
10
|
DEFAULT_MOUNT_AT = "/_ecg"
|
9
|
-
|
10
|
-
|
11
|
-
|
11
|
+
# Checks enabled by default.
|
12
|
+
DEFAULT_CHECKS = [:http]
|
13
|
+
|
14
|
+
# Constructs an instance of ECG Rack middleware with the specified
|
15
|
+
# options.
|
16
|
+
#
|
17
|
+
# @param app [Object,nil] Underlying Rack application to receive unmatched
|
18
|
+
# requests. If unset, any unmatched requests will return a 404.
|
19
|
+
# @param checks [Array<Symbol, Array<Symbol, Object>>] Sets and
|
20
|
+
# configures the checks run by this instance.
|
21
|
+
# @param at [String, nil] Path which this ECG instance handles.
|
22
|
+
# @param hook [#call, nil] Callable which receives the success status and
|
23
|
+
# check results
|
24
|
+
def initialize(app = nil, checks: DEFAULT_CHECKS, at: DEFAULT_MOUNT_AT, hook: nil)
|
12
25
|
@app = app
|
13
26
|
|
14
|
-
check_configuration =
|
27
|
+
check_configuration = checks || []
|
15
28
|
@check_factory = CheckFactory.new(check_configuration, DEFAULT_CHECKS)
|
16
|
-
@
|
29
|
+
@mount_at = at || DEFAULT_MOUNT_AT
|
17
30
|
|
18
|
-
@
|
31
|
+
@result_hook = hook
|
19
32
|
end
|
20
33
|
|
34
|
+
# Rack compatible call method. Not intended for direct usage.
|
21
35
|
def call(env)
|
22
|
-
if env["PATH_INFO"] == @
|
36
|
+
if env["PATH_INFO"] == @mount_at
|
23
37
|
check_results = @check_factory.build_all.inject({}) do |results, check|
|
24
|
-
results.merge(check.result.
|
38
|
+
results.merge(check.result.as_json)
|
25
39
|
end
|
26
40
|
|
27
41
|
success = check_results.none? { |check| check[1][:status] == Check::Status::ERROR }
|
28
42
|
|
29
43
|
response_status = success ? 200 : 500
|
30
44
|
|
31
|
-
@
|
45
|
+
@result_hook&.call(success, check_results)
|
32
46
|
|
33
47
|
response_headers = {
|
34
|
-
"X-Rack-ECG-Version"
|
35
|
-
"Content-Type"
|
48
|
+
"X-Rack-ECG-Version" => Rack::ECG::VERSION,
|
49
|
+
"Content-Type" => "application/json",
|
36
50
|
}
|
37
51
|
|
38
52
|
response_body = JSON.pretty_generate(check_results)
|
@@ -41,7 +55,7 @@ module Rack
|
|
41
55
|
elsif @app
|
42
56
|
@app.call(env)
|
43
57
|
else
|
44
|
-
[404, {},[]]
|
58
|
+
[404, {}, []]
|
45
59
|
end
|
46
60
|
end
|
47
61
|
end
|