what 0.2.5 → 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/whatch +39 -0
- data/lib/what/ch.rb +65 -0
- data/lib/what/config.rb +9 -1
- data/lib/what/modules/memory.rb +53 -0
- data/lib/what/modules.rb +42 -12
- data/lib/what/monitor.rb +25 -9
- data/lib/what/version.rb +1 -1
- metadata +25 -20
data/bin/whatch
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'optparse'
|
5
|
+
require 'what/version'
|
6
|
+
require 'what/ch'
|
7
|
+
|
8
|
+
options = Struct.new(:interval, :all).new
|
9
|
+
|
10
|
+
opts = OptionParser.new do |opts|
|
11
|
+
opts.banner = "Usage: what [options] module_name1 [ module_name2 ... ]"
|
12
|
+
opts.separator ""
|
13
|
+
|
14
|
+
opts.on_tail('-v', '--version', 'Show the version number.') do
|
15
|
+
puts What::VERSION
|
16
|
+
exit
|
17
|
+
end
|
18
|
+
|
19
|
+
opts.on_tail('-h', '--help', 'Show this message.') do
|
20
|
+
puts opts
|
21
|
+
exit
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on('-c', '--config FILE', 'Specify the location of the YAML config file.') do |fn|
|
25
|
+
What::Config.load(fn)
|
26
|
+
end
|
27
|
+
|
28
|
+
opts.on('-n', '--interval SECS', 'Run module check every SECS seconds.') do |secs|
|
29
|
+
options.interval = secs
|
30
|
+
end
|
31
|
+
|
32
|
+
opts.on_tail('-a', '--all', 'Load all modules specified in config option (which must be present too).') do
|
33
|
+
options.all = true
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
opts.parse!(ARGV)
|
38
|
+
|
39
|
+
What::Ch.run(ARGV, options)
|
data/lib/what/ch.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
## Impletments the whatsch CLI for running modules from the command line
|
2
|
+
|
3
|
+
require 'what/config'
|
4
|
+
require 'what/modules'
|
5
|
+
require 'what/monitor'
|
6
|
+
|
7
|
+
module What
|
8
|
+
class Ch
|
9
|
+
|
10
|
+
def self.run(module_names, opts)
|
11
|
+
new(module_names, opts).run
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(module_names, opts)
|
15
|
+
if opts.all && !Config.loaded?
|
16
|
+
self.error "Use all: No config given to read for module names"
|
17
|
+
end
|
18
|
+
|
19
|
+
if 0 == module_names.size && !opts.all
|
20
|
+
self.error "No module names given"
|
21
|
+
end
|
22
|
+
|
23
|
+
@modules = if What::Config.loaded?
|
24
|
+
if opts.all
|
25
|
+
What::Config['modules']
|
26
|
+
else
|
27
|
+
What::Config['modules'].select{|m| module_names.include?(m['name'])}
|
28
|
+
end
|
29
|
+
else
|
30
|
+
What::Config.set_defaults
|
31
|
+
module_names.uniq.map{|mn| {'type' => mn, 'name' => mn} }
|
32
|
+
end
|
33
|
+
|
34
|
+
if 0 == @modules.size
|
35
|
+
self.error "No modules to use"
|
36
|
+
end
|
37
|
+
|
38
|
+
@interval = (opts.interval || 10).to_i
|
39
|
+
end
|
40
|
+
|
41
|
+
def run
|
42
|
+
@modules.each do |m|
|
43
|
+
unless Modules.load_module(m['type'])
|
44
|
+
self.error("Unknown module #{m['type']}")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
@monitor = Monitor.new(@modules)
|
48
|
+
@monitor.go!
|
49
|
+
@monitor.do_it(@interval) do |health, statuses|
|
50
|
+
self.report health, statuses
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def report(health, statuses)
|
55
|
+
$stdout.puts health
|
56
|
+
$stdout.puts statuses.inspect
|
57
|
+
end
|
58
|
+
|
59
|
+
def error(message)
|
60
|
+
$stderr.puts message
|
61
|
+
exit(1)
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
data/lib/what/config.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
|
2
|
+
require 'yaml'
|
3
|
+
|
1
4
|
module What
|
2
5
|
class Config
|
3
6
|
DEFAULTS = {
|
@@ -11,12 +14,17 @@ module What
|
|
11
14
|
@config = {}
|
12
15
|
|
13
16
|
def self.load(fn)
|
17
|
+
set_defaults
|
14
18
|
load_primary(fn)
|
15
19
|
load_secondary(@config['configs'])
|
16
20
|
end
|
17
21
|
|
22
|
+
def self.set_defaults
|
23
|
+
@config = DEFAULTS
|
24
|
+
end
|
25
|
+
|
18
26
|
def self.load_primary(fn)
|
19
|
-
@config
|
27
|
+
@config.merge!(YAML.load_file(fn))
|
20
28
|
@config['base'] ||= File.expand_path(File.dirname(fn))
|
21
29
|
@loaded = true
|
22
30
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module What
|
2
|
+
class Modules::Memory < Modules::Base
|
3
|
+
DEFAULTS = {
|
4
|
+
'warning' => '80%',
|
5
|
+
'alert' => '90%'
|
6
|
+
}
|
7
|
+
|
8
|
+
def check!
|
9
|
+
fields = self.memory_details
|
10
|
+
@info = if fields.size == 2
|
11
|
+
{
|
12
|
+
'size' => fields[0],
|
13
|
+
'used' => fields[0] - fields[1],
|
14
|
+
'avail' => fields[1],
|
15
|
+
'use%' => ((1.0 - (fields[1].to_f / fields[0])) * 100).round,
|
16
|
+
'warning%' => @config['warning'].to_i,
|
17
|
+
'alert%' => @config['alert'].to_i
|
18
|
+
}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def health
|
23
|
+
if @info.nil?
|
24
|
+
'alert'
|
25
|
+
elsif @info['use%'] >= @info['alert%']
|
26
|
+
'alert'
|
27
|
+
elsif @info['use%'] >= @info['warning%']
|
28
|
+
'warning'
|
29
|
+
else
|
30
|
+
'ok'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def details
|
35
|
+
@info
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
# [total, free]
|
41
|
+
def memory_details
|
42
|
+
if RUBY_PLATFORM.match 'darwin'
|
43
|
+
line = `top -l 1 | grep PhysMem:`
|
44
|
+
used = line.match(/(\d+)\D+?used/)[1].to_i
|
45
|
+
free = line.match(/(\d+)\D+?free/)[1].to_i
|
46
|
+
[used + free, free]
|
47
|
+
else
|
48
|
+
`cat /proc/meminfo`.split("\n")[0..1].map{|line| line.match(/(\d+)/)[1].to_i}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
data/lib/what/modules.rb
CHANGED
@@ -1,28 +1,58 @@
|
|
1
|
+
require 'what/config'
|
2
|
+
|
1
3
|
module What
|
2
4
|
module Modules
|
5
|
+
|
6
|
+
def self.default_modules_full_path
|
7
|
+
File.join(File.dirname(__FILE__), 'modules')
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.config_module_full_paths
|
11
|
+
(Config['module_paths'] || []).map do |p|
|
12
|
+
if p.match(%r(^/))
|
13
|
+
p
|
14
|
+
else
|
15
|
+
File.join(Config['base'], p)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
3
20
|
# load all modules defined in what/modules, in addition to any paths
|
4
21
|
# specified in the config file.
|
5
22
|
def self.load_all
|
6
23
|
require 'what/modules/base'
|
7
24
|
|
8
|
-
|
9
|
-
require_dir(default_modules_path)
|
25
|
+
require_dir(self.default_modules_full_path)
|
10
26
|
|
11
|
-
|
12
|
-
path = if module_path.match(%r(^/))
|
13
|
-
module_path
|
14
|
-
else
|
15
|
-
File.join(Config['base'], module_path)
|
16
|
-
end
|
27
|
+
self.config_module_full_paths.each do |path|
|
17
28
|
require_dir(path)
|
18
29
|
end
|
19
30
|
end
|
20
31
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
32
|
+
def self.load_module(module_name)
|
33
|
+
require 'what/modules/base'
|
34
|
+
|
35
|
+
loaded = false
|
36
|
+
|
37
|
+
short_module_name = module_name.sub(/\.rb$/, '')
|
38
|
+
|
39
|
+
([self.default_modules_full_path] + self.config_module_full_paths).each do |path|
|
40
|
+
candidate = File.join(path, short_module_name)
|
41
|
+
if File.exists?("#{candidate}.rb")
|
42
|
+
loaded = require candidate
|
25
43
|
end
|
26
44
|
end
|
45
|
+
|
46
|
+
loaded
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def self.require_dir(path)
|
52
|
+
Dir[File.join(path, '*.rb')].each do |fn|
|
53
|
+
require fn
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
27
57
|
end
|
28
58
|
end
|
data/lib/what/monitor.rb
CHANGED
@@ -1,12 +1,20 @@
|
|
1
|
+
|
2
|
+
require 'what/modules'
|
3
|
+
require 'what/helpers'
|
4
|
+
|
1
5
|
module What
|
2
6
|
class Monitor
|
7
|
+
|
3
8
|
# don't worry, these method names are ironic
|
4
|
-
|
5
|
-
|
9
|
+
|
10
|
+
def initialize(modules)
|
11
|
+
@modules = modules.map do |mod|
|
6
12
|
name = Helpers.camelize(mod.delete('type'))
|
7
13
|
Modules.const_get(name).new(mod)
|
8
14
|
end
|
15
|
+
end
|
9
16
|
|
17
|
+
def go!
|
10
18
|
Thread.abort_on_exception = true
|
11
19
|
@threads = @modules.collect do |mod|
|
12
20
|
Thread.new do
|
@@ -17,12 +25,9 @@ module What
|
|
17
25
|
end
|
18
26
|
end
|
19
27
|
end
|
20
|
-
|
21
|
-
Thread.new { self.do_it }
|
22
28
|
end
|
23
29
|
|
24
|
-
def
|
25
|
-
Status['details'] = []
|
30
|
+
def do_it(interval)
|
26
31
|
loop do
|
27
32
|
statuses = []
|
28
33
|
healths = []
|
@@ -32,10 +37,21 @@ module What
|
|
32
37
|
statuses << th[:status]
|
33
38
|
end
|
34
39
|
end
|
35
|
-
|
36
|
-
|
37
|
-
sleep Config['interval']
|
40
|
+
yield Helpers.overall_health(healths), statuses
|
41
|
+
sleep interval
|
38
42
|
end
|
39
43
|
end
|
44
|
+
|
45
|
+
def self.go!
|
46
|
+
monitor = new Config['modules']
|
47
|
+
monitor.go!
|
48
|
+
Thread.new do
|
49
|
+
monitor.do_it(Config['interval']) do |health, statuses|
|
50
|
+
Status['health'] = health
|
51
|
+
Status['details'] = statuses
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
40
56
|
end
|
41
57
|
end
|
data/lib/what/version.rb
CHANGED
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: what
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.5
|
5
4
|
prerelease:
|
5
|
+
version: 0.2.6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Ryan Fitzgerald
|
@@ -11,56 +11,56 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2012-11
|
14
|
+
date: 2012-12-11 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
|
-
|
18
|
-
requirement: !ruby/object:Gem::Requirement
|
19
|
-
none: false
|
17
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
18
|
requirements:
|
21
19
|
- - ! '>='
|
22
20
|
- !ruby/object:Gem::Version
|
23
21
|
version: 1.1.2
|
22
|
+
none: false
|
23
|
+
name: rack
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
|
-
|
27
|
-
none: false
|
26
|
+
requirement: !ruby/object:Gem::Requirement
|
28
27
|
requirements:
|
29
28
|
- - ! '>='
|
30
29
|
- !ruby/object:Gem::Version
|
31
30
|
version: 1.1.2
|
32
|
-
- !ruby/object:Gem::Dependency
|
33
|
-
name: excon
|
34
|
-
requirement: !ruby/object:Gem::Requirement
|
35
31
|
none: false
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
34
|
requirements:
|
37
35
|
- - ~>
|
38
36
|
- !ruby/object:Gem::Version
|
39
37
|
version: 0.13.4
|
38
|
+
none: false
|
39
|
+
name: excon
|
40
40
|
type: :runtime
|
41
41
|
prerelease: false
|
42
|
-
|
43
|
-
none: false
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
44
43
|
requirements:
|
45
44
|
- - ~>
|
46
45
|
- !ruby/object:Gem::Version
|
47
46
|
version: 0.13.4
|
48
|
-
- !ruby/object:Gem::Dependency
|
49
|
-
name: json
|
50
|
-
requirement: !ruby/object:Gem::Requirement
|
51
47
|
none: false
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
50
|
requirements:
|
53
51
|
- - ! '>='
|
54
52
|
- !ruby/object:Gem::Version
|
55
53
|
version: '0'
|
54
|
+
none: false
|
55
|
+
name: json
|
56
56
|
type: :runtime
|
57
57
|
prerelease: false
|
58
|
-
|
59
|
-
none: false
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
60
59
|
requirements:
|
61
60
|
- - ! '>='
|
62
61
|
- !ruby/object:Gem::Version
|
63
62
|
version: '0'
|
63
|
+
none: false
|
64
64
|
description: ! 'What uses WEBrick to serve a JSON object representing the state of
|
65
65
|
services
|
66
66
|
|
@@ -77,6 +77,7 @@ email:
|
|
77
77
|
- colin.t.curtin@gmail.com
|
78
78
|
executables:
|
79
79
|
- what
|
80
|
+
- whatch
|
80
81
|
- whatsup
|
81
82
|
extensions: []
|
82
83
|
extra_rdoc_files: []
|
@@ -87,10 +88,12 @@ files:
|
|
87
88
|
- README.md
|
88
89
|
- Rakefile
|
89
90
|
- bin/what
|
91
|
+
- bin/whatch
|
90
92
|
- bin/whatsup
|
91
93
|
- example/modules/custom_module.rb
|
92
94
|
- example/what.yml
|
93
95
|
- lib/what.rb
|
96
|
+
- lib/what/ch.rb
|
94
97
|
- lib/what/config.rb
|
95
98
|
- lib/what/formatter.rb
|
96
99
|
- lib/what/formatters.rb
|
@@ -102,6 +105,7 @@ files:
|
|
102
105
|
- lib/what/modules/base.rb
|
103
106
|
- lib/what/modules/disk.rb
|
104
107
|
- lib/what/modules/existence.rb
|
108
|
+
- lib/what/modules/memory.rb
|
105
109
|
- lib/what/modules/process.rb
|
106
110
|
- lib/what/modules/unicorn.rb
|
107
111
|
- lib/what/modules/what.rb
|
@@ -118,21 +122,22 @@ rdoc_options: []
|
|
118
122
|
require_paths:
|
119
123
|
- lib
|
120
124
|
required_ruby_version: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
125
|
requirements:
|
123
126
|
- - ! '>='
|
124
127
|
- !ruby/object:Gem::Version
|
125
128
|
version: '0'
|
126
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
129
|
none: false
|
130
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
131
|
requirements:
|
129
132
|
- - ! '>='
|
130
133
|
- !ruby/object:Gem::Version
|
131
134
|
version: '0'
|
135
|
+
none: false
|
132
136
|
requirements: []
|
133
137
|
rubyforge_project: what
|
134
|
-
rubygems_version: 1.8.
|
138
|
+
rubygems_version: 1.8.23
|
135
139
|
signing_key:
|
136
140
|
specification_version: 3
|
137
141
|
summary: Simple server monitoring tool
|
138
142
|
test_files: []
|
143
|
+
has_rdoc:
|