status_cat 0.0.8
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 +161 -0
- data/Rakefile +31 -0
- data/app/assets/javascripts/status-cat/application.js +15 -0
- data/app/assets/stylesheets/status-cat/application.css +13 -0
- data/app/controllers/status_cat/status_controller.rb +26 -0
- data/app/helpers/status_cat/status_helper.rb +105 -0
- data/app/mailers/status_cat/status_mailer.rb +12 -0
- data/app/views/status_cat/status/index.html.erb +4 -0
- data/app/views/status_cat/status_mailer/failure.html.erb +9 -0
- data/app/views/status_cat/status_mailer/failure.text.erb +1 -0
- data/config/locales/en.yml +7 -0
- data/config/routes.rb +4 -0
- data/lib/status_cat/checkers/action_mailer.rb +31 -0
- data/lib/status_cat/checkers/active_record.rb +24 -0
- data/lib/status_cat/checkers/base.rb +36 -0
- data/lib/status_cat/checkers/delayed_job.rb +28 -0
- data/lib/status_cat/checkers/s3.rb +17 -0
- data/lib/status_cat/checkers/stripe.rb +19 -0
- data/lib/status_cat/config.rb +33 -0
- data/lib/status_cat/engine.rb +5 -0
- data/lib/status_cat/status.rb +37 -0
- data/lib/status_cat/version.rb +3 -0
- data/lib/status_cat.rb +22 -0
- data/lib/tasks/status_cat.rake +14 -0
- data/spec/controllers/status_cat/status_controller_spec.rb +36 -0
- data/spec/coverage_spec.rb +22 -0
- data/spec/data/report.txt +10 -0
- data/spec/data/report.txt.tmp +10 -0
- data/spec/data/status_report_format.txt +1 -0
- data/spec/data/status_report_format.txt.tmp +1 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/checkers/dummy.rb +10 -0
- data/spec/dummy/app/controllers/application_controller.rb +10 -0
- data/spec/dummy/app/controllers/root_controller.rb +20 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/admin.html.erb +14 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/root/index.html.erb +8 -0
- data/spec/dummy/app/views/root/mail.html.erb +1 -0
- data/spec/dummy/config/application.rb +54 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +32 -0
- data/spec/dummy/config/environments/production.rb +69 -0
- data/spec/dummy/config/environments/test.rb +33 -0
- data/spec/dummy/config/initializers/action_mailer.rb +16 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/status_cat.rb +17 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/passwords.yml +5 -0
- data/spec/dummy/config/passwords.yml.sample +5 -0
- data/spec/dummy/config/routes.rb +11 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/production.sqlite3 +0 -0
- data/spec/dummy/db/schema.rb +16 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +889 -0
- data/spec/dummy/log/test.log +2474 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
- data/spec/dummy/tmp/cache/assets/D03/1A0/sprockets%2F9007913fce90a3c1766dc0d8282bd10b +0 -0
- data/spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/spec/dummy/tmp/cache/assets/D37/670/sprockets%2Fe230d6e60a0226de8748d1e26ee741cb +0 -0
- data/spec/dummy/tmp/cache/assets/D3D/4E0/sprockets%2F999ebb6862b2b7ca1b20b765f12704ed +0 -0
- data/spec/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/spec/dummy/tmp/cache/assets/DCB/210/sprockets%2Fdf0a443455a9d359be2e931ba70ecdfe +0 -0
- data/spec/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/0891c389c9f47b48b695b65602d93a57 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/0edf8c53de2ee6fe74108f1ecc87e457 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/264f02aaf3a74cd5a91b5575c69b784a +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/31c22cfbb3b5f7f9e1e9a013997ad8aa +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/400d7aa6ca317151fe36fc9f02ccfc4e +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/40da66d7323888023264d2f06b7525d4 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/4bddf542ba5114155847240380cf6e7c +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/572759e0267736e8961ff1fad85cfe47 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/6cec2a8a17b78e61daecff44044e1179 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/952a706f512b208187110eff045a0e66 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c7d1ab26b0b22ab011a9d30f44014f06 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f1ebb0ab4631911fbbdf496685d8b7a0 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/dummy/tmp/pids/server.pid +1 -0
- data/spec/helpers/status_cat/status_helper_spec.rb +101 -0
- data/spec/lib/status_cat/checkers/action_mailer_spec.rb +72 -0
- data/spec/lib/status_cat/checkers/active_record_spec.rb +45 -0
- data/spec/lib/status_cat/checkers/base_spec.rb +56 -0
- data/spec/lib/status_cat/checkers/delayed_job_spec.rb +15 -0
- data/spec/lib/status_cat/checkers/s3_spec.rb +15 -0
- data/spec/lib/status_cat/checkers/stripe_spec.rb +15 -0
- data/spec/lib/status_cat/config_spec.rb +133 -0
- data/spec/lib/status_cat/engine_spec.rb +9 -0
- data/spec/lib/status_cat/status_spec.rb +120 -0
- data/spec/lib/status_cat/version_spec.rb +11 -0
- data/spec/lib/status_cat_spec.rb +21 -0
- data/spec/lib/tasks/status_cat.rake_spec.rb +32 -0
- data/spec/mailers/status_cat/status_mailer_spec.rb +38 -0
- data/spec/spec_helper.rb +50 -0
- data/spec/support/shared/checker.rb +25 -0
- data/spec/views/status_cat/status/index.html.erb_spec.rb +25 -0
- data/spec/views/status_cat/status_mailer/failure.html.erb_spec.rb +16 -0
- data/spec/views/status_cat/status_mailer/failure.text.erb_spec.rb +15 -0
- metadata +373 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: b4d7e541b0764d848791a7a4b5d56e20de702db5
|
|
4
|
+
data.tar.gz: d072d488b05aa95fb5c2de5b6f166e81c169418d
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 8db8481cfa3edcd43bfb3b369a6ae5a63f2d0201f99d95ceca48ef129a57bbd7d96f946ab2343dde8b8da7b8ee71d918c1dc2a883a8658cf34fc88cb59ffac71
|
|
7
|
+
data.tar.gz: 4bc2df86a682d5c0e1ad4567c269878345f4bffb9657c5552e33ce2da9779ca3c35c8045073c4d0e1c874c24995a6377f8f3d19e8b65158bab5679053ab381b4
|
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright 2012 SchrodingersBox.com
|
|
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,161 @@
|
|
|
1
|
+
# schrodingersbox/status_cat README
|
|
2
|
+
|
|
3
|
+
This engine makes monitoring the status of your Rails environment easier.
|
|
4
|
+
|
|
5
|
+
It provides a Rails action with a green light / red light list of configured services,
|
|
6
|
+
such as:
|
|
7
|
+
|
|
8
|
+
* ActionMailer
|
|
9
|
+
* ActiveRecord
|
|
10
|
+
* AWS S3
|
|
11
|
+
* Delayed Job
|
|
12
|
+
* Stripe
|
|
13
|
+
|
|
14
|
+
## Getting Started
|
|
15
|
+
|
|
16
|
+
1. Add this to your `Gemfile` and `bundle install`
|
|
17
|
+
|
|
18
|
+
gem 'status_cat', :git => 'https://github.com/schrodingersbox/status_cat.git'
|
|
19
|
+
|
|
20
|
+
2. Add this to your `config/routes.rb`
|
|
21
|
+
|
|
22
|
+
mount StatusCat::Engine => '/status_cat'
|
|
23
|
+
|
|
24
|
+
3. Restart your Rails server
|
|
25
|
+
|
|
26
|
+
4. Run `rake status_cat:check` for a text status report
|
|
27
|
+
|
|
28
|
+
5. Visit http://yourapp/status_cat in a browser for an HTML status report
|
|
29
|
+
|
|
30
|
+
## Configuration
|
|
31
|
+
|
|
32
|
+
All configuration should go in `config/initializers/status_cat.rb`.
|
|
33
|
+
|
|
34
|
+
Status.configure do |config|
|
|
35
|
+
|
|
36
|
+
config.authenticate_with do
|
|
37
|
+
authenticate!
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
config.authorize_with do
|
|
41
|
+
authorize!
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
config.layout = 'admin'
|
|
45
|
+
|
|
46
|
+
config.noreply = 'noreply@schrodingersbox.com'
|
|
47
|
+
config.to = 'ops@schrodingersbox.com'
|
|
48
|
+
config.from = 'ops@schrodingersbox.com'
|
|
49
|
+
config.subject = "#{Rails.env.upcase} StatusCat Failure"
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
## How To
|
|
54
|
+
|
|
55
|
+
### Configure Enabled Checkers
|
|
56
|
+
|
|
57
|
+
By default, all subclasses of StatusCat::Checkers::Base will be run. Do the following if you would like to limit or reorder the set of checkers
|
|
58
|
+
|
|
59
|
+
Create or add to `config/initializers/status_cat.rb`
|
|
60
|
+
|
|
61
|
+
StatusCat.configure do |config|
|
|
62
|
+
config.enabled = [ :action_mailer, :active_record ]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
### Configure Email Settings
|
|
66
|
+
|
|
67
|
+
Create or add to `config/initializers/status_cat.rb`
|
|
68
|
+
|
|
69
|
+
StatusCat.configure do |config|
|
|
70
|
+
config.noreply = 'noreply@schrodingersbox.com'
|
|
71
|
+
config.to = 'ops@schrodingersbox.com'
|
|
72
|
+
config.from = 'ops@schrodingersbox.com'
|
|
73
|
+
config.subject = "#{Rails.env.upcase} StatusCat Failure"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
### Run Status Checks From A Cron
|
|
77
|
+
|
|
78
|
+
1. Run `rake status_cat:cron` from a cron job or other scheduling system.
|
|
79
|
+
|
|
80
|
+
PLEASE NOTE: The :action_mailer checker will attempt to send a test email to your `StatusCat.config.noreply` email address. This could cause unwanted spam or incur charges if you're using a metered mail transfer agent, like SendGrid.
|
|
81
|
+
|
|
82
|
+
### Add New Checkers
|
|
83
|
+
|
|
84
|
+
You can place new checkers anywhere you like, but `app/checkers` is the recommended location.
|
|
85
|
+
|
|
86
|
+
1. Add the following to `config/application.rb`
|
|
87
|
+
|
|
88
|
+
Dir[Rails.root + 'app/checkers/**/*.rb'].each { |path| require path }
|
|
89
|
+
|
|
90
|
+
2. Create a new subclass of `StatusCat::Checkers::Base` that sets `@value` and `@status` instance variables.
|
|
91
|
+
|
|
92
|
+
module StatusCat
|
|
93
|
+
module Checkers
|
|
94
|
+
class Dummy < Base
|
|
95
|
+
def initialize
|
|
96
|
+
@value = 'dummy'
|
|
97
|
+
@status = 'fail'
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
### Require authentication
|
|
104
|
+
|
|
105
|
+
Create or add to `config/initializers/status_cat.rb`
|
|
106
|
+
|
|
107
|
+
StatusCat.configure do |config|
|
|
108
|
+
config.authenticate_with do
|
|
109
|
+
warden.authenticate! scope: :user
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
### Require authorization
|
|
114
|
+
|
|
115
|
+
Create or add to `config/initializers/status_cat.rb`
|
|
116
|
+
|
|
117
|
+
StatusCat.configure do |config|
|
|
118
|
+
config.authorize_with do
|
|
119
|
+
redirect_to main_app.root_path unless current_user.try(:admin?)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
### Apply a custom layout
|
|
124
|
+
|
|
125
|
+
Create or add to `config/initializers/status_cat.rb`
|
|
126
|
+
|
|
127
|
+
StatusCat.configure do |config|
|
|
128
|
+
config.layout = 'admin'
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
## Reference
|
|
132
|
+
|
|
133
|
+
* [Getting Started with Engines](http://edgeguides.rubyonrails.org/engines.html)
|
|
134
|
+
* [Testing Rails Engines With Rspec](http://whilefalse.net/2012/01/25/testing-rails-engines-rspec/)
|
|
135
|
+
* [How do I write a Rails 3.1 engine controller test in rspec?](http://stackoverflow.com/questions/5200654/how-do-i-write-a-rails-3-1-engine-controller-test-in-rspec)
|
|
136
|
+
* [Best practice for specifying dependencies that cannot be put in gemspec?](https://groups.google.com/forum/?fromgroups=#!topic/ruby-bundler/U7FMRAl3nJE)
|
|
137
|
+
* [Clarifying the Roles of the .gemspec and Gemfile](http://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/)
|
|
138
|
+
* [The Semi-Isolated Rails Engine](http://bibwild.wordpress.com/2012/05/10/the-semi-isolated-rails-engine/)
|
|
139
|
+
* [config.reload_plugins = true only works in environment.rb](https://rails.lighthouseapp.com/projects/8994/tickets/2324-configreload_plugins-true-only-works-in-environmentrb?spam=1)
|
|
140
|
+
* [describe vs. context in rspec](http://lmws.net/describe-vs-context-in-rspec)
|
|
141
|
+
* [Add Achievement Badges to Your Gem README](http://elgalu.github.io/2013/add-achievement-badges-to-your-gem-readme/)
|
|
142
|
+
* [Publishing your gem](http://guides.rubygems.org/publishing/)
|
|
143
|
+
|
|
144
|
+
## History
|
|
145
|
+
|
|
146
|
+
Version 0.0.2 = Rails 3 compatible
|
|
147
|
+
Version 0.0.3 = Rails 4 compatible
|
|
148
|
+
|
|
149
|
+
## TODO
|
|
150
|
+
|
|
151
|
+
* Add disk space checker with externally configurable limit
|
|
152
|
+
* Add Zencoder checker?
|
|
153
|
+
* Add NewRelic checker?
|
|
154
|
+
|
|
155
|
+
* Dynamically create rake tasks for each checker
|
|
156
|
+
|
|
157
|
+
* Doc
|
|
158
|
+
* General checker concept
|
|
159
|
+
* Shared spec
|
|
160
|
+
|
|
161
|
+
* Publish as gem
|
data/Rakefile
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env rake
|
|
2
|
+
begin
|
|
3
|
+
require 'bundler/setup'
|
|
4
|
+
rescue LoadError
|
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
begin
|
|
9
|
+
require 'rdoc/task'
|
|
10
|
+
rescue LoadError
|
|
11
|
+
require 'rdoc/rdoc'
|
|
12
|
+
require 'rake/rdoctask'
|
|
13
|
+
RDoc::Task = Rake::RDocTask
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
|
17
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
18
|
+
rdoc.title = 'StatusCat'
|
|
19
|
+
rdoc.options << '--line-numbers'
|
|
20
|
+
rdoc.rdoc_files.include('README.rdoc')
|
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
|
25
|
+
load 'rails/tasks/engine.rake'
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
Bundler::GemHelper.install_tasks
|
|
30
|
+
|
|
31
|
+
load 'tasks/spec_cat.rake'
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
|
2
|
+
// listed below.
|
|
3
|
+
//
|
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
|
6
|
+
//
|
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
|
8
|
+
// the compiled file.
|
|
9
|
+
//
|
|
10
|
+
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
|
11
|
+
// GO AFTER THE REQUIRES BELOW.
|
|
12
|
+
//
|
|
13
|
+
//= require jquery
|
|
14
|
+
//= require jquery_ujs
|
|
15
|
+
//= require_tree .
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
|
3
|
+
* listed below.
|
|
4
|
+
*
|
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
|
7
|
+
*
|
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
|
9
|
+
* compiled file, but it's generally better to create a new file per style scope.
|
|
10
|
+
*
|
|
11
|
+
*= require_self
|
|
12
|
+
*= require_tree .
|
|
13
|
+
*/
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
class StatusCat::StatusController < ApplicationController
|
|
2
|
+
|
|
3
|
+
layout :set_layout
|
|
4
|
+
|
|
5
|
+
before_filter :_authenticate!
|
|
6
|
+
before_filter :_authorize!
|
|
7
|
+
|
|
8
|
+
def index
|
|
9
|
+
@checkers = StatusCat::Status.all
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def set_layout
|
|
15
|
+
return StatusCat.config.layout
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def _authenticate!
|
|
19
|
+
instance_eval( &StatusCat.config.authenticate_with )
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def _authorize!
|
|
23
|
+
instance_eval( &StatusCat.config.authorize_with )
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
module StatusCat::StatusHelper
|
|
2
|
+
|
|
3
|
+
# Constructs an HTML table header
|
|
4
|
+
|
|
5
|
+
def status_header
|
|
6
|
+
content_tag( :tr ) do
|
|
7
|
+
concat content_tag( :th, t( :name, :scope => :status_cat ) )
|
|
8
|
+
concat content_tag( :th, t( :value, :scope => :status_cat ) )
|
|
9
|
+
concat content_tag( :th, t( :status, :scope => :status_cat ) )
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Constructs an HTML table row
|
|
14
|
+
|
|
15
|
+
def status_row( checker )
|
|
16
|
+
content_tag( :tr ) do
|
|
17
|
+
concat content_tag( :td, checker.name, :style => status_style( checker ) )
|
|
18
|
+
concat content_tag( :td, checker.value )
|
|
19
|
+
concat status_cell(checker.status || t( :ok, :scope => :status_cat ))
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def status_cell( status )
|
|
24
|
+
if status.kind_of?(Array)
|
|
25
|
+
return content_tag( :td ) do
|
|
26
|
+
content_tag( :table ) do
|
|
27
|
+
rows = nil
|
|
28
|
+
status.each do |s|
|
|
29
|
+
row = content_tag( :tr ) do
|
|
30
|
+
content_tag( :td, s )
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
if rows == nil
|
|
34
|
+
rows = row
|
|
35
|
+
else
|
|
36
|
+
rows += row
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
rows
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
return content_tag( :td, status )
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Returns an HTML style for the status table cell
|
|
48
|
+
|
|
49
|
+
def status_style( checker )
|
|
50
|
+
"background-color: #{checker.status.nil? ? :green : :red}"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Returns an HTML table
|
|
54
|
+
|
|
55
|
+
def status_table( checkers )
|
|
56
|
+
content_tag( :table, :border => 1 ) do
|
|
57
|
+
concat status_header
|
|
58
|
+
checkers.each { |checker| concat status_row( checker ) }
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Returns an HTML title
|
|
63
|
+
|
|
64
|
+
def status_title
|
|
65
|
+
content_tag( :h1, t( :h1, :scope => :status_cat ) )
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Constructs a text status report
|
|
69
|
+
|
|
70
|
+
def status_report( checkers )
|
|
71
|
+
format, format_length = status_report_format( checkers )
|
|
72
|
+
header = status_report_header( format )
|
|
73
|
+
length = [ format_length, header.length ].max
|
|
74
|
+
separator = ( '-' * length ) + "\n"
|
|
75
|
+
|
|
76
|
+
result = separator + header + separator
|
|
77
|
+
checkers.each { |checker| result << checker.to_s( format ) }
|
|
78
|
+
result << separator
|
|
79
|
+
|
|
80
|
+
return result
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Generate a format string to justify all values
|
|
84
|
+
|
|
85
|
+
def status_report_format( checkers )
|
|
86
|
+
name_max = checkers.map { |c| c.name.to_s.length }.max
|
|
87
|
+
value_max = checkers.map { |c| c.value.to_s.length }.max
|
|
88
|
+
status_max = checkers.map { |c| c.status.to_s.length }.max
|
|
89
|
+
|
|
90
|
+
format = "%#{name_max}s | %#{value_max}s | %#{status_max}s\n"
|
|
91
|
+
length = name_max + 3 + value_max + 3 + status_max
|
|
92
|
+
|
|
93
|
+
return format, length
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Generate a header string
|
|
97
|
+
|
|
98
|
+
def status_report_header( format = StatusCat::Checkers::Base::FORMAT )
|
|
99
|
+
name = I18n.t( :name, :scope => :status_cat )
|
|
100
|
+
value = I18n.t( :value, :scope => :status_cat )
|
|
101
|
+
status = I18n.t( :status, :scope => :status_cat )
|
|
102
|
+
return sprintf( format, name, value, status )
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
class StatusCat::StatusMailer < ActionMailer::Base
|
|
2
|
+
|
|
3
|
+
add_template_helper( StatusCat::StatusHelper )
|
|
4
|
+
|
|
5
|
+
def failure( checkers )
|
|
6
|
+
@checkers = checkers
|
|
7
|
+
|
|
8
|
+
config = StatusCat.config
|
|
9
|
+
mail( :to => config.to, :from => config.from, :subject => config.subject )
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= status_report( @checkers ) %>
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module StatusCat
|
|
2
|
+
module Checkers
|
|
3
|
+
class ActionMailer < Base
|
|
4
|
+
|
|
5
|
+
def initialize
|
|
6
|
+
@value = "#{config[ :address ]}:#{config[ :port ]}"
|
|
7
|
+
|
|
8
|
+
unless ::ActionMailer::Base.delivery_method == :test
|
|
9
|
+
@status = fail_on_exception do
|
|
10
|
+
address = config[ :address ]
|
|
11
|
+
port = config[ :port ]
|
|
12
|
+
domain = config[ :domain ]
|
|
13
|
+
user_name = config[ :user_name ]
|
|
14
|
+
password = config[ :password ]
|
|
15
|
+
authentication = config[ :authentication ]
|
|
16
|
+
|
|
17
|
+
Net::SMTP.start( address, port, domain, user_name, password, authentication ) do |smtp|
|
|
18
|
+
smtp.send_message( '', StatusCat.config.from, StatusCat.config.noreply )
|
|
19
|
+
end
|
|
20
|
+
nil
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def config
|
|
26
|
+
@config ||= ::ActionMailer::Base.smtp_settings
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module StatusCat
|
|
2
|
+
module Checkers
|
|
3
|
+
class ActiveRecord < Base
|
|
4
|
+
|
|
5
|
+
def initialize
|
|
6
|
+
@value = "#{config[ :adapter ]}:#{config[ :username ]}@#{config[ :database ]}"
|
|
7
|
+
|
|
8
|
+
@status = fail_on_exception do
|
|
9
|
+
::ActiveRecord::Base.connection.execute( "select max(version) from schema_migrations" )
|
|
10
|
+
nil
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def config
|
|
15
|
+
unless @config
|
|
16
|
+
yaml = YAML::load( ERB.new( IO.read( File.join( Rails.root, 'config', 'database.yml' ) ) ).result )
|
|
17
|
+
@config = yaml[ Rails.env ].symbolize_keys!
|
|
18
|
+
end
|
|
19
|
+
return @config
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module StatusCat
|
|
2
|
+
module Checkers
|
|
3
|
+
class Base
|
|
4
|
+
extend ActiveSupport::DescendantsTracker
|
|
5
|
+
|
|
6
|
+
FORMAT = "%s | %s | %s\n"
|
|
7
|
+
|
|
8
|
+
attr_reader :value, :status
|
|
9
|
+
|
|
10
|
+
def self.class_to_name( klass )
|
|
11
|
+
klass.to_s.split( '::' ).last.underscore.to_sym
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def name
|
|
15
|
+
Base.class_to_name( self.class )
|
|
16
|
+
#self.class.to_s.split( '::' ).last.underscore.to_sym
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def to_s( format = FORMAT )
|
|
20
|
+
sprintf( format, name, value, status || I18n.t( :ok, :scope => :status_cat ) )
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
protected
|
|
24
|
+
|
|
25
|
+
def fail_on_exception
|
|
26
|
+
begin
|
|
27
|
+
return yield
|
|
28
|
+
rescue Exception => e
|
|
29
|
+
return e
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
return nil
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module StatusCat
|
|
2
|
+
module Checkers
|
|
3
|
+
|
|
4
|
+
class DelayedJob < Base
|
|
5
|
+
include ActionView::Helpers::DateHelper
|
|
6
|
+
|
|
7
|
+
def initialize
|
|
8
|
+
if !defined?( ::Delayed )
|
|
9
|
+
@status = 'delayed_job gem not installed'
|
|
10
|
+
else
|
|
11
|
+
@status = fail_on_exception do
|
|
12
|
+
sql = 'select count(*) from delayed_jobs'
|
|
13
|
+
result = ::ActiveRecord::Base.connection.execute( sql ).first
|
|
14
|
+
@value = result.is_a?( Hash ) ? result[ 'count' ] : result[ 0 ]
|
|
15
|
+
|
|
16
|
+
expires = 1.day.ago
|
|
17
|
+
sql = "select count(*) from delayed_jobs where created_at < '#{expires.to_s( :db )}'"
|
|
18
|
+
result = ::ActiveRecord::Base.connection.execute( sql ).first
|
|
19
|
+
value = result.is_a?( Hash ) ? result[ 'count' ] : result[ 0 ]
|
|
20
|
+
|
|
21
|
+
( value.to_i == 0 ) ? nil : "#{value} jobs more than #{time_ago_in_words( expires )} old"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module StatusCat
|
|
2
|
+
module Checkers
|
|
3
|
+
class S3 < Base
|
|
4
|
+
def initialize
|
|
5
|
+
if !defined?( ::AWS )
|
|
6
|
+
@status = 'aws-sdk gem not installed'
|
|
7
|
+
else
|
|
8
|
+
@value = AWS.config.access_key_id
|
|
9
|
+
@status = fail_on_exception do
|
|
10
|
+
s3 = AWS::S3.new
|
|
11
|
+
( s3.buckets.count > 0 ) ? nil : 'no buckets'
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module StatusCat
|
|
2
|
+
module Checkers
|
|
3
|
+
|
|
4
|
+
class Stripe < Base
|
|
5
|
+
def initialize
|
|
6
|
+
if !defined?( ::Stripe )
|
|
7
|
+
@status = 'stripe gem not installed'
|
|
8
|
+
else
|
|
9
|
+
@status = fail_on_exception do
|
|
10
|
+
account = ::Stripe::Account.retrieve()
|
|
11
|
+
@value = account.email
|
|
12
|
+
account.charge_enabled ? nil : 'Charge is not enabled'
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'singleton'
|
|
2
|
+
|
|
3
|
+
module StatusCat
|
|
4
|
+
|
|
5
|
+
class Config
|
|
6
|
+
include Singleton
|
|
7
|
+
|
|
8
|
+
NIL_PROC = proc {}
|
|
9
|
+
|
|
10
|
+
attr_accessor :enabled
|
|
11
|
+
attr_accessor :authenticate, :authorize
|
|
12
|
+
attr_accessor :from, :to, :subject, :noreply
|
|
13
|
+
attr_accessor :layout
|
|
14
|
+
|
|
15
|
+
def initialize
|
|
16
|
+
@enabled = StatusCat::Checkers::Base.descendants.map { |klass|
|
|
17
|
+
StatusCat::Checkers::Base.class_to_name( klass )
|
|
18
|
+
}.sort
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def authenticate_with(&blk)
|
|
22
|
+
@authenticate = blk if blk
|
|
23
|
+
@authenticate || NIL_PROC
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def authorize_with(&block)
|
|
27
|
+
@authorize = block if block
|
|
28
|
+
@authorize || NIL_PROC
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module StatusCat
|
|
2
|
+
|
|
3
|
+
class Status
|
|
4
|
+
|
|
5
|
+
# Returns an array of instances of StatusCat::Checkers::Base subclasses
|
|
6
|
+
def self.all
|
|
7
|
+
StatusCat::Config.instance.enabled.map { |name| factory( name ) }
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# By default, returns all checkers
|
|
11
|
+
# If given a list of checker names, returns an array of those checkers
|
|
12
|
+
# If given a single checker name, just returns that checker
|
|
13
|
+
def self.check( which = :all )
|
|
14
|
+
return all if which == :all
|
|
15
|
+
return factory( which ) unless which.is_a?( Array )
|
|
16
|
+
return which.map { |name| factory( name ) }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Emails ::failed list if it is not empty
|
|
20
|
+
def self.cron
|
|
21
|
+
checkers = self.failed
|
|
22
|
+
StatusCat::StatusMailer.failure( checkers ).deliver unless checkers.empty?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Constructs a checker instance given it's name
|
|
26
|
+
def self.factory( name )
|
|
27
|
+
( 'StatusCat::Checkers::' + name.to_s.classify ).constantize.new
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Returns an array of failed instances of ::all
|
|
31
|
+
def self.failed
|
|
32
|
+
self.all.map { |checker| checker.status.nil? ? nil : checker }.compact
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|