what 0.0.8 → 0.0.9
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/lib/what/config.rb +49 -47
- data/lib/what/formatter.rb +18 -16
- data/lib/what/formatters/base.rb +8 -6
- data/lib/what/formatters/json.rb +8 -6
- data/lib/what/formatters/yaml.rb +8 -6
- data/lib/what/formatters.rb +17 -15
- data/lib/what/helpers.rb +30 -28
- data/lib/what/modules/base.rb +23 -19
- data/lib/what/modules/processes.rb +25 -24
- data/lib/what/modules/unicorn.rb +27 -25
- data/lib/what/modules.rb +22 -20
- data/lib/what/monitor.rb +21 -19
- data/lib/what/server.rb +14 -12
- data/lib/what/status.rb +12 -10
- data/lib/what/version.rb +1 -1
- metadata +3 -3
data/lib/what/config.rb
CHANGED
@@ -1,57 +1,59 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
1
|
+
module What
|
2
|
+
class Config
|
3
|
+
DEFAULTS = {
|
4
|
+
'interval' => 10,
|
5
|
+
'formatter' => 'json',
|
6
|
+
'configs' => [],
|
7
|
+
'module_paths' => [],
|
8
|
+
'modules' => [],
|
9
|
+
'module_config' => {}
|
10
|
+
}
|
11
|
+
|
12
|
+
@config = {}
|
13
|
+
|
14
|
+
def self.load(fn)
|
15
|
+
load_primary(fn)
|
16
|
+
load_secondary(@config['configs'])
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
def self.load_primary(fn)
|
20
|
+
@config = DEFAULTS.merge(YAML.load_file(fn))
|
21
|
+
@config['base'] ||= File.expand_path(File.dirname(fn))
|
22
|
+
@loaded = true
|
23
|
+
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
25
|
+
def self.load_secondary(fns)
|
26
|
+
return if !fns
|
27
|
+
|
28
|
+
fns.each do |fn|
|
29
|
+
path = if fn.match(%r(^/))
|
30
|
+
fn
|
31
|
+
else
|
32
|
+
File.join(@config['base'], fn)
|
33
|
+
end
|
34
|
+
begin
|
35
|
+
opts = YAML.load_file(path)
|
36
|
+
@config.merge!(opts)
|
37
|
+
rescue Exception => e
|
38
|
+
puts "Error loading config file #{path}: #{e}"
|
39
|
+
end
|
38
40
|
end
|
39
41
|
end
|
40
|
-
end
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
|
43
|
+
def self.loaded?
|
44
|
+
@loaded
|
45
|
+
end
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
47
|
+
def self.[](attr)
|
48
|
+
@config[attr]
|
49
|
+
end
|
49
50
|
|
50
|
-
|
51
|
-
|
52
|
-
|
51
|
+
def self.[]=(attr, val)
|
52
|
+
@config[attr] = val
|
53
|
+
end
|
53
54
|
|
54
|
-
|
55
|
-
|
55
|
+
def self.all
|
56
|
+
@config
|
57
|
+
end
|
56
58
|
end
|
57
59
|
end
|
data/lib/what/formatter.rb
CHANGED
@@ -1,20 +1,22 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
module What
|
2
|
+
class Formatter
|
3
|
+
def self.use(name)
|
4
|
+
@formatter = case name
|
5
|
+
when 'json'
|
6
|
+
Formatters::JSON.new
|
7
|
+
when 'yaml'
|
8
|
+
Formatters::YAML.new
|
9
|
+
else
|
10
|
+
raise "Unknown formatter #{name}"
|
11
|
+
end
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
def self.mime
|
15
|
+
@formatter.mime
|
16
|
+
end
|
16
17
|
|
17
|
-
|
18
|
-
|
18
|
+
def self.format(hash)
|
19
|
+
@formatter.format(hash)
|
20
|
+
end
|
19
21
|
end
|
20
22
|
end
|
data/lib/what/formatters/base.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
module What
|
2
|
+
class Formatters::Base
|
3
|
+
def mime
|
4
|
+
raise "Formatter #{self.class.name} doesn't override 'mime'"
|
5
|
+
end
|
5
6
|
|
6
|
-
|
7
|
-
|
7
|
+
def format(_)
|
8
|
+
raise "Formatter #{self.class.name} doesn't override 'format'"
|
9
|
+
end
|
8
10
|
end
|
9
11
|
end
|
data/lib/what/formatters/json.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
module What
|
2
|
+
class Formatters::JSON < Formatters::Base
|
3
|
+
def mime
|
4
|
+
'application/json'
|
5
|
+
end
|
5
6
|
|
6
|
-
|
7
|
-
|
7
|
+
def format(hash)
|
8
|
+
JSON.unparse(hash) + "\n"
|
9
|
+
end
|
8
10
|
end
|
9
11
|
end
|
data/lib/what/formatters/yaml.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
module What
|
2
|
+
class Formatters::YAML < Formatters::Base
|
3
|
+
def mime
|
4
|
+
'application/x-yaml'
|
5
|
+
end
|
5
6
|
|
6
|
-
|
7
|
-
|
7
|
+
def format(hash)
|
8
|
+
hash.to_yaml
|
9
|
+
end
|
8
10
|
end
|
9
11
|
end
|
data/lib/what/formatters.rb
CHANGED
@@ -1,23 +1,25 @@
|
|
1
|
-
module What
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
module What
|
2
|
+
module Formatters
|
3
|
+
def self.load_all
|
4
|
+
# load all formatters defined in what/formatters, in addition to any paths
|
5
|
+
# specified in the config file.
|
6
|
+
require 'what/formatters/base'
|
6
7
|
|
7
|
-
|
8
|
+
globs = [File.join(File.dirname(__FILE__), 'formatters', '*.rb')]
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
if Config['formatter_paths']
|
11
|
+
Config['formatter_paths'].each do |formatter_path|
|
12
|
+
globs << File.join(Config['base'], formatter_path, '*.rb')
|
13
|
+
end
|
12
14
|
end
|
13
|
-
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
globs.each do |glob|
|
17
|
+
Dir[glob].each do |fn|
|
18
|
+
require fn
|
19
|
+
end
|
18
20
|
end
|
19
|
-
end
|
20
21
|
|
21
|
-
|
22
|
+
Formatter.use(Config['formatter'])
|
23
|
+
end
|
22
24
|
end
|
23
25
|
end
|
data/lib/what/helpers.rb
CHANGED
@@ -1,35 +1,37 @@
|
|
1
|
-
module What
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
:warning
|
11
|
-
|
12
|
-
|
1
|
+
module What
|
2
|
+
module Helpers
|
3
|
+
# Take an array of healths and determine overall health, on
|
4
|
+
# the principle that overall health == the worst sub-health.
|
5
|
+
def self.overall_health(healths)
|
6
|
+
healths.reduce(:ok) do |overall, current|
|
7
|
+
case current
|
8
|
+
when :ok
|
9
|
+
overall
|
10
|
+
when :warning
|
11
|
+
:warning if overall != :alert
|
12
|
+
else
|
13
|
+
:alert
|
14
|
+
end
|
13
15
|
end
|
14
16
|
end
|
15
|
-
end
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
# Stolen from Rails (http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html)
|
19
|
+
def self.camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
|
20
|
+
if first_letter_in_uppercase
|
21
|
+
lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
22
|
+
else
|
23
|
+
lower_case_and_underscored_word.to_s[0].chr.downcase + camelize(lower_case_and_underscored_word)[1..-1]
|
24
|
+
end
|
23
25
|
end
|
24
|
-
end
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
27
|
+
def self.underscore(camel_cased_word)
|
28
|
+
word = camel_cased_word.to_s.dup
|
29
|
+
word.gsub!(/::/, '/')
|
30
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
31
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
32
|
+
word.tr!("-", "_")
|
33
|
+
word.downcase!
|
34
|
+
word
|
35
|
+
end
|
34
36
|
end
|
35
37
|
end
|
data/lib/what/modules/base.rb
CHANGED
@@ -1,26 +1,30 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module What
|
2
|
+
class Modules::Base
|
3
|
+
def initialize
|
4
|
+
@config = if defined?(DEFAULTS)
|
5
|
+
DEFAULTS.merge(Config['module_config'][self.name] || {})
|
6
|
+
else
|
7
|
+
Config['module_config'][self.name]
|
8
|
+
end
|
9
|
+
end
|
3
10
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
def name
|
9
|
-
Helpers.underscore(self.class.name.split('::').last)
|
10
|
-
end
|
11
|
+
def name
|
12
|
+
Helpers.underscore(self.class.name.split('::').last)
|
13
|
+
end
|
11
14
|
|
12
|
-
|
13
|
-
|
15
|
+
def check!
|
16
|
+
end
|
14
17
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
+
def status
|
19
|
+
{ :health => health }.merge(details)
|
20
|
+
end
|
18
21
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
+
def health
|
23
|
+
raise "Module #{self.class.name} doesn't override 'health'"
|
24
|
+
end
|
22
25
|
|
23
|
-
|
24
|
-
|
26
|
+
def details
|
27
|
+
{}
|
28
|
+
end
|
25
29
|
end
|
26
30
|
end
|
@@ -1,33 +1,34 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
@config
|
1
|
+
module What
|
2
|
+
class Modules::Processes < Modules::Base
|
3
|
+
def initialize
|
4
|
+
super
|
5
|
+
@config.each do |name, regexp_str|
|
6
|
+
@config[name] = Regexp.new(regexp_str)
|
7
|
+
end
|
8
|
+
@processes = {}
|
6
9
|
end
|
7
|
-
@processes = {}
|
8
|
-
end
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
def check!
|
12
|
+
@config.each do |name, regexp|
|
13
|
+
@processes[name] = `ps aux`.split("\n").grep(regexp).map do |ln|
|
14
|
+
ln =~ /^\w+\s+(\d+).*(\d+:\d\d(?:\.\d\d)?) (.*)$/
|
15
|
+
{:pid => $1, :cpu_time => $2, :proctitle => $3.strip}
|
16
|
+
end
|
17
|
+
end
|
16
18
|
end
|
17
|
-
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
def health
|
21
|
+
all_ok = true
|
22
|
+
@processes.each do |name, results|
|
23
|
+
if results.count == 0
|
24
|
+
all_ok = false
|
25
|
+
end
|
24
26
|
end
|
27
|
+
all_ok ? :ok : :alert
|
25
28
|
end
|
26
|
-
all_ok ? :ok : :alert
|
27
|
-
end
|
28
29
|
|
29
|
-
|
30
|
-
|
30
|
+
def details
|
31
|
+
@processes
|
32
|
+
end
|
31
33
|
end
|
32
34
|
end
|
33
|
-
|
data/lib/what/modules/unicorn.rb
CHANGED
@@ -1,32 +1,34 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
module What
|
2
|
+
class Modules::Unicorn < Modules::Base
|
3
|
+
DEFAULTS = {
|
4
|
+
'warning' => 1,
|
5
|
+
'alert' => 0
|
6
|
+
}
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
def initialize
|
9
|
+
super
|
10
|
+
@unicorns = []
|
11
|
+
end
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
def check!
|
14
|
+
@unicorns = `ps aux`.split("\n").grep(/unicorn_rails worker/).map do |ln|
|
15
|
+
ln =~ /^\w+\s+(\d+).*(\d+:\d\d(?:\.\d\d)?) unicorn/
|
16
|
+
{:pid => $1, :cpu_time => $2}
|
17
|
+
end
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
def health
|
21
|
+
if @unicorns.count > @config['warning']
|
22
|
+
:ok
|
23
|
+
elsif @unicorns.count > @config['alert']
|
24
|
+
:warning
|
25
|
+
else
|
26
|
+
:alert
|
27
|
+
end
|
26
28
|
end
|
27
|
-
end
|
28
29
|
|
29
|
-
|
30
|
-
|
30
|
+
def details
|
31
|
+
{:workers => @unicorns.count, :details => @unicorns}
|
32
|
+
end
|
31
33
|
end
|
32
34
|
end
|
data/lib/what/modules.rb
CHANGED
@@ -1,26 +1,28 @@
|
|
1
|
-
module What
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
module What
|
2
|
+
module Modules
|
3
|
+
# load all modules defined in what/modules, in addition to any paths
|
4
|
+
# specified in the config file.
|
5
|
+
def self.load_all
|
6
|
+
require 'what/modules/base'
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
default_modules_path = File.join(File.dirname(__FILE__), 'modules')
|
9
|
+
require_dir(default_modules_path)
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
Config['module_paths'].each do |module_path|
|
12
|
+
path = if module_path.match(%r(^/))
|
13
|
+
module_path
|
14
|
+
else
|
15
|
+
File.join(Config['base'], module_path)
|
16
|
+
end
|
17
|
+
require_dir(path)
|
18
|
+
end
|
17
19
|
end
|
18
|
-
end
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
private
|
22
|
+
def self.require_dir(path)
|
23
|
+
Dir[File.join(path, '*.rb')].each do |fn|
|
24
|
+
require fn
|
25
|
+
end
|
24
26
|
end
|
25
|
-
|
27
|
+
end
|
26
28
|
end
|
data/lib/what/monitor.rb
CHANGED
@@ -1,25 +1,27 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
module What
|
2
|
+
class Monitor
|
3
|
+
# don't worry, these method names are ironic
|
4
|
+
def self.go!
|
5
|
+
@modules = Config['modules'].map do |m|
|
6
|
+
name = Helpers.camelize(m)
|
7
|
+
Modules.const_get(name).new
|
8
|
+
end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
Thread.abort_on_exception = true
|
11
|
+
@thread = Thread.new(@modules) { |modules| self.do_it(modules) }
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
def self.do_it(modules)
|
15
|
+
loop do
|
16
|
+
healths = []
|
17
|
+
modules.each do |mod|
|
18
|
+
mod.check!
|
19
|
+
healths << mod.health
|
20
|
+
Status[mod.name] = mod.status
|
21
|
+
end
|
22
|
+
Status[:health] = Helpers.overall_health(healths)
|
23
|
+
sleep Config['interval']
|
20
24
|
end
|
21
|
-
Status[:health] = Helpers.overall_health(healths)
|
22
|
-
sleep Config['interval']
|
23
25
|
end
|
24
26
|
end
|
25
27
|
end
|
data/lib/what/server.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module What
|
2
|
+
class Server
|
3
|
+
def initialize
|
4
|
+
Modules.load_all
|
5
|
+
Formatters.load_all
|
6
|
+
Monitor.go!
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
def call(_)
|
10
|
+
[
|
11
|
+
Status[:health] != :alert ? 200 : 503,
|
12
|
+
{'Content-Type' => Formatter.mime},
|
13
|
+
Formatter.format(Status.all)
|
14
|
+
]
|
15
|
+
end
|
14
16
|
end
|
15
17
|
end
|
data/lib/what/status.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module What
|
2
|
+
class Status
|
3
|
+
@status = {}
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
def self.[](attr)
|
6
|
+
@status[attr]
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
def self.[]=(attr, val)
|
10
|
+
@status[attr] = val
|
11
|
+
end
|
11
12
|
|
12
|
-
|
13
|
-
|
13
|
+
def self.all
|
14
|
+
@status
|
15
|
+
end
|
14
16
|
end
|
15
17
|
end
|
data/lib/what/version.rb
CHANGED
metadata
CHANGED