healthy 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +37 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +46 -0
- data/Rakefile +48 -0
- data/VERSION +1 -0
- data/bin/healthy-web +15 -0
- data/healthy.gemspec +98 -0
- data/lib/healthy.rb +12 -0
- data/lib/healthy/base.rb +18 -0
- data/lib/healthy/diagnostic.rb +73 -0
- data/lib/healthy/disk_space.rb +11 -0
- data/lib/healthy/env_check.rb +11 -0
- data/lib/healthy/gem_list.rb +17 -0
- data/lib/healthy/public/bg_button_a.gif +0 -0
- data/lib/healthy/public/bg_button_span.gif +0 -0
- data/lib/healthy/public/screen.css +155 -0
- data/lib/healthy/revision_deployed.rb +13 -0
- data/lib/healthy/router.rb +27 -0
- data/lib/healthy/server.rb +40 -0
- data/lib/healthy/server_identity.rb +35 -0
- data/lib/healthy/views/show.erb +90 -0
- data/spec/base_spec.rb +36 -0
- data/spec/diagnostic_spec.rb +38 -0
- data/spec/router_spec.rb +38 -0
- data/spec/server_identity_spec.rb +53 -0
- data/spec/spec_helper.rb +12 -0
- metadata +219 -0
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
gem 'sinatra'
|
9
|
+
|
10
|
+
group :development, :test do
|
11
|
+
gem "rspec", "~> 2.3.0"
|
12
|
+
gem "bundler", "~> 1.0.0"
|
13
|
+
gem "jeweler", "~> 1.5.2"
|
14
|
+
gem "rcov", ">= 0"
|
15
|
+
gem 'mocha'
|
16
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
diff-lcs (1.1.2)
|
5
|
+
git (1.2.5)
|
6
|
+
jeweler (1.5.2)
|
7
|
+
bundler (~> 1.0.0)
|
8
|
+
git (>= 1.2.5)
|
9
|
+
rake
|
10
|
+
mocha (0.9.9)
|
11
|
+
rake
|
12
|
+
rack (1.2.1)
|
13
|
+
rake (0.8.7)
|
14
|
+
rcov (0.9.9)
|
15
|
+
rspec (2.3.0)
|
16
|
+
rspec-core (~> 2.3.0)
|
17
|
+
rspec-expectations (~> 2.3.0)
|
18
|
+
rspec-mocks (~> 2.3.0)
|
19
|
+
rspec-core (2.3.1)
|
20
|
+
rspec-expectations (2.3.0)
|
21
|
+
diff-lcs (~> 1.1.2)
|
22
|
+
rspec-mocks (2.3.0)
|
23
|
+
sinatra (1.1.2)
|
24
|
+
rack (~> 1.1)
|
25
|
+
tilt (~> 1.2)
|
26
|
+
tilt (1.2.2)
|
27
|
+
|
28
|
+
PLATFORMS
|
29
|
+
ruby
|
30
|
+
|
31
|
+
DEPENDENCIES
|
32
|
+
bundler (~> 1.0.0)
|
33
|
+
jeweler (~> 1.5.2)
|
34
|
+
mocha
|
35
|
+
rcov
|
36
|
+
rspec (~> 2.3.0)
|
37
|
+
sinatra
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Matthew Deiters
|
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.rdoc
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
= healthy
|
2
|
+
|
3
|
+
Coming Soon
|
4
|
+
|
5
|
+
== Mounting the application in rails 2.3.*
|
6
|
+
|
7
|
+
Create a new folder in app called metal. Add the file healthy_web.rb with:
|
8
|
+
|
9
|
+
require 'healthy'
|
10
|
+
class HealthyWeb
|
11
|
+
@app = Rack::Builder.new {
|
12
|
+
map "/status" do
|
13
|
+
run Healthy::Server.new
|
14
|
+
end
|
15
|
+
}.to_app
|
16
|
+
|
17
|
+
def self.call(env)
|
18
|
+
@app.call(env)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
This will route all requests to /status to the healthy rack app
|
23
|
+
|
24
|
+
== Adding custom diagnostics
|
25
|
+
|
26
|
+
Add each diagnostics check to the to
|
27
|
+
|
28
|
+
config.to_prepare do
|
29
|
+
Healthy::Diagnostic.monitor(YourSuperDuperDiagnosticsCheck)
|
30
|
+
end
|
31
|
+
|
32
|
+
== Contributing to healthy
|
33
|
+
|
34
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
35
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
36
|
+
* Fork the project
|
37
|
+
* Start a feature/bugfix branch
|
38
|
+
* Commit and push until you are happy with your contribution
|
39
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
40
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
41
|
+
|
42
|
+
== Copyright
|
43
|
+
|
44
|
+
Copyright (c) 2011 Matthew Deiters. See LICENSE.txt for
|
45
|
+
further details.
|
46
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "healthy"
|
16
|
+
gem.homepage = "http://github.com/mdeiters/healthy"
|
17
|
+
gem.license = "MIT"
|
18
|
+
gem.summary = %Q{A rack app for monitoring application health that can be attached to your rails application}
|
19
|
+
gem.description = %Q{A rack app for monitoring application health that can be attached to your rails application}
|
20
|
+
gem.email = "mdeiters@gmail.com"
|
21
|
+
gem.authors = ["Matthew Deiters"]
|
22
|
+
gem.add_runtime_dependency 'sinatra'
|
23
|
+
gem.add_development_dependency 'rspec', '> 1.2.3'
|
24
|
+
end
|
25
|
+
Jeweler::RubygemsDotOrgTasks.new
|
26
|
+
|
27
|
+
require 'rspec/core'
|
28
|
+
require 'rspec/core/rake_task'
|
29
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
30
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
31
|
+
end
|
32
|
+
|
33
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
34
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
35
|
+
spec.rcov = true
|
36
|
+
end
|
37
|
+
|
38
|
+
task :default => :spec
|
39
|
+
|
40
|
+
require 'rake/rdoctask'
|
41
|
+
Rake::RDocTask.new do |rdoc|
|
42
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
43
|
+
|
44
|
+
rdoc.rdoc_dir = 'rdoc'
|
45
|
+
rdoc.title = "healthy #{version}"
|
46
|
+
rdoc.rdoc_files.include('README*')
|
47
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
48
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.1
|
data/bin/healthy-web
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
4
|
+
begin
|
5
|
+
require 'vegas'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'vegas'
|
9
|
+
end
|
10
|
+
require 'activesupport'
|
11
|
+
require 'healthy'
|
12
|
+
|
13
|
+
Vegas::Runner.new(Healthy::Server, 'healthy-web', {}) do |runner, opts, app|
|
14
|
+
|
15
|
+
end
|
data/healthy.gemspec
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{healthy}
|
8
|
+
s.version = "0.1.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Matthew Deiters"]
|
12
|
+
s.date = %q{2011-09-01}
|
13
|
+
s.default_executable = %q{healthy-web}
|
14
|
+
s.description = %q{A rack app for monitoring application health that can be attached to your rails application}
|
15
|
+
s.email = %q{mdeiters@gmail.com}
|
16
|
+
s.executables = ["healthy-web"]
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE.txt",
|
19
|
+
"README.rdoc"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
".document",
|
23
|
+
".rspec",
|
24
|
+
"Gemfile",
|
25
|
+
"Gemfile.lock",
|
26
|
+
"LICENSE.txt",
|
27
|
+
"README.rdoc",
|
28
|
+
"Rakefile",
|
29
|
+
"VERSION",
|
30
|
+
"bin/healthy-web",
|
31
|
+
"healthy.gemspec",
|
32
|
+
"lib/healthy.rb",
|
33
|
+
"lib/healthy/base.rb",
|
34
|
+
"lib/healthy/diagnostic.rb",
|
35
|
+
"lib/healthy/disk_space.rb",
|
36
|
+
"lib/healthy/env_check.rb",
|
37
|
+
"lib/healthy/gem_list.rb",
|
38
|
+
"lib/healthy/public/bg_button_a.gif",
|
39
|
+
"lib/healthy/public/bg_button_span.gif",
|
40
|
+
"lib/healthy/public/screen.css",
|
41
|
+
"lib/healthy/revision_deployed.rb",
|
42
|
+
"lib/healthy/router.rb",
|
43
|
+
"lib/healthy/server.rb",
|
44
|
+
"lib/healthy/server_identity.rb",
|
45
|
+
"lib/healthy/views/show.erb",
|
46
|
+
"spec/base_spec.rb",
|
47
|
+
"spec/diagnostic_spec.rb",
|
48
|
+
"spec/router_spec.rb",
|
49
|
+
"spec/server_identity_spec.rb",
|
50
|
+
"spec/spec_helper.rb"
|
51
|
+
]
|
52
|
+
s.homepage = %q{http://github.com/mdeiters/healthy}
|
53
|
+
s.licenses = ["MIT"]
|
54
|
+
s.require_paths = ["lib"]
|
55
|
+
s.rubygems_version = %q{1.6.2}
|
56
|
+
s.summary = %q{A rack app for monitoring application health that can be attached to your rails application}
|
57
|
+
s.test_files = [
|
58
|
+
"spec/base_spec.rb",
|
59
|
+
"spec/diagnostic_spec.rb",
|
60
|
+
"spec/router_spec.rb",
|
61
|
+
"spec/server_identity_spec.rb",
|
62
|
+
"spec/spec_helper.rb"
|
63
|
+
]
|
64
|
+
|
65
|
+
if s.respond_to? :specification_version then
|
66
|
+
s.specification_version = 3
|
67
|
+
|
68
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
69
|
+
s.add_runtime_dependency(%q<sinatra>, [">= 0"])
|
70
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
|
71
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
72
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
73
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
74
|
+
s.add_development_dependency(%q<mocha>, [">= 0"])
|
75
|
+
s.add_runtime_dependency(%q<sinatra>, [">= 0"])
|
76
|
+
s.add_development_dependency(%q<rspec>, ["> 1.2.3"])
|
77
|
+
else
|
78
|
+
s.add_dependency(%q<sinatra>, [">= 0"])
|
79
|
+
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
80
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
81
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
82
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
83
|
+
s.add_dependency(%q<mocha>, [">= 0"])
|
84
|
+
s.add_dependency(%q<sinatra>, [">= 0"])
|
85
|
+
s.add_dependency(%q<rspec>, ["> 1.2.3"])
|
86
|
+
end
|
87
|
+
else
|
88
|
+
s.add_dependency(%q<sinatra>, [">= 0"])
|
89
|
+
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
90
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
91
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
92
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
93
|
+
s.add_dependency(%q<mocha>, [">= 0"])
|
94
|
+
s.add_dependency(%q<sinatra>, [">= 0"])
|
95
|
+
s.add_dependency(%q<rspec>, ["> 1.2.3"])
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
data/lib/healthy.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
DIAGNOSTIC_LOGGER = defined?(Rails) ? Rails.logger : require('logger') && Logger.new($stdout)
|
2
|
+
|
3
|
+
require 'healthy/diagnostic'
|
4
|
+
require 'healthy/base'
|
5
|
+
require 'sinatra'
|
6
|
+
require 'healthy/server'
|
7
|
+
require 'healthy/server_identity'
|
8
|
+
require 'healthy/router'
|
9
|
+
require('healthy/gem_list') && Healthy::Diagnostic.monitor(Healthy::GemList)
|
10
|
+
require('healthy/env_check') && Healthy::Diagnostic.monitor(Healthy::EnvCheck)
|
11
|
+
require('healthy/disk_space') && Healthy::Diagnostic.monitor(Healthy::DiskSpace)
|
12
|
+
require('healthy/revision_deployed') && Healthy::Diagnostic.monitor(Healthy::RevisionDeployed)
|
data/lib/healthy/base.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Healthy
|
2
|
+
class Diagnostic
|
3
|
+
# all checks are expected to implement methods passed?, warning?, info
|
4
|
+
# all tools are expected to implement methods info
|
5
|
+
module Base
|
6
|
+
def status
|
7
|
+
raise "status is not supported on a tool" unless respond_to?(:passed?)
|
8
|
+
return :warn if warning? && passed?
|
9
|
+
return :fail unless passed?
|
10
|
+
return :pass
|
11
|
+
end
|
12
|
+
|
13
|
+
def name
|
14
|
+
self.class.name
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Healthy
|
2
|
+
class Diagnostic
|
3
|
+
class << self
|
4
|
+
def info_for(normalized_name)
|
5
|
+
route = Router.routes[normalized_name]
|
6
|
+
if ServerIdentity.matches?(route[:servers])
|
7
|
+
route[:klass].new.info
|
8
|
+
else
|
9
|
+
`curl -H 'Host: #{Diagnostic.site_host}' http://#{route[:servers].first}/status/#{normalized_name}`
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def status
|
14
|
+
status = :pass
|
15
|
+
checks.each do |check|
|
16
|
+
case check.status
|
17
|
+
when :warn
|
18
|
+
status = warn
|
19
|
+
when :fail
|
20
|
+
return :fail
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
status
|
25
|
+
end
|
26
|
+
|
27
|
+
def all_good?
|
28
|
+
status == :pass
|
29
|
+
end
|
30
|
+
|
31
|
+
def site_host
|
32
|
+
@@site_host
|
33
|
+
end
|
34
|
+
|
35
|
+
def site_host=(value)
|
36
|
+
@@site_host=value
|
37
|
+
end
|
38
|
+
|
39
|
+
def monitor(diagnostic)
|
40
|
+
@diagnostics ||= []
|
41
|
+
exsisting = @diagnostics.detect{|exsisting| exsisting.name == diagnostic.name }
|
42
|
+
@diagnostics.delete(exsisting) if exsisting
|
43
|
+
@diagnostics << diagnostic
|
44
|
+
Router.add_route(diagnostic)
|
45
|
+
end
|
46
|
+
|
47
|
+
def diagnostics
|
48
|
+
@diagnostics.uniq.collect(&:new)
|
49
|
+
end
|
50
|
+
|
51
|
+
def flush_diagnostics!
|
52
|
+
@diagnostics.uniq.clear
|
53
|
+
Router.routes = nil
|
54
|
+
end
|
55
|
+
|
56
|
+
def checks
|
57
|
+
diagnostics.select{|diagnostic| diagnostic.respond_to?(:passed?) }.sort{|x,y| extract_name(x) <=> extract_name(y)}
|
58
|
+
end
|
59
|
+
|
60
|
+
def tools
|
61
|
+
diagnostics.select{|diagnostic| !diagnostic.respond_to?(:passed?) }.sort{|x,y| extract_name(x) <=> extract_name(y)}
|
62
|
+
end
|
63
|
+
|
64
|
+
def extract_name(obj)
|
65
|
+
if obj.respond_to?(:name)
|
66
|
+
obj.name
|
67
|
+
else
|
68
|
+
obj.class.name
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Healthy
|
2
|
+
class GemList
|
3
|
+
def name
|
4
|
+
'Installed Ruby And Gems'
|
5
|
+
end
|
6
|
+
|
7
|
+
def info
|
8
|
+
[
|
9
|
+
"RUBY_VERSION=#{RUBY_VERSION}",
|
10
|
+
"RUBY_PATCHLEVEL=#{RUBY_PATCHLEVEL}",
|
11
|
+
"RUBY_PLATFORM=#{RUBY_PLATFORM}",
|
12
|
+
"RUBY_RELEASE_DATE=#{RUBY_RELEASE_DATE}",
|
13
|
+
`gem list`
|
14
|
+
].join("\n")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
Binary file
|
Binary file
|
@@ -0,0 +1,155 @@
|
|
1
|
+
body {
|
2
|
+
font-family: 'HelveticaNeue-Light', 'Helvetica Neue Light', 'Helvetica Neue', Arial, Helvetica, sans-serif;
|
3
|
+
}
|
4
|
+
|
5
|
+
#main {
|
6
|
+
width: 800px;
|
7
|
+
margin: auto;
|
8
|
+
background: #fff;
|
9
|
+
-webkit-border-radius: 15px;
|
10
|
+
-moz-border-radius: 15px;
|
11
|
+
border-radius: 15px;
|
12
|
+
}
|
13
|
+
|
14
|
+
p{
|
15
|
+
margin: 0;
|
16
|
+
padding: 0;
|
17
|
+
text-align: center;
|
18
|
+
color: #85813B;
|
19
|
+
}
|
20
|
+
|
21
|
+
h1 {
|
22
|
+
margin: 0px;
|
23
|
+
margin-bottom: 5px;
|
24
|
+
font-size: 24px;
|
25
|
+
text-align: center;
|
26
|
+
font-weight: bold;
|
27
|
+
color: #fff;
|
28
|
+
}
|
29
|
+
h4 {
|
30
|
+
margin: 5px 0px 0px 0px;
|
31
|
+
text-align: center;
|
32
|
+
font-weight: bold;
|
33
|
+
color: #fff;
|
34
|
+
font-size: 12px;
|
35
|
+
}
|
36
|
+
|
37
|
+
h2 {
|
38
|
+
margin: 0px;
|
39
|
+
padding: 0px;
|
40
|
+
font-size: 18px;
|
41
|
+
font-weight: bold;
|
42
|
+
text-align: left;
|
43
|
+
display: inline;
|
44
|
+
}
|
45
|
+
|
46
|
+
h3 {
|
47
|
+
margin: 0px;
|
48
|
+
padding: 0px;
|
49
|
+
font-size: 14px;
|
50
|
+
font-weight: bold;
|
51
|
+
text-align: left;
|
52
|
+
}
|
53
|
+
|
54
|
+
ul {
|
55
|
+
list-style: none;
|
56
|
+
margin: 0;
|
57
|
+
padding: 0;
|
58
|
+
padding-bottom: 20px;
|
59
|
+
}
|
60
|
+
|
61
|
+
li {
|
62
|
+
padding: 20px 20px 0px 20px;
|
63
|
+
}
|
64
|
+
|
65
|
+
li a {
|
66
|
+
float: right;
|
67
|
+
}
|
68
|
+
|
69
|
+
.status{
|
70
|
+
width: 100px;
|
71
|
+
height: 20px;
|
72
|
+
text-align: center;
|
73
|
+
font-size: 60%;
|
74
|
+
line-height: 20px;
|
75
|
+
float: left;
|
76
|
+
margin-right:20px;
|
77
|
+
}
|
78
|
+
|
79
|
+
.pass{
|
80
|
+
background:#6DAF2D;
|
81
|
+
}
|
82
|
+
|
83
|
+
.fail{
|
84
|
+
background:#C52D08;
|
85
|
+
}
|
86
|
+
|
87
|
+
.warn{
|
88
|
+
background:#EBC809;
|
89
|
+
}
|
90
|
+
|
91
|
+
.info{
|
92
|
+
clear:both;
|
93
|
+
display:none;
|
94
|
+
border-bottom: 1px solid;
|
95
|
+
margin-top: 5px;
|
96
|
+
margin-bottom: 5px;
|
97
|
+
padding: 5px;
|
98
|
+
font-size: 12px;
|
99
|
+
white-space:pre;
|
100
|
+
}
|
101
|
+
|
102
|
+
.close{
|
103
|
+
display:none;
|
104
|
+
padding-right: 10px;
|
105
|
+
}
|
106
|
+
|
107
|
+
#headers{
|
108
|
+
display: none;
|
109
|
+
}
|
110
|
+
|
111
|
+
|
112
|
+
.clear { /* generic container (i.e. div) for floating buttons */
|
113
|
+
overflow: hidden;
|
114
|
+
width: 100%;
|
115
|
+
}
|
116
|
+
|
117
|
+
a.button {
|
118
|
+
background: transparent url('bg_button_a.gif') no-repeat scroll top right;
|
119
|
+
color: #444;
|
120
|
+
font: normal 12px arial, sans-serif;
|
121
|
+
height: 24px;
|
122
|
+
margin-right: 6px;
|
123
|
+
padding-right: 18px; /* sliding doors padding */
|
124
|
+
text-decoration: none;
|
125
|
+
}
|
126
|
+
|
127
|
+
a.button span {
|
128
|
+
background: transparent url('bg_button_span.gif') no-repeat;
|
129
|
+
display: block;
|
130
|
+
line-height: 14px;
|
131
|
+
padding: 5px 0 5px 18px;
|
132
|
+
}
|
133
|
+
|
134
|
+
a.button:active {
|
135
|
+
background-position: bottom right;
|
136
|
+
color: #000;
|
137
|
+
outline: none; /* hide dotted outline in Firefox */
|
138
|
+
}
|
139
|
+
|
140
|
+
a.button:active span {
|
141
|
+
background-position: bottom left;
|
142
|
+
padding: 6px 0 4px 18px; /* push text down 1px */
|
143
|
+
}
|
144
|
+
|
145
|
+
.hide {
|
146
|
+
display: none;
|
147
|
+
}
|
148
|
+
|
149
|
+
.left{
|
150
|
+
float: left;
|
151
|
+
}
|
152
|
+
|
153
|
+
.right{
|
154
|
+
float: right;
|
155
|
+
}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
module Healthy
|
3
|
+
class Router
|
4
|
+
class << self
|
5
|
+
attr_accessor :routes
|
6
|
+
|
7
|
+
# @param Hash r key should be class, value should be array of servers to run on
|
8
|
+
def add(r)
|
9
|
+
r.each { |klass, servers| add_route(klass, servers) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_route(*route)
|
13
|
+
@routes ||= Hash.new{|h, k| h[k] = {}}
|
14
|
+
klass = route.first
|
15
|
+
# this can be nil
|
16
|
+
servers = route[1]
|
17
|
+
@routes[normalized_name(klass)][:klass] = klass
|
18
|
+
@routes[normalized_name(klass)][:servers] = servers
|
19
|
+
end
|
20
|
+
|
21
|
+
def normalized_name(klass)
|
22
|
+
name = klass.respond_to?(:display_name) ? klass.display_name : klass.name
|
23
|
+
name.downcase.gsub(" ", "")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Healthy
|
2
|
+
class Server < Sinatra::Base
|
3
|
+
dir = File.dirname(File.expand_path(__FILE__))
|
4
|
+
|
5
|
+
set :views, "#{dir}/views"
|
6
|
+
set :public, "#{dir}/public"
|
7
|
+
set :static, true
|
8
|
+
|
9
|
+
get '/', :provides => 'html' do
|
10
|
+
@checks = Diagnostic.checks
|
11
|
+
@tools = Diagnostic.tools
|
12
|
+
erb :show
|
13
|
+
end
|
14
|
+
|
15
|
+
get '/up.txt' do
|
16
|
+
content_type 'text/plain'
|
17
|
+
if Healthy::Diagnostic.all_good?
|
18
|
+
return halt(200, 'PASS')
|
19
|
+
else
|
20
|
+
return halt(500, 'FAIL')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
get '/:info' do
|
25
|
+
Healthy::Diagnostic.info_for(params[:info])
|
26
|
+
end
|
27
|
+
|
28
|
+
helpers do
|
29
|
+
def url_for(path)
|
30
|
+
"#{request.env['SCRIPT_NAME']}/#{path}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def display_name(check)
|
34
|
+
klass = check.class
|
35
|
+
klass.respond_to?(:display_name) ? klass.display_name : klass.name
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
module Healthy
|
3
|
+
class ServerIdentity
|
4
|
+
class << self
|
5
|
+
attr_accessor :identity
|
6
|
+
def establish(string_or_method_name = nil, &block)
|
7
|
+
self.identity = if block
|
8
|
+
yield
|
9
|
+
elsif string_or_method_name.is_a? Symbol
|
10
|
+
self.send(string_or_method_name)
|
11
|
+
else
|
12
|
+
string_or_method_name
|
13
|
+
end
|
14
|
+
if identity.nil? || identity.empty?
|
15
|
+
raise ArgumentError, "server identity cannot be nil or empty"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def matches?(test)
|
20
|
+
test.nil? || test.empty? || test == identity || test.is_a?(Array) && test.include?(identity)
|
21
|
+
end
|
22
|
+
|
23
|
+
def fqdn
|
24
|
+
fqdn = `hostname --fqdn`.strip
|
25
|
+
fqdn = `hostname`.strip if fqdn == ''
|
26
|
+
fqdn
|
27
|
+
end
|
28
|
+
|
29
|
+
# TODO
|
30
|
+
def ip_and_port
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
5
|
+
<link rel='stylesheet' href='<%= url_for("screen.css") %>' type='text/css' media='screen' />
|
6
|
+
<title>Status : <%= Healthy::Diagnostic.status.to_s.upcase %></title>
|
7
|
+
</head>
|
8
|
+
<body class="<%= Healthy::Diagnostic.status %>">
|
9
|
+
<h1><%= Healthy::Diagnostic.status.to_s.upcase %></h1>
|
10
|
+
<div id="main">
|
11
|
+
<ul>
|
12
|
+
<% @checks.each do |check| %>
|
13
|
+
<% normalized_name = Healthy::Router.normalized_name(check.class) %>
|
14
|
+
<li id="<%= normalized_name %>">
|
15
|
+
<h2>
|
16
|
+
<div class="status <%= check.status %>"><%= check.status.to_s.upcase %></div>
|
17
|
+
<%= display_name(check) %>
|
18
|
+
</h2>
|
19
|
+
<% if check.respond_to?(:info) %>
|
20
|
+
<a href="<%= url_for(normalized_name) %>" class='remote button'><span>run</span></a>
|
21
|
+
<% end %>
|
22
|
+
<a href="#" class='close button hide' onclick="$(this).hide().siblings('.info').slideUp(); return false;"><span>close</span></a>
|
23
|
+
<div class='info'></div>
|
24
|
+
</li>
|
25
|
+
<% end %>
|
26
|
+
</ul>
|
27
|
+
<ul id='tools'>
|
28
|
+
<% @tools.each do |check| %>
|
29
|
+
<% normalized_name = Healthy::Router.normalized_name(check.class) %>
|
30
|
+
<li id="<%=normalized_name %>">
|
31
|
+
<h2>
|
32
|
+
<div class="status"></div>
|
33
|
+
<%= display_name(check) %>
|
34
|
+
</h2>
|
35
|
+
<a href="<%= url_for(normalized_name) %>" class='remote button'><span>run</span></a>
|
36
|
+
<a href="#" class='close button hide' onclick="$(this).hide().siblings('.info').slideUp(); return false;"><span>close</span></a>
|
37
|
+
<div class='info'></div>
|
38
|
+
</li>
|
39
|
+
<% end %>
|
40
|
+
</ul>
|
41
|
+
|
42
|
+
<h4 id="refresh-msg" class='left'></h4>
|
43
|
+
<h4 class='right'>
|
44
|
+
<%= Healthy::ServerIdentity.identity %>
|
45
|
+
<a href='#headers' onclick="$('#headers').toggle(); return false;">(show headers)</a>
|
46
|
+
</h4>
|
47
|
+
<div id='headers'><h6><%= request.env.keys.sort.collect{|n| "#{n} = #{request.env[n]}" }.join('<br>') %></h6></div>
|
48
|
+
</div>
|
49
|
+
</body>
|
50
|
+
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
|
51
|
+
<script type="text/JavaScript">
|
52
|
+
var pause = false;
|
53
|
+
|
54
|
+
function reload(){
|
55
|
+
if(!pause) location.reload(true);
|
56
|
+
}
|
57
|
+
|
58
|
+
function updateRefreshMessage(){
|
59
|
+
var element = document.getElementById('refresh-msg');
|
60
|
+
if(pause){
|
61
|
+
element.innerHTML = 'page refresh disabled'
|
62
|
+
return true;
|
63
|
+
}
|
64
|
+
|
65
|
+
var seconds = parseInt(element.innerHTML.replace(/\D/g,''));
|
66
|
+
if(isNaN(seconds))
|
67
|
+
element.innerHTML = "The page will refresh in 30 seconds";
|
68
|
+
else
|
69
|
+
element.innerHTML = "The page will refresh in " + (seconds - 1) + " seconds";
|
70
|
+
setTimeout('updateRefreshMessage();', 1000);
|
71
|
+
}
|
72
|
+
|
73
|
+
$(document).ready(function(){
|
74
|
+
$('a.remote').bind('click', function(){
|
75
|
+
pause = true;
|
76
|
+
var close = $(this).siblings('.close');
|
77
|
+
var info = $(this).siblings('.info');
|
78
|
+
$.get($(this).attr('href'), function(data){
|
79
|
+
info.html(data).slideDown();
|
80
|
+
close.children('span').text('hide');
|
81
|
+
});
|
82
|
+
close.show().children('span').text('(processing)');
|
83
|
+
return false;
|
84
|
+
});
|
85
|
+
|
86
|
+
updateRefreshMessage();
|
87
|
+
setTimeout("reload();", 30 * 1000);
|
88
|
+
});
|
89
|
+
</script>
|
90
|
+
</html>
|
data/spec/base_spec.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
module Healthy
|
4
|
+
|
5
|
+
describe Diagnostic::Base do
|
6
|
+
before(:all) do
|
7
|
+
class Check
|
8
|
+
include Healthy::Diagnostic::Base
|
9
|
+
end
|
10
|
+
end
|
11
|
+
it 'returns a status of :pass if a diagnostic indicates passed? and there are no warnings' do
|
12
|
+
test_diagnotic = Class.new(Check) do
|
13
|
+
def warning?; false; end
|
14
|
+
def passed?; true; end
|
15
|
+
end
|
16
|
+
test_diagnotic.new.status.should == :pass
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'returns a status of :warn if a diagnostic indicates passed? but there are warnings' do
|
20
|
+
test_diagnotic = Class.new(Check) do
|
21
|
+
def warning?; true; end
|
22
|
+
def passed?; true; end
|
23
|
+
end
|
24
|
+
test_diagnotic.new.status.should == :warn
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'returns a status of :fail when it did not pass' do
|
28
|
+
test_diagnotic = Class.new(Check) do
|
29
|
+
def warning?; true; end
|
30
|
+
def passed?; false; end
|
31
|
+
end
|
32
|
+
test_diagnotic.new.status.should == :fail
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
module Healthy
|
4
|
+
describe Diagnostic do
|
5
|
+
before :each do
|
6
|
+
Diagnostic.flush_diagnostics!
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'considers tools as anything in diagnostic array that does not have the passed? method but has info' do
|
10
|
+
test_tool_class = Class.new do
|
11
|
+
def info; end
|
12
|
+
end
|
13
|
+
Diagnostic.monitor(test_tool_class)
|
14
|
+
Diagnostic.tools.first.should be_instance_of(test_tool_class)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'considers checks as anything in diagnostic array that has the passed? method' do
|
18
|
+
test_check_class = Class.new do
|
19
|
+
def passed?; end
|
20
|
+
def info; end
|
21
|
+
end
|
22
|
+
Diagnostic.monitor(test_check_class)
|
23
|
+
Diagnostic.checks.first.should be_instance_of(test_check_class)
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
it 'should only have one instance of diagnostic even if multiple exsist so development autoreloading works' do
|
28
|
+
test_check_class = Class.new(Object)
|
29
|
+
test_check_class.class_eval do
|
30
|
+
include Diagnostic::Base
|
31
|
+
end
|
32
|
+
Diagnostic.monitor(test_check_class)
|
33
|
+
Diagnostic.monitor(test_check_class)
|
34
|
+
loaded_diagnostics = Diagnostic.instance_variable_get("@diagnostics")
|
35
|
+
loaded_diagnostics.uniq.should == loaded_diagnostics
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/spec/router_spec.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
class WarholCheck
|
4
|
+
end
|
5
|
+
|
6
|
+
class DuchampCheck
|
7
|
+
def self.display_name
|
8
|
+
"Moustache Check"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module Healthy
|
13
|
+
describe Router do
|
14
|
+
before(:all) do
|
15
|
+
Diagnostic.flush_diagnostics!
|
16
|
+
end
|
17
|
+
|
18
|
+
describe ".add" do
|
19
|
+
it "should convert they given key/value pair" do
|
20
|
+
Router.add({
|
21
|
+
WarholCheck => ["localhost:3000"],
|
22
|
+
DuchampCheck => ["localhost:3001"]
|
23
|
+
})
|
24
|
+
|
25
|
+
Router.routes.should == {
|
26
|
+
"warholcheck" => {
|
27
|
+
:servers => ["localhost:3000"],
|
28
|
+
:klass => WarholCheck
|
29
|
+
},
|
30
|
+
"moustachecheck" => {
|
31
|
+
:servers => ["localhost:3001"],
|
32
|
+
:klass => DuchampCheck
|
33
|
+
}
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
module Healthy
|
4
|
+
|
5
|
+
describe ServerIdentity do
|
6
|
+
before { ServerIdentity.identity = nil }
|
7
|
+
describe ".establish" do
|
8
|
+
it "should set the identity when given a string" do
|
9
|
+
ServerIdentity.establish("test")
|
10
|
+
ServerIdentity.identity.should == "test"
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should set the identity when given a block" do
|
14
|
+
ServerIdentity.establish { "block" }
|
15
|
+
ServerIdentity.identity.should == "block"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should set the identity when given a symbol of a method name" do
|
19
|
+
class Healthy::ServerIdentity
|
20
|
+
def self.test_method
|
21
|
+
"test_method"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
ServerIdentity.establish(:test_method)
|
26
|
+
ServerIdentity.identity.should == "test_method"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe ".matches?" do
|
31
|
+
it "should match if the argument given is nil or empty" do
|
32
|
+
ServerIdentity.matches?(nil).should == true
|
33
|
+
ServerIdentity.matches?([]).should == true
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should match if the argument is the same as the identity" do
|
37
|
+
ServerIdentity.establish("match")
|
38
|
+
ServerIdentity.matches?("match").should == true
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should match if the argument is an array containing the identity" do
|
42
|
+
ServerIdentity.establish("match")
|
43
|
+
ServerIdentity.matches?(["does not match", "match"]).should == true
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should not match if none of the above are true" do
|
47
|
+
ServerIdentity.establish("match")
|
48
|
+
ServerIdentity.matches?("does not match").should == false
|
49
|
+
ServerIdentity.matches?(["does not match"]).should == false
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rspec'
|
4
|
+
require 'healthy'
|
5
|
+
|
6
|
+
# Requires supporting files with custom matchers and macros, etc,
|
7
|
+
# in ./support/ and its subdirectories.
|
8
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
config.mock_with :mocha
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,219 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: healthy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 25
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Matthew Deiters
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-09-01 00:00:00 -10:00
|
19
|
+
default_executable: healthy-web
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
hash: 3
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
requirement: *id001
|
32
|
+
prerelease: false
|
33
|
+
name: sinatra
|
34
|
+
type: :runtime
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
hash: 3
|
42
|
+
segments:
|
43
|
+
- 2
|
44
|
+
- 3
|
45
|
+
- 0
|
46
|
+
version: 2.3.0
|
47
|
+
requirement: *id002
|
48
|
+
prerelease: false
|
49
|
+
name: rspec
|
50
|
+
type: :development
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ~>
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 23
|
58
|
+
segments:
|
59
|
+
- 1
|
60
|
+
- 0
|
61
|
+
- 0
|
62
|
+
version: 1.0.0
|
63
|
+
requirement: *id003
|
64
|
+
prerelease: false
|
65
|
+
name: bundler
|
66
|
+
type: :development
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ~>
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
hash: 7
|
74
|
+
segments:
|
75
|
+
- 1
|
76
|
+
- 5
|
77
|
+
- 2
|
78
|
+
version: 1.5.2
|
79
|
+
requirement: *id004
|
80
|
+
prerelease: false
|
81
|
+
name: jeweler
|
82
|
+
type: :development
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
hash: 3
|
90
|
+
segments:
|
91
|
+
- 0
|
92
|
+
version: "0"
|
93
|
+
requirement: *id005
|
94
|
+
prerelease: false
|
95
|
+
name: rcov
|
96
|
+
type: :development
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
99
|
+
none: false
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
hash: 3
|
104
|
+
segments:
|
105
|
+
- 0
|
106
|
+
version: "0"
|
107
|
+
requirement: *id006
|
108
|
+
prerelease: false
|
109
|
+
name: mocha
|
110
|
+
type: :development
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
version_requirements: &id007 !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
hash: 3
|
118
|
+
segments:
|
119
|
+
- 0
|
120
|
+
version: "0"
|
121
|
+
requirement: *id007
|
122
|
+
prerelease: false
|
123
|
+
name: sinatra
|
124
|
+
type: :runtime
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
version_requirements: &id008 !ruby/object:Gem::Requirement
|
127
|
+
none: false
|
128
|
+
requirements:
|
129
|
+
- - ">"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
hash: 25
|
132
|
+
segments:
|
133
|
+
- 1
|
134
|
+
- 2
|
135
|
+
- 3
|
136
|
+
version: 1.2.3
|
137
|
+
requirement: *id008
|
138
|
+
prerelease: false
|
139
|
+
name: rspec
|
140
|
+
type: :development
|
141
|
+
description: A rack app for monitoring application health that can be attached to your rails application
|
142
|
+
email: mdeiters@gmail.com
|
143
|
+
executables:
|
144
|
+
- healthy-web
|
145
|
+
extensions: []
|
146
|
+
|
147
|
+
extra_rdoc_files:
|
148
|
+
- LICENSE.txt
|
149
|
+
- README.rdoc
|
150
|
+
files:
|
151
|
+
- .document
|
152
|
+
- .rspec
|
153
|
+
- Gemfile
|
154
|
+
- Gemfile.lock
|
155
|
+
- LICENSE.txt
|
156
|
+
- README.rdoc
|
157
|
+
- Rakefile
|
158
|
+
- VERSION
|
159
|
+
- bin/healthy-web
|
160
|
+
- healthy.gemspec
|
161
|
+
- lib/healthy.rb
|
162
|
+
- lib/healthy/base.rb
|
163
|
+
- lib/healthy/diagnostic.rb
|
164
|
+
- lib/healthy/disk_space.rb
|
165
|
+
- lib/healthy/env_check.rb
|
166
|
+
- lib/healthy/gem_list.rb
|
167
|
+
- lib/healthy/public/bg_button_a.gif
|
168
|
+
- lib/healthy/public/bg_button_span.gif
|
169
|
+
- lib/healthy/public/screen.css
|
170
|
+
- lib/healthy/revision_deployed.rb
|
171
|
+
- lib/healthy/router.rb
|
172
|
+
- lib/healthy/server.rb
|
173
|
+
- lib/healthy/server_identity.rb
|
174
|
+
- lib/healthy/views/show.erb
|
175
|
+
- spec/base_spec.rb
|
176
|
+
- spec/diagnostic_spec.rb
|
177
|
+
- spec/router_spec.rb
|
178
|
+
- spec/server_identity_spec.rb
|
179
|
+
- spec/spec_helper.rb
|
180
|
+
has_rdoc: true
|
181
|
+
homepage: http://github.com/mdeiters/healthy
|
182
|
+
licenses:
|
183
|
+
- MIT
|
184
|
+
post_install_message:
|
185
|
+
rdoc_options: []
|
186
|
+
|
187
|
+
require_paths:
|
188
|
+
- lib
|
189
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
190
|
+
none: false
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
hash: 3
|
195
|
+
segments:
|
196
|
+
- 0
|
197
|
+
version: "0"
|
198
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
199
|
+
none: false
|
200
|
+
requirements:
|
201
|
+
- - ">="
|
202
|
+
- !ruby/object:Gem::Version
|
203
|
+
hash: 3
|
204
|
+
segments:
|
205
|
+
- 0
|
206
|
+
version: "0"
|
207
|
+
requirements: []
|
208
|
+
|
209
|
+
rubyforge_project:
|
210
|
+
rubygems_version: 1.6.2
|
211
|
+
signing_key:
|
212
|
+
specification_version: 3
|
213
|
+
summary: A rack app for monitoring application health that can be attached to your rails application
|
214
|
+
test_files:
|
215
|
+
- spec/base_spec.rb
|
216
|
+
- spec/diagnostic_spec.rb
|
217
|
+
- spec/router_spec.rb
|
218
|
+
- spec/server_identity_spec.rb
|
219
|
+
- spec/spec_helper.rb
|