rack-ping 0.0.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.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/Guardfile +5 -0
- data/README.md +62 -0
- data/Rakefile +1 -0
- data/examples/config.ru +10 -0
- data/lib/rack/ping.rb +80 -0
- data/lib/rack/version.rb +5 -0
- data/rack-ping.gemspec +24 -0
- data/spec/rack/ping_spec.rb +115 -0
- data/spec/spec_helper.rb +8 -0
- metadata +89 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# Rack::Ping
|
2
|
+
A Rack middleware that should indicate the health of your service.
|
3
|
+
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
Here is a simple example (see `examples`)
|
7
|
+
|
8
|
+
map '/ping' do
|
9
|
+
use Rack::Ping do |ping|
|
10
|
+
ping.check_url "http://localhost:9292/"
|
11
|
+
ping.ok_regex /goodbye/
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
run lambda{|env| [200, {'Content-Type' => 'text/html'}, ["hello"]]}
|
16
|
+
|
17
|
+
## Options
|
18
|
+
|
19
|
+
When building/mounting your rack, use the `ping` configuration variable,
|
20
|
+
specify:
|
21
|
+
|
22
|
+
* `version` is an accessor for your application version. `App::VERSION`
|
23
|
+
would be a good idea.
|
24
|
+
* `check_url` is a url that `ping` will fetch and run `ok_regex` on. If
|
25
|
+
the match is ok, we're good. You must specify `check_url` and
|
26
|
+
`ok_regex` togather. `timeout_secs` is the amount of seconds we wait
|
27
|
+
until spitting out an error.
|
28
|
+
* `check` will accept a block to run. This is a good alternative to
|
29
|
+
`check_url`: run a couple of sanity checks to indicate you're good.
|
30
|
+
* `ok_code`, `error_code`, `ok_text`, `error_text` are configuration for
|
31
|
+
you to use, to configure against LB quirks. The default config should
|
32
|
+
work against ELBs (Amazon elastic LB).
|
33
|
+
|
34
|
+
## Headers
|
35
|
+
|
36
|
+
`ping` will output intelligent headers. First `x-ping-error` will try to
|
37
|
+
explain why ping failed.
|
38
|
+
|
39
|
+
Next, `x-app-version` will expose the current deployed version of your
|
40
|
+
app. This is good in order to validate nothing crawled up to production,
|
41
|
+
as well as validation for post-production deployment.
|
42
|
+
|
43
|
+
`ping` will bust any browser/client cache for you.
|
44
|
+
|
45
|
+
|
46
|
+
## Contributing
|
47
|
+
|
48
|
+
Guard is set up for your ease of development. Here's how to go from 0 to
|
49
|
+
ready.
|
50
|
+
|
51
|
+
$ git clone https://github.com/jondot/rack-ping
|
52
|
+
$ cd rack-ping
|
53
|
+
$ bundle install
|
54
|
+
$ guard
|
55
|
+
|
56
|
+
Fork, implement, add tests, pull request, get my everlasting thanks and a respectable place here :).
|
57
|
+
|
58
|
+
|
59
|
+
## Copyright
|
60
|
+
|
61
|
+
Copyright (c) 2011 [Dotan Nahum](http://gplus.to/dotan) [@jondot](http://twitter.com/jondot). See MIT-LICENSE for further details.
|
62
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/examples/config.ru
ADDED
data/lib/rack/ping.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
class Ping
|
5
|
+
attr_reader :config
|
6
|
+
|
7
|
+
def initialize(app)
|
8
|
+
@config = {
|
9
|
+
:version => '0',
|
10
|
+
:check_url => nil,
|
11
|
+
:ok_regex => nil,
|
12
|
+
:ok_text => 'ok',
|
13
|
+
:ok_code => 200,
|
14
|
+
:timeout_secs => 5,
|
15
|
+
:error_text => 'error',
|
16
|
+
:error_code => 500
|
17
|
+
}
|
18
|
+
|
19
|
+
yield self if block_given?
|
20
|
+
end
|
21
|
+
|
22
|
+
%w[version check_url ok_regex ok_text ok_code timeout_secs error_text error_code].each do |meth|
|
23
|
+
define_method(meth) { |value| @config[meth.to_sym] = value }
|
24
|
+
end
|
25
|
+
|
26
|
+
def check(&block)
|
27
|
+
@check_block = block
|
28
|
+
end
|
29
|
+
|
30
|
+
def call(env)
|
31
|
+
if @check_block
|
32
|
+
begin
|
33
|
+
return @check_block.call() ? ok : error("logic")
|
34
|
+
rescue
|
35
|
+
return error("logic: #{$!}")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
if @config[:ok_regex] && @config[:check_url]
|
40
|
+
begin
|
41
|
+
timeout(@config[:timeout_secs]) do
|
42
|
+
text = open(@config[:check_url]).read
|
43
|
+
return error("regex") unless text =~ @config[:ok_regex]
|
44
|
+
end
|
45
|
+
rescue Timeout::Error
|
46
|
+
return error("timeout")
|
47
|
+
rescue
|
48
|
+
return error("url: #{$!}")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
return ok
|
53
|
+
end
|
54
|
+
|
55
|
+
def error(reason)
|
56
|
+
[ @config[:error_code],
|
57
|
+
NO_CACHE.merge({
|
58
|
+
'Content-Type' => 'text/html',
|
59
|
+
'x-app-version' => @config[:version],
|
60
|
+
'x-ping-error' => reason
|
61
|
+
}),
|
62
|
+
[@config[:error_text]] ]
|
63
|
+
end
|
64
|
+
|
65
|
+
def ok
|
66
|
+
[ @config[:ok_code],
|
67
|
+
NO_CACHE.merge({
|
68
|
+
'Content-Type' => 'text/html',
|
69
|
+
'x-app-version' => @config[:version]
|
70
|
+
}),
|
71
|
+
[@config[:ok_text]] ]
|
72
|
+
end
|
73
|
+
private
|
74
|
+
NO_CACHE = {
|
75
|
+
"Cache-Control" => "no-cache, no-store, max-age=0, must-revalidate",
|
76
|
+
"Pragma" => "no-cache",
|
77
|
+
"Expires" => "Tue, 8 Sep 1981 08:42:00 UTC"
|
78
|
+
}
|
79
|
+
end
|
80
|
+
end
|
data/lib/rack/version.rb
ADDED
data/rack-ping.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "rack/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "rack-ping"
|
7
|
+
s.version = Rack::Ping::VERSION
|
8
|
+
s.authors = ["Dotan Nahum"]
|
9
|
+
s.email = ["jondotan@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Health checking Rack middleware}
|
12
|
+
s.description = %q{Health checking Rack middleware}
|
13
|
+
|
14
|
+
s.rubyforge_project = "rack-ping"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_development_dependency 'guard-minitest'
|
22
|
+
s.add_development_dependency 'rack-test'
|
23
|
+
s.add_development_dependency 'webmock'
|
24
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rack/ping'
|
3
|
+
|
4
|
+
|
5
|
+
def app
|
6
|
+
lambda{|env| [200, {'Content-Type' => 'text/html'}, ["hello"]]}
|
7
|
+
end
|
8
|
+
|
9
|
+
def must_bust_cache(h)
|
10
|
+
h["Cache-Control"].must_equal "no-cache, no-store, max-age=0, must-revalidate"
|
11
|
+
h["Pragma"].must_equal "no-cache"
|
12
|
+
h["Expires"].must_equal "Tue, 8 Sep 1981 08:42:00 UTC"
|
13
|
+
end
|
14
|
+
|
15
|
+
describe Rack::Ping do
|
16
|
+
it "should bust cache" do
|
17
|
+
s, h, b = Rack::Ping.new(app).call({})
|
18
|
+
must_bust_cache(h)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should have sane defaults" do
|
22
|
+
# when ok
|
23
|
+
s, h, b = Rack::Ping.new(app).call({})
|
24
|
+
|
25
|
+
s.must_equal 200
|
26
|
+
h['x-app-version'].must_equal '0'
|
27
|
+
b[0].must_equal 'ok'
|
28
|
+
must_bust_cache(h)
|
29
|
+
|
30
|
+
# when error
|
31
|
+
s, h, b = Rack::Ping.new(app) do |ping|
|
32
|
+
ping.check { false }
|
33
|
+
end.call({})
|
34
|
+
|
35
|
+
s.must_equal 500
|
36
|
+
b[0].must_equal 'error'
|
37
|
+
must_bust_cache(h)
|
38
|
+
end
|
39
|
+
|
40
|
+
module MyApp
|
41
|
+
VERSION = '1.0.0'
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should pick up application version" do
|
45
|
+
s, h, b = Rack::Ping.new(app) do |ping|
|
46
|
+
ping.version MyApp::VERSION
|
47
|
+
end.call({})
|
48
|
+
h['x-app-version'].must_equal '1.0.0'
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
it "should run check code when available" do
|
53
|
+
s, h, b = Rack::Ping.new(app) do |ping|
|
54
|
+
ping.check do
|
55
|
+
false
|
56
|
+
end
|
57
|
+
end.call({})
|
58
|
+
|
59
|
+
s.must_equal 500
|
60
|
+
b[0].must_equal 'error'
|
61
|
+
h['x-ping-error'].must_equal "logic"
|
62
|
+
must_bust_cache(h)
|
63
|
+
|
64
|
+
|
65
|
+
s, h, b = Rack::Ping.new(app) do |ping|
|
66
|
+
ping.check do
|
67
|
+
raise "error"
|
68
|
+
end
|
69
|
+
end.call({})
|
70
|
+
|
71
|
+
s.must_equal 500
|
72
|
+
b[0].must_equal 'error'
|
73
|
+
h['x-ping-error'].must_equal "logic: error"
|
74
|
+
must_bust_cache(h)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should fetch url content and run regex on it when available" do
|
78
|
+
stub_request(:any, "http://google.com").to_return(:body => "google is awesome")
|
79
|
+
s, h, b = Rack::Ping.new(app) do |ping|
|
80
|
+
ping.check_url "http://google.com"
|
81
|
+
ping.ok_regex /awesome/
|
82
|
+
ping.ok_text "groovy"
|
83
|
+
end.call({})
|
84
|
+
|
85
|
+
s.must_equal 200
|
86
|
+
b[0].must_equal 'groovy'
|
87
|
+
must_bust_cache(h)
|
88
|
+
|
89
|
+
|
90
|
+
s, h, b = Rack::Ping.new(app) do |ping|
|
91
|
+
ping.check_url "http://google.com"
|
92
|
+
ping.ok_regex /bing/
|
93
|
+
ping.ok_text "groovy"
|
94
|
+
end.call({})
|
95
|
+
|
96
|
+
s.must_equal 500
|
97
|
+
b[0].must_equal 'error'
|
98
|
+
must_bust_cache(h)
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should timeout when resource at url is unavailable" do
|
102
|
+
stub_request(:any, "http://google.com").to_timeout
|
103
|
+
s, h, b = Rack::Ping.new(app) do |ping|
|
104
|
+
ping.check_url "http://google.com"
|
105
|
+
ping.ok_regex /awesome/
|
106
|
+
ping.error_text "shitty"
|
107
|
+
end.call({})
|
108
|
+
|
109
|
+
s.must_equal 500
|
110
|
+
b[0].must_equal 'shitty'
|
111
|
+
h['x-ping-error'].must_equal "timeout"
|
112
|
+
must_bust_cache(h)
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rack-ping
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Dotan Nahum
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-01-19 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: guard-minitest
|
16
|
+
requirement: &89268900 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *89268900
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rack-test
|
27
|
+
requirement: &89268680 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *89268680
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: webmock
|
38
|
+
requirement: &89268450 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *89268450
|
47
|
+
description: Health checking Rack middleware
|
48
|
+
email:
|
49
|
+
- jondotan@gmail.com
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- .gitignore
|
55
|
+
- Gemfile
|
56
|
+
- Guardfile
|
57
|
+
- README.md
|
58
|
+
- Rakefile
|
59
|
+
- examples/config.ru
|
60
|
+
- lib/rack/ping.rb
|
61
|
+
- lib/rack/version.rb
|
62
|
+
- rack-ping.gemspec
|
63
|
+
- spec/rack/ping_spec.rb
|
64
|
+
- spec/spec_helper.rb
|
65
|
+
homepage: ''
|
66
|
+
licenses: []
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options: []
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
requirements: []
|
84
|
+
rubyforge_project: rack-ping
|
85
|
+
rubygems_version: 1.8.10
|
86
|
+
signing_key:
|
87
|
+
specification_version: 3
|
88
|
+
summary: Health checking Rack middleware
|
89
|
+
test_files: []
|