slugly 0.0.4 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/slugly +97 -59
- data/lib/slugly/redis_memory_monitor.rb +37 -0
- data/lib/slugly/server.rb +18 -7
- data/lib/slugly/slugly_servlet.rb +6 -8
- data/lib/slugly/wormly_serializer0_91.rb +2 -2
- data/lib/slugly/wormly_serializer_base.rb +3 -3
- metadata +63 -71
data/bin/slugly
CHANGED
@@ -4,85 +4,123 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), %w{.. lib}))
|
|
4
4
|
require 'optparse'
|
5
5
|
require 'uri'
|
6
6
|
require 'yaml'
|
7
|
+
require 'rubygems'
|
7
8
|
|
8
9
|
require 'slugly/server'
|
9
10
|
require 'slugly/health_provider'
|
10
11
|
require 'slugly/ssh_health_provider'
|
12
|
+
require 'slugly/redis_memory_monitor'
|
11
13
|
require 'slugly/wormly_api'
|
14
|
+
require 'slugly/wormly_serializer0_91'
|
12
15
|
|
13
|
-
|
16
|
+
def host(cfgfile)
|
17
|
+
begin
|
18
|
+
restart = false
|
14
19
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
20
|
+
providers = {
|
21
|
+
'HealthProvider' => [HealthProvider, true],
|
22
|
+
'SSHHealthProvider' => [SSHHealthProvider, true],
|
23
|
+
'RedisMemoryMonitor' => [RedisMemoryMonitor, false]
|
24
|
+
}
|
19
25
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
26
|
+
config = YAML.load_file(cfgfile)
|
27
|
+
wormly_key = config['wormly_key']
|
28
|
+
host = config['host']
|
29
|
+
port = config['port']
|
30
|
+
nodes = config['nodes']
|
31
|
+
tests_folder = config['tests_folder']
|
25
32
|
|
26
|
-
|
27
|
-
optparse.parse!
|
28
|
-
required = [:cfgfile]
|
29
|
-
missing = required.select{ |param| options_h[param].nil? }
|
30
|
-
if not missing.empty?
|
31
|
-
puts "missing required options: #{missing.join(', ')}"
|
32
|
-
puts optparse
|
33
|
-
exit
|
34
|
-
end
|
35
|
-
rescue OptionParser::InvalidOption, OptionParser::MissingArgument
|
36
|
-
puts $!.to_s
|
37
|
-
puts optparse
|
38
|
-
exit
|
39
|
-
end
|
33
|
+
slugly = Server.new(host, port)
|
40
34
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
}
|
35
|
+
['INT', 'TERM'].each do |sig|
|
36
|
+
trap(sig) { slugly.shutdown }
|
37
|
+
end
|
45
38
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
nodes = config['nodes']
|
39
|
+
trap('USR1') do
|
40
|
+
slugly.shutdown
|
41
|
+
restart = true
|
42
|
+
end
|
51
43
|
|
52
|
-
wormly_url_list = []
|
44
|
+
wormly_url_list = []
|
45
|
+
|
46
|
+
nodes.each do |node|
|
47
|
+
path = node['path']
|
48
|
+
provider, register_wormly = providers[node['provider']]
|
49
|
+
options = node['options']
|
50
|
+
wormly_id = node['wormly_id']
|
51
|
+
p = provider.new(options)
|
52
|
+
|
53
|
+
if register_wormly
|
54
|
+
wormly_url_list.push([
|
55
|
+
wormly_id,
|
56
|
+
URI::HTTP.build({
|
57
|
+
:host => host,
|
58
|
+
:port => port,
|
59
|
+
:path => path
|
60
|
+
})
|
61
|
+
]) if wormly_id and wormly_key
|
62
|
+
|
63
|
+
slugly.on_request path do |request, response|
|
64
|
+
response.body = WormlySerializer0_91.serialize(p)
|
65
|
+
response['X-Wormly-Version'] = WormlySerializer0_91.version
|
66
|
+
end
|
67
|
+
|
68
|
+
else
|
69
|
+
slugly.on_request path do |request, response|
|
70
|
+
response.body = p.status
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
53
74
|
|
54
|
-
|
55
|
-
nodes.each do |node|
|
56
|
-
path = node['path']
|
57
|
-
provider = providers[node['provider']]
|
58
|
-
options = node['options']
|
59
|
-
wormly_id = node['wormly_id']
|
75
|
+
slugly.serve do
|
60
76
|
|
61
|
-
|
62
|
-
|
63
|
-
:host => host, :port => port, :path => path
|
64
|
-
})
|
77
|
+
#once the server is running tell wormly we're up
|
78
|
+
#wormly verifies that the server responds so we avoid blocking with a new thread
|
65
79
|
|
66
|
-
|
67
|
-
|
80
|
+
Thread.new() do
|
81
|
+
wormly_api = WormlyAPI.new(wormly_key)
|
82
|
+
wormly_url_list.each do |wormly_id, uri|
|
83
|
+
res = wormly_api.enable_host_hm_linux(wormly_id, uri)
|
84
|
+
status = res.errorcode.zero? ? "succeeded" : "failed with error '#{res.errormsg}'"
|
85
|
+
puts "Enabling Health Monitoring for wormly_id #{wormly_id} at #{uri} #{status}."
|
86
|
+
end
|
87
|
+
end if wormly_key
|
68
88
|
|
69
|
-
|
89
|
+
end #slugly.serve
|
90
|
+
end while restart
|
70
91
|
end
|
71
92
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
93
|
+
def main
|
94
|
+
options_h = {}
|
95
|
+
|
96
|
+
begin
|
97
|
+
optparse = OptionParser.new do |options|
|
98
|
+
options.on('-c', '--config FILENAME', 'config file path') do |cfgfile|
|
99
|
+
options_h[:cfgfile] = cfgfile
|
100
|
+
end
|
101
|
+
|
102
|
+
options.on('-h', '--help', 'display this screen') do
|
103
|
+
puts options
|
104
|
+
exit
|
105
|
+
end
|
106
|
+
end # OptionParser.new
|
107
|
+
|
108
|
+
optparse.parse!
|
109
|
+
required = [:cfgfile]
|
110
|
+
missing = required.select{ |param| options_h[param].nil? }
|
111
|
+
if not missing.empty?
|
112
|
+
puts "missing required options: #{missing.join(', ')}"
|
113
|
+
puts optparse
|
114
|
+
exit
|
83
115
|
end
|
84
|
-
|
116
|
+
rescue OptionParser::InvalidOption, OptionParser::MissingArgument
|
117
|
+
puts $!.to_s
|
118
|
+
puts optparse
|
119
|
+
exit
|
85
120
|
end
|
86
121
|
|
122
|
+
host(options_h[:cfgfile])
|
87
123
|
end
|
88
124
|
|
125
|
+
main
|
126
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'net/ssh'
|
2
|
+
|
3
|
+
class RedisMemoryMonitor
|
4
|
+
CMD_REDIS_MEM_CURRENT = "/usr/local/bin/redis-cli -a $(grep requirepass /etc/redis.conf | cut -d ' ' -f 2) info | grep used_memory: | cut -d : -f 2"
|
5
|
+
CMD_REDIS_MEM_MAX = "grep 'maxmemory ' /etc/redis.conf | cut -d ' ' -f 2"
|
6
|
+
CACHE_TIME = 15
|
7
|
+
|
8
|
+
def initialize(options)
|
9
|
+
@hostname = options['hostname']
|
10
|
+
@username = options['username']
|
11
|
+
@alert_percent = options['alert_percent'].to_f
|
12
|
+
@last_update = Time.now - 2*CACHE_TIME
|
13
|
+
end
|
14
|
+
|
15
|
+
def redis_mem_alert
|
16
|
+
update
|
17
|
+
@_redis_mem_alert
|
18
|
+
end
|
19
|
+
|
20
|
+
def status
|
21
|
+
redis_mem_alert ? "above" : "below"
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def update()
|
27
|
+
delta = (Time.now - @last_update).to_i
|
28
|
+
if delta >= CACHE_TIME
|
29
|
+
Net::SSH.start(@hostname, @username) do |ssh|
|
30
|
+
redis_mem_current = ssh.exec!(CMD_REDIS_MEM_CURRENT).to_f
|
31
|
+
redis_mem_max = ssh.exec!(CMD_REDIS_MEM_MAX).to_f
|
32
|
+
@_redis_mem_alert = (redis_mem_current / redis_mem_max) > @alert_percent
|
33
|
+
@last_update = Time.now
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/slugly/server.rb
CHANGED
@@ -1,18 +1,29 @@
|
|
1
1
|
require 'webrick'
|
2
2
|
require 'slugly/slugly_servlet'
|
3
|
-
require 'slugly/wormly_serializer0_91'
|
4
3
|
|
5
4
|
class Server
|
6
|
-
def initialize(host, port
|
5
|
+
def initialize(host, port)
|
7
6
|
@host = host
|
8
7
|
@port = port
|
9
|
-
@routes =
|
8
|
+
@routes = Hash.new
|
9
|
+
@server = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def on_request(path, &callback)
|
13
|
+
@routes[path] = callback
|
14
|
+
end
|
15
|
+
|
16
|
+
def remove_request_handler(path)
|
17
|
+
@routes.delete(path)
|
10
18
|
end
|
11
19
|
|
12
20
|
def serve(&f)
|
13
|
-
server = WEBrick::HTTPServer.new(:BindAddress => @host, :Port => @port, :StartCallback => f)
|
14
|
-
server.mount "/", SluglyServlet, @routes
|
15
|
-
|
16
|
-
|
21
|
+
@server = WEBrick::HTTPServer.new(:BindAddress => @host, :Port => @port, :StartCallback => f)
|
22
|
+
@server.mount "/", SluglyServlet, @routes
|
23
|
+
@server.start
|
24
|
+
end
|
25
|
+
|
26
|
+
def shutdown
|
27
|
+
@server.shutdown if @server
|
17
28
|
end
|
18
29
|
end
|
@@ -1,29 +1,27 @@
|
|
1
1
|
require 'webrick'
|
2
2
|
|
3
3
|
class SluglyServlet < WEBrick::HTTPServlet::AbstractServlet
|
4
|
-
def initialize(server, providers
|
4
|
+
def initialize(server, providers)
|
5
5
|
super(server)
|
6
|
-
@serializer = wormlyserializer
|
7
6
|
@providers = providers
|
8
7
|
end
|
9
8
|
|
10
9
|
def do_POST(request, response)
|
11
|
-
response['Content-Type'] = 'text/plain'
|
12
10
|
begin
|
13
11
|
if not @providers.has_key?(request.path)
|
14
12
|
response.status = 404
|
13
|
+
response['Content-Type'] = 'text/plain'
|
15
14
|
response.body = "Unknown Route"
|
16
15
|
else
|
17
|
-
p = @providers[request.path]
|
18
|
-
response.body = @serializer.serialize(p)
|
19
16
|
response.status = 200
|
20
|
-
|
17
|
+
@providers[request.path].call(request, response)
|
21
18
|
end
|
22
19
|
rescue Exception => e
|
20
|
+
response.status = 500
|
21
|
+
response.body = "Internal Server Error"
|
22
|
+
|
23
23
|
puts e.message
|
24
24
|
puts e.backtrace.inspect
|
25
|
-
response.body = "Internal Server Error"
|
26
|
-
response.status = 500
|
27
25
|
end
|
28
26
|
end
|
29
27
|
|
@@ -1,11 +1,11 @@
|
|
1
1
|
require 'slugly/wormly_serializer_base'
|
2
2
|
|
3
3
|
class WormlySerializer0_91 < WormlySerializerBase
|
4
|
-
def version
|
4
|
+
def self.version
|
5
5
|
'0.91'
|
6
6
|
end
|
7
7
|
|
8
|
-
def serialize(provider)
|
8
|
+
def self.serialize(provider)
|
9
9
|
meta1 = [
|
10
10
|
[:moment, provider.time],
|
11
11
|
[:version, version],
|
@@ -1,9 +1,9 @@
|
|
1
1
|
class WormlySerializerBase
|
2
|
-
def version
|
2
|
+
def self.version
|
3
3
|
# e.g. '0.91'
|
4
4
|
end
|
5
5
|
|
6
|
-
def stanza(name, body = "", values ={})
|
6
|
+
def self.stanza(name, body = "", values ={})
|
7
7
|
s = "[#{name}]\n"
|
8
8
|
values.each do |k,v|
|
9
9
|
s += "#{k}:#{v}\n"
|
@@ -11,7 +11,7 @@ class WormlySerializerBase
|
|
11
11
|
s += "#{body}\n"
|
12
12
|
end
|
13
13
|
|
14
|
-
def serialize(provider)
|
14
|
+
def self.serialize(provider)
|
15
15
|
#serialize as per agent.php
|
16
16
|
end
|
17
17
|
end
|
metadata
CHANGED
@@ -1,105 +1,97 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: slugly
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 0
|
9
|
-
- 4
|
10
|
-
version: 0.0.4
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.6
|
5
|
+
prerelease:
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Alfred Rossi
|
9
|
+
- Arthur Neuman
|
14
10
|
autorequire:
|
15
11
|
bindir: bin
|
16
12
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
13
|
+
date: 2013-05-30 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
22
16
|
name: net-ssh
|
23
|
-
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
25
18
|
none: false
|
26
|
-
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
|
30
|
-
segments:
|
31
|
-
- 0
|
32
|
-
version: "0"
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
33
23
|
type: :runtime
|
34
|
-
version_requirements: *id001
|
35
|
-
- !ruby/object:Gem::Dependency
|
36
|
-
name: httparty
|
37
24
|
prerelease: false
|
38
|
-
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ! '>='
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '0'
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: httparty
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
39
34
|
none: false
|
40
|
-
requirements:
|
41
|
-
- -
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
|
44
|
-
segments:
|
45
|
-
- 0
|
46
|
-
version: "0"
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
47
39
|
type: :runtime
|
48
|
-
|
49
|
-
|
50
|
-
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
description: Proxy for Wormly.com's health monitoring to enable monitoring of machines
|
48
|
+
that are behind firewalls or where you don't want to run Wormly's HTTP and PHP-based
|
49
|
+
monitoring script. Requires only Ruby on the proxy server and nothing at all on
|
50
|
+
the machines being monitored when the SSH-based backend is used.
|
51
|
+
email:
|
51
52
|
- alfred@actionverb.com
|
52
|
-
|
53
|
+
- arthur@actionverb.com
|
54
|
+
executables:
|
53
55
|
- slugly
|
54
56
|
extensions: []
|
55
|
-
|
56
57
|
extra_rdoc_files: []
|
57
|
-
|
58
|
-
files:
|
58
|
+
files:
|
59
59
|
- bin/slugly
|
60
|
-
- lib/slugly/wormly_api.rb
|
61
|
-
- lib/slugly/ssh_health_provider.rb
|
62
60
|
- lib/slugly/health_provider.rb
|
63
|
-
- lib/slugly/
|
64
|
-
- lib/slugly/wormly_serializer_base.rb
|
61
|
+
- lib/slugly/redis_memory_monitor.rb
|
65
62
|
- lib/slugly/server.rb
|
63
|
+
- lib/slugly/slugly_servlet.rb
|
64
|
+
- lib/slugly/ssh_health_provider.rb
|
65
|
+
- lib/slugly/wormly_api.rb
|
66
66
|
- lib/slugly/wormly_serializer0_91.rb
|
67
|
+
- lib/slugly/wormly_serializer_base.rb
|
67
68
|
- LICENSE
|
68
69
|
- README.md
|
69
70
|
- config.yaml.example
|
70
|
-
|
71
|
-
homepage: https://github.com/bombino/slugly
|
71
|
+
homepage: https://github.com/actionverb/slugly
|
72
72
|
licenses: []
|
73
|
-
|
74
73
|
post_install_message:
|
75
74
|
rdoc_options: []
|
76
|
-
|
77
|
-
require_paths:
|
75
|
+
require_paths:
|
78
76
|
- lib
|
79
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
78
|
none: false
|
81
|
-
requirements:
|
82
|
-
- -
|
83
|
-
- !ruby/object:Gem::Version
|
84
|
-
|
85
|
-
|
86
|
-
- 0
|
87
|
-
version: "0"
|
88
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
84
|
none: false
|
90
|
-
requirements:
|
91
|
-
- -
|
92
|
-
- !ruby/object:Gem::Version
|
93
|
-
|
94
|
-
segments:
|
95
|
-
- 0
|
96
|
-
version: "0"
|
85
|
+
requirements:
|
86
|
+
- - ! '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
97
89
|
requirements: []
|
98
|
-
|
99
90
|
rubyforge_project:
|
100
|
-
rubygems_version: 1.
|
91
|
+
rubygems_version: 1.8.25
|
101
92
|
signing_key:
|
102
93
|
specification_version: 3
|
103
|
-
summary: Slugly is a health monitoring service for wormly with support for multiple
|
94
|
+
summary: Slugly is a health monitoring service for wormly with support for multiple
|
95
|
+
backend machines.
|
104
96
|
test_files: []
|
105
|
-
|
97
|
+
has_rdoc:
|