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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 7bd8eb96d04ad56746e1b5a29c1bf994706a4fe1
4
- data.tar.gz: c64c43e74caa9020f24fab71f72a328cb3a194c6
2
+ SHA256:
3
+ metadata.gz: daea3d8ff855b734db9fc65f7ed6859114f1a89e095d06f7c26f907d011b65e9
4
+ data.tar.gz: b311a75d0c8555c21e9db5633bbbf3dc7304fd8dc42497dfeb9957edeb1f9233
5
5
  SHA512:
6
- metadata.gz: fc8fc08610d5e269889dc0d5f6717be7b468298f7469f2fa01754be67988aa242bbd0dd5b78ae9f5003d4c096800c2444a6e1d9eadd325a05d9fe71450f9af75
7
- data.tar.gz: e173e7a8cf827fe3dd3d747afd8cb9d2440e64ec67d44fada6aaf9bf330e08953f78b69eb945fb4d30dba2fffedf98ad675d621423f0ae89f0f98ac7463b6d4e
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
@@ -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'
@@ -0,0 +1 @@
1
+ 2.5.8
@@ -0,0 +1 @@
1
+ --files lib/**/*.rb
@@ -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
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  source 'https://rubygems.org'
2
3
 
3
4
  # Specify your gem's dependencies in rack-ecg.gemspec
data/README.md CHANGED
@@ -1,21 +1,23 @@
1
1
  # Rack::ECG
2
2
 
3
- An easy to configure Rack middleware for Ruby web apps to provide a simple
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
- (it's ECG as in electrocardiogram - as in the machine that monitors how your
8
- heart works)
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
- - simple 1 line to drop into your `config.ru` or `config/application.rb` file to
12
- set up
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 [![travis ci build](https://api.travis-ci.org/envato/rack-ecg.svg)](https://travis-ci.org/envato/rack-ecg)
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 line to your application's Gemfile:
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
- And then execute:
33
-
34
- $ bundle
35
-
36
- Or install it yourself as:
34
+ Then run `bundle install`.
37
35
 
38
- $ gem install rack-ecg
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
- ### Rack
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
- More examples are provided in [/examples](https://github.com/envato/rack-ecg/tree/master/examples)
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
- - Ruby >= 1.9.3 (this may be increased to Ruby >= 2.0 if it makes sense to use
192
- Ruby 2.0 features)
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
- - [Tao Guo](https://github.com/taoza)
209
- - [Warren Seen](https://github.com/warrenseen)
214
+ - [Liam Dawson](https://github.com/liamdawson)
210
215
 
211
- ## Authors
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/master/LICENSE.txt) for
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/master/CODE_OF_CONDUCT.md)
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 :default => :spec
12
+ task(default: [:rubocop, :spec, :yard])
13
+
14
+ task(:watch_docs) do
15
+ sh "yard server --reload"
16
+ end
@@ -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__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -1,5 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  require 'rack/ecg'
2
3
 
3
- use Rack::ECG
4
+ use(Rack::ECG)
4
5
 
5
- run -> (env) { [200, {}, ["Hello, World"]] }
6
+ run(-> (_env) { [200, {}, ["Hello, World"]] })
@@ -1,5 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  require 'rack/ecg'
2
3
 
3
- use Rack::ECG, checks: [:git_revision, :migration_version]
4
+ use(Rack::ECG, checks: [:git_revision, :migration_version])
4
5
 
5
- run -> (env) { [200, {}, ["Hello, World"]] }
6
+ run(-> (_env) { [200, {}, ["Hello, World"]] })
@@ -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']] })
@@ -1,5 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  require 'rack/ecg'
2
3
 
3
- use Rack::ECG, at: "/health_check"
4
+ use(Rack::ECG, at: "/health_check")
4
5
 
5
- run -> (env) { [200, {}, ["Hello, World"]] }
6
+ run(-> (_env) { [200, {}, ["Hello, World"]] })
@@ -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 Rack::ECG, checks: [
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 -> (env) { [200, {}, ["Hello, World"]] }
12
+ run(-> (_env) { [200, {}, ["Hello, World"]] })
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'rack/ecg'
2
3
 
3
- run Rack::ECG.new
4
+ run(Rack::ECG.new)
@@ -1 +1,2 @@
1
+ # frozen_string_literal: true
1
2
  require 'rack/ecg'
@@ -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
- DEFAULT_CHECKS = [ :http ]
10
-
11
- def initialize(app=nil, options={})
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 = options.delete(:checks) || []
27
+ check_configuration = checks || []
15
28
  @check_factory = CheckFactory.new(check_configuration, DEFAULT_CHECKS)
16
- @at = options.delete(:at) || DEFAULT_MOUNT_AT
29
+ @mount_at = at || DEFAULT_MOUNT_AT
17
30
 
18
- @hook = options.delete(:hook)
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"] == @at
36
+ if env["PATH_INFO"] == @mount_at
23
37
  check_results = @check_factory.build_all.inject({}) do |results, check|
24
- results.merge(check.result.to_json)
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
- @hook.call(success, check_results) if @hook
45
+ @result_hook&.call(success, check_results)
32
46
 
33
47
  response_headers = {
34
- "X-Rack-ECG-Version" => Rack::ECG::VERSION,
35
- "Content-Type" => "application/json"
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