slugly 0.0.4 → 0.0.6
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/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:
|