litmus_paper 0.9.6 → 0.9.7
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/README.md +2 -2
- data/bin/litmus-agent-check +0 -1
- data/config.ru +1 -0
- data/lib/litmus_paper/agent_check_handler.rb +28 -0
- data/lib/litmus_paper/agent_check_server.rb +97 -0
- data/lib/litmus_paper/app.rb +3 -0
- data/lib/litmus_paper/cli/agent_check.rb +46 -31
- data/lib/litmus_paper/dependency/script.rb +19 -13
- data/lib/litmus_paper/metric/cpu_load.rb +10 -4
- data/lib/litmus_paper/metric/script.rb +20 -14
- data/lib/litmus_paper/terminal_output.rb +2 -0
- data/lib/litmus_paper/version.rb +1 -1
- data/lib/litmus_paper.rb +4 -18
- data/litmus-agent-check.init.sh +130 -0
- data/litmus_paper.gemspec +0 -2
- data/spec/litmus_paper/{cli/agent_check_spec.rb → agent_check_handler_spec.rb} +12 -19
- data/spec/litmus_paper/agent_check_server_spec.rb +57 -0
- data/spec/litmus_paper/app_spec.rb +0 -16
- data/spec/litmus_paper/cli/admin_spec.rb +3 -3
- data/spec/litmus_paper/dependency/script_spec.rb +21 -1
- data/spec/litmus_paper/metric/cpu_load_spec.rb +18 -5
- data/spec/litmus_paper/metric/script_spec.rb +20 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/support/config.d/passing_test.config +0 -1
- data/spec/support/config.d/test.config +0 -1
- data/spec/support/test.config +1 -2
- data/spec/support/test.reload.config +0 -2
- metadata +9 -43
- data/lib/facts/loadaverage.rb +0 -6
- data/lib/litmus_paper/metric/available_memory.rb +0 -36
- data/spec/litmus_paper/metric/available_memory_spec.rb +0 -58
- data/spec/support/stub_facter.rb +0 -9
- data/xinetd.conf +0 -13
data/README.md
CHANGED
@@ -20,8 +20,8 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
-
Use the sample config to run it under unicorn. Or
|
24
|
-
agent-check for HAProxy
|
23
|
+
Use the sample config to run it under unicorn. Or execute litmus-agent-check to
|
24
|
+
use it as an agent-check for HAProxy.
|
25
25
|
|
26
26
|
## Contributing
|
27
27
|
|
data/bin/litmus-agent-check
CHANGED
data/config.ru
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
module LitmusPaper
|
2
|
+
class AgentCheckHandler
|
3
|
+
def self.handle(service)
|
4
|
+
output = []
|
5
|
+
health = LitmusPaper.check_service(service)
|
6
|
+
if health.nil?
|
7
|
+
output << "failed#NOT_FOUND"
|
8
|
+
else
|
9
|
+
case health.direction
|
10
|
+
when :up, :health
|
11
|
+
output << "ready" # administrative state
|
12
|
+
output << "up" # operational state
|
13
|
+
when :down
|
14
|
+
output << "drain" # administrative state
|
15
|
+
when :none
|
16
|
+
if health.ok?
|
17
|
+
output << "ready" # administrative state
|
18
|
+
output << "up" # operational state
|
19
|
+
else
|
20
|
+
output << "down" # operational state
|
21
|
+
end
|
22
|
+
end
|
23
|
+
output << "#{health.value.to_s}%"
|
24
|
+
end
|
25
|
+
output.join("\t")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# Preforking TCP server, mostly stolen from Jesse Storimer's Book Working with
|
2
|
+
# TCP Sockets
|
3
|
+
|
4
|
+
require 'socket'
|
5
|
+
require 'litmus_paper/agent_check_handler'
|
6
|
+
|
7
|
+
module LitmusPaper
|
8
|
+
class AgentCheckServer
|
9
|
+
CRLF = "\r\n"
|
10
|
+
|
11
|
+
def initialize(litmus_paper_config, services, workers, pid_file, daemonize)
|
12
|
+
LitmusPaper.configure(litmus_paper_config)
|
13
|
+
@services = services
|
14
|
+
@workers = workers
|
15
|
+
@pid_file = pid_file
|
16
|
+
@daemonize = daemonize
|
17
|
+
@control_sockets = @services.keys.map do |port|
|
18
|
+
TCPServer.new(port)
|
19
|
+
end
|
20
|
+
trap(:INT) { exit }
|
21
|
+
trap(:TERM) { exit }
|
22
|
+
end
|
23
|
+
|
24
|
+
# Stolen pattern from ruby Socket, modified to return the service based on
|
25
|
+
# the accepting port
|
26
|
+
def accept_loop(sockets)
|
27
|
+
if sockets.empty?
|
28
|
+
raise ArgumentError, "no sockets"
|
29
|
+
end
|
30
|
+
loop {
|
31
|
+
readable, _, _ = IO.select(sockets)
|
32
|
+
readable.each { |r|
|
33
|
+
begin
|
34
|
+
sock, addr = r.accept_nonblock
|
35
|
+
service = @services[r.local_address.ip_port]
|
36
|
+
rescue IO::WaitReadable
|
37
|
+
next
|
38
|
+
end
|
39
|
+
yield sock, service
|
40
|
+
}
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
def respond(sock, message)
|
45
|
+
sock.write(message)
|
46
|
+
sock.write(CRLF)
|
47
|
+
end
|
48
|
+
|
49
|
+
def write_pid(pid_file)
|
50
|
+
File.open(pid_file, 'w') do |f|
|
51
|
+
f.write(Process.pid)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def run
|
56
|
+
if @daemonize
|
57
|
+
Process.daemon
|
58
|
+
end
|
59
|
+
write_pid(@pid_file)
|
60
|
+
child_pids = []
|
61
|
+
|
62
|
+
@workers.times do
|
63
|
+
child_pids << spawn_child
|
64
|
+
end
|
65
|
+
|
66
|
+
kill_children = Proc.new { |signo|
|
67
|
+
child_pids.each do |cpid|
|
68
|
+
begin
|
69
|
+
Process.kill(:INT, cpid)
|
70
|
+
rescue Errno::ESRCH
|
71
|
+
end
|
72
|
+
end
|
73
|
+
File.delete(@pid_file) if File.exists?(@pid_file)
|
74
|
+
exit
|
75
|
+
}
|
76
|
+
|
77
|
+
trap(:INT, &kill_children)
|
78
|
+
trap(:TERM, &kill_children)
|
79
|
+
|
80
|
+
loop do
|
81
|
+
pid = Process.wait
|
82
|
+
LitmusPaper.logger.error("Process #{pid} quit unexpectedly")
|
83
|
+
child_pids.delete(pid)
|
84
|
+
child_pids << spawn_child
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def spawn_child
|
89
|
+
fork do
|
90
|
+
accept_loop(@control_sockets) do |sock, service|
|
91
|
+
respond(sock, AgentCheckHandler.handle(service))
|
92
|
+
sock.close
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
data/lib/litmus_paper/app.rb
CHANGED
@@ -1,15 +1,28 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'litmus_paper/agent_check_server'
|
3
|
+
|
1
4
|
module LitmusPaper
|
2
5
|
module CLI
|
3
6
|
class AgentCheck
|
4
7
|
|
5
8
|
def parse_args(args)
|
6
9
|
options = {}
|
10
|
+
options[:pid_file] = '/tmp/litmus-agent-check.pid'
|
7
11
|
optparser = OptionParser.new do |opts|
|
8
|
-
opts.on("-s", "--service SERVICE", "
|
9
|
-
options[:
|
12
|
+
opts.on("-s", "--service SERVICE:PORT,...", Array, "agent-check service to port mappings") do |s|
|
13
|
+
options[:services] = s
|
14
|
+
end
|
15
|
+
opts.on("-c", "--config CONFIG", "Path to litmus paper config file") do |c|
|
16
|
+
options[:litmus_paper_config] = c
|
17
|
+
end
|
18
|
+
opts.on("-p", "--pid-file PID_FILE", String, "Where to write the pid") do |p|
|
19
|
+
options[:pid_file] = p
|
10
20
|
end
|
11
|
-
opts.on("-
|
12
|
-
options[:
|
21
|
+
opts.on("-w", "--workers WORKERS", Integer, "Number of worker processes") do |w|
|
22
|
+
options[:workers] = w
|
23
|
+
end
|
24
|
+
opts.on("-D", "--daemonize", "Daemonize the process") do |d|
|
25
|
+
options[:daemonize] = d
|
13
26
|
end
|
14
27
|
opts.on("-h", "--help", "Help text") do |h|
|
15
28
|
options[:help] = h
|
@@ -29,43 +42,45 @@ module LitmusPaper
|
|
29
42
|
exit 0
|
30
43
|
end
|
31
44
|
|
32
|
-
if !options.has_key?(:
|
33
|
-
puts "Error: `-s SERVICE
|
45
|
+
if !options.has_key?(:services)
|
46
|
+
puts "Error: `-s SERVICE:PORT,...` required"
|
34
47
|
puts optparser
|
35
48
|
exit 1
|
36
49
|
end
|
37
|
-
options
|
38
|
-
end
|
39
50
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
output << "down" # operational state
|
58
|
-
end
|
51
|
+
if !options.has_key?(:workers) || options[:workers] <= 0
|
52
|
+
puts "Error: `-w WORKERS` required, and must be greater than 0"
|
53
|
+
puts " Use a value equal to the number of expected concurrent"
|
54
|
+
puts " agent checks from HAProxy"
|
55
|
+
puts optparser
|
56
|
+
exit 1
|
57
|
+
end
|
58
|
+
|
59
|
+
options[:services] = options[:services].reduce({}) do |memo, service|
|
60
|
+
if service.split(':').length == 2
|
61
|
+
service, port = service.split(':')
|
62
|
+
memo[port.to_i] = service
|
63
|
+
memo
|
64
|
+
else
|
65
|
+
puts "Error: Incorrect service port arg `-s SERVICE:PORT,...`"
|
66
|
+
puts optparser
|
67
|
+
exit 1
|
59
68
|
end
|
60
|
-
output << "#{health.value.to_s}%"
|
61
69
|
end
|
62
|
-
|
70
|
+
|
71
|
+
options
|
63
72
|
end
|
64
73
|
|
65
74
|
def run(args)
|
66
75
|
options = parse_args(args)
|
67
|
-
LitmusPaper.
|
68
|
-
|
76
|
+
agent_check_server = LitmusPaper::AgentCheckServer.new(
|
77
|
+
options[:litmus_paper_config],
|
78
|
+
options[:services],
|
79
|
+
options[:workers],
|
80
|
+
options[:pid_file],
|
81
|
+
options[:daemonize],
|
82
|
+
)
|
83
|
+
agent_check_server.run
|
69
84
|
end
|
70
85
|
|
71
86
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
1
3
|
module LitmusPaper
|
2
4
|
module Dependency
|
3
5
|
class Script
|
@@ -9,23 +11,27 @@ module LitmusPaper
|
|
9
11
|
end
|
10
12
|
|
11
13
|
def available?
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
LitmusPaper.logger.info("Available check to #{@command} failed with status #{$CHILD_STATUS.exitstatus}")
|
21
|
-
LitmusPaper.logger.info("Failed stdout: #{script_stdout}")
|
22
|
-
LitmusPaper.logger.info("Failed stderr: #{script_stderr}")
|
14
|
+
script_status = script_stdout = script_stderr = nil
|
15
|
+
Open3.popen3(@command, :pgroup=>true) do |stdin, stdout, stderr, wait_thr|
|
16
|
+
@script_pid = wait_thr.pid
|
17
|
+
thstderr = Thread.new { stderr.read }
|
18
|
+
thstdout = Thread.new { stdout.read }
|
19
|
+
if !wait_thr.join(@timeout) # wait thread does not end within timeout
|
20
|
+
kill_and_reap_script(-@script_pid) # kill the process group
|
21
|
+
raise Timeout::Error
|
23
22
|
end
|
24
|
-
|
23
|
+
script_stderr = thstderr.value
|
24
|
+
script_stdout = thstdout.value
|
25
|
+
script_status = wait_thr.value
|
26
|
+
end
|
27
|
+
unless script_status.success?
|
28
|
+
LitmusPaper.logger.info("Available check to #{@command} failed with status #{script_status.exitstatus}")
|
29
|
+
LitmusPaper.logger.info("Failed stdout: #{script_stdout}")
|
30
|
+
LitmusPaper.logger.info("Failed stderr: #{script_stderr}")
|
25
31
|
end
|
32
|
+
script_status.success?
|
26
33
|
rescue Timeout::Error
|
27
34
|
LitmusPaper.logger.info("Timeout running command: '#{@command}'")
|
28
|
-
kill_and_reap_script(@script_pid)
|
29
35
|
false
|
30
36
|
rescue => e
|
31
37
|
LitmusPaper.logger.info("Available check to #{@uri} failed with #{e.message}")
|
@@ -1,9 +1,8 @@
|
|
1
1
|
module LitmusPaper
|
2
2
|
module Metric
|
3
3
|
class CPULoad
|
4
|
-
def initialize(weight
|
4
|
+
def initialize(weight)
|
5
5
|
@weight = weight
|
6
|
-
@facter = facter
|
7
6
|
end
|
8
7
|
|
9
8
|
def current_health
|
@@ -11,11 +10,18 @@ module LitmusPaper
|
|
11
10
|
end
|
12
11
|
|
13
12
|
def processor_count
|
14
|
-
@processor_count ||=
|
13
|
+
@processor_count ||= File.readlines('/proc/cpuinfo').reduce(0) do |memo, line|
|
14
|
+
if line =~ /^processor/
|
15
|
+
memo + 1
|
16
|
+
else
|
17
|
+
memo
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
15
21
|
end
|
16
22
|
|
17
23
|
def load_average
|
18
|
-
|
24
|
+
File.read('/proc/loadavg').split(' ').first.to_f
|
19
25
|
end
|
20
26
|
|
21
27
|
def to_s
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
1
3
|
module LitmusPaper
|
2
4
|
module Metric
|
3
5
|
class Script
|
@@ -15,24 +17,28 @@ module LitmusPaper
|
|
15
17
|
|
16
18
|
def result
|
17
19
|
value = 0
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
LitmusPaper.logger.info("Available check to #{@command} failed with status #{$CHILD_STATUS.exitstatus}")
|
27
|
-
LitmusPaper.logger.info("Failed stdout: #{script_stdout}")
|
28
|
-
LitmusPaper.logger.info("Failed stderr: #{script_stderr}")
|
20
|
+
script_status = script_stdout = script_stderr = nil
|
21
|
+
Open3.popen3(@command, :pgroup=>true) do |stdin, stdout, stderr, wait_thr|
|
22
|
+
@script_pid = wait_thr.pid
|
23
|
+
thstderr = Thread.new { stderr.read }
|
24
|
+
thstdout = Thread.new { stdout.read }
|
25
|
+
if !wait_thr.join(@timeout) # wait thread does not end within timeout
|
26
|
+
kill_and_reap_script(-@script_pid) # kill the process group
|
27
|
+
raise Timeout::Error
|
29
28
|
end
|
30
|
-
|
31
|
-
value
|
29
|
+
script_stderr = thstderr.value
|
30
|
+
script_stdout = thstdout.value
|
31
|
+
value = script_stdout.strip
|
32
|
+
script_status = wait_thr.value
|
33
|
+
end
|
34
|
+
unless script_status.success?
|
35
|
+
LitmusPaper.logger.info("Available check to #{@command} failed with status #{script_status.exitstatus}")
|
36
|
+
LitmusPaper.logger.info("Failed stdout: #{script_stdout}")
|
37
|
+
LitmusPaper.logger.info("Failed stderr: #{script_stderr}")
|
32
38
|
end
|
39
|
+
value.to_f
|
33
40
|
rescue Timeout::Error
|
34
41
|
LitmusPaper.logger.info("Available check to '#{@command}' timed out")
|
35
|
-
kill_and_reap_script(@script_pid)
|
36
42
|
0
|
37
43
|
end
|
38
44
|
|
data/lib/litmus_paper/version.rb
CHANGED
data/lib/litmus_paper.rb
CHANGED
@@ -1,11 +1,3 @@
|
|
1
|
-
require 'pathname'
|
2
|
-
require 'net/http'
|
3
|
-
require 'net/https'
|
4
|
-
require 'uri'
|
5
|
-
require 'forwardable'
|
6
|
-
require 'English'
|
7
|
-
require 'colorize'
|
8
|
-
|
9
1
|
# Ruby's stock DNS resolution, by default, blocks the entire Ruby VM from
|
10
2
|
# processing while the lookup is happening, because it calls out to the native
|
11
3
|
# libc resolver code. A slow DNS server can cause your entire Ruby process to
|
@@ -15,15 +7,13 @@ require 'colorize'
|
|
15
7
|
# 'resolv-replace' monkeypatches the various Ruby Socket objects to use resolv
|
16
8
|
#
|
17
9
|
require 'resolv-replace'
|
10
|
+
require 'net/http'
|
11
|
+
require 'net/https'
|
12
|
+
require 'uri'
|
13
|
+
require 'forwardable'
|
18
14
|
|
19
|
-
require 'popen4'
|
20
|
-
require 'sinatra/base'
|
21
|
-
require 'facter'
|
22
15
|
require 'remote_syslog_logger'
|
23
16
|
|
24
|
-
require 'facts/loadaverage'
|
25
|
-
|
26
|
-
require 'litmus_paper/app'
|
27
17
|
require 'litmus_paper/configuration'
|
28
18
|
require 'litmus_paper/configuration_file'
|
29
19
|
require 'litmus_paper/dependency/file_contents'
|
@@ -33,7 +23,6 @@ require 'litmus_paper/dependency/script'
|
|
33
23
|
require 'litmus_paper/dependency/tcp'
|
34
24
|
require 'litmus_paper/health'
|
35
25
|
require 'litmus_paper/logger'
|
36
|
-
require 'litmus_paper/metric/available_memory'
|
37
26
|
require 'litmus_paper/metric/big_brother_service'
|
38
27
|
require 'litmus_paper/metric/constant_metric'
|
39
28
|
require 'litmus_paper/metric/cpu_load'
|
@@ -41,7 +30,6 @@ require 'litmus_paper/metric/internet_health'
|
|
41
30
|
require 'litmus_paper/metric/script'
|
42
31
|
require 'litmus_paper/service'
|
43
32
|
require 'litmus_paper/status_file'
|
44
|
-
require 'litmus_paper/terminal_output'
|
45
33
|
require 'litmus_paper/version'
|
46
34
|
|
47
35
|
module LitmusPaper
|
@@ -54,8 +42,6 @@ module LitmusPaper
|
|
54
42
|
self.logger = Logger.new
|
55
43
|
|
56
44
|
def self.check_service(service_name)
|
57
|
-
Facter.flush
|
58
|
-
|
59
45
|
if service = services[service_name]
|
60
46
|
service.current_health
|
61
47
|
else
|
@@ -0,0 +1,130 @@
|
|
1
|
+
#! /bin/sh
|
2
|
+
### BEGIN INIT INFO
|
3
|
+
# Provides: litmus-agent-check
|
4
|
+
# Required-Start: $remote_fs $syslog
|
5
|
+
# Required-Stop: $remote_fs $syslog
|
6
|
+
# Default-Start: 2 3 4 5
|
7
|
+
# Default-Stop: 0 1 6
|
8
|
+
# Short-Description: Litmus agent-check for HAProxy
|
9
|
+
# Description: Provide an agent-check server for HAProxy
|
10
|
+
### END INIT INFO
|
11
|
+
|
12
|
+
# Author: Braintreeps <code@getbraintree.com>
|
13
|
+
|
14
|
+
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
15
|
+
DESC="Litmus HAProxy agent-check server"
|
16
|
+
NAME=litmus-agent-check
|
17
|
+
DAEMON=/usr/bin/$NAME
|
18
|
+
PIDFILE=/var/run/litmus-agent-check/pid
|
19
|
+
DAEMON_ARGS="-D -p ${PIDFILE}"
|
20
|
+
SCRIPTNAME=/etc/init.d/$NAME
|
21
|
+
|
22
|
+
# Exit if the package is not installed
|
23
|
+
[ -x "$DAEMON" ] || exit 0
|
24
|
+
|
25
|
+
# Read configuration variable file if it is present
|
26
|
+
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
|
27
|
+
|
28
|
+
# Define LSB log_* functions.
|
29
|
+
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
|
30
|
+
. /lib/lsb/init-functions
|
31
|
+
|
32
|
+
#
|
33
|
+
# Function that starts the daemon/service
|
34
|
+
#
|
35
|
+
do_start()
|
36
|
+
{
|
37
|
+
mkdir -p $(dirname $PIDFILE)
|
38
|
+
# Return
|
39
|
+
# 0 if daemon has been started
|
40
|
+
# 1 if daemon was already running
|
41
|
+
# 2 if daemon could not be started
|
42
|
+
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|
43
|
+
|| return 1
|
44
|
+
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
|
45
|
+
$DAEMON_ARGS $EXTRA_ARGS\
|
46
|
+
|| return 2
|
47
|
+
# Add code here, if necessary, that waits for the process to be ready
|
48
|
+
# to handle requests from services started subsequently which depend
|
49
|
+
# on this one. As a last resort, sleep for some time.
|
50
|
+
}
|
51
|
+
|
52
|
+
#
|
53
|
+
# Function that stops the daemon/service
|
54
|
+
#
|
55
|
+
do_stop()
|
56
|
+
{
|
57
|
+
# Return
|
58
|
+
# 0 if daemon has been stopped
|
59
|
+
# 1 if daemon was already stopped
|
60
|
+
# 2 if daemon could not be stopped
|
61
|
+
# other if a failure occurred
|
62
|
+
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE
|
63
|
+
RETVAL="$?"
|
64
|
+
[ "$RETVAL" = 2 ] && return 2
|
65
|
+
# Many daemons don't delete their pidfiles when they exit.
|
66
|
+
rm -f $PIDFILE
|
67
|
+
return "$RETVAL"
|
68
|
+
}
|
69
|
+
|
70
|
+
#
|
71
|
+
# Function that sends a SIGHUP to the daemon/service
|
72
|
+
#
|
73
|
+
do_reload() {
|
74
|
+
#
|
75
|
+
# If the daemon can reload its configuration without
|
76
|
+
# restarting (for example, when it is sent a SIGHUP),
|
77
|
+
# then implement that here.
|
78
|
+
#
|
79
|
+
start-stop-daemon --stop --signal HUP --quiet --pidfile $PIDFILE
|
80
|
+
return 0
|
81
|
+
}
|
82
|
+
|
83
|
+
case "$1" in
|
84
|
+
start)
|
85
|
+
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
|
86
|
+
do_start
|
87
|
+
case "$?" in
|
88
|
+
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
89
|
+
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
90
|
+
esac
|
91
|
+
;;
|
92
|
+
stop)
|
93
|
+
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
94
|
+
do_stop
|
95
|
+
case "$?" in
|
96
|
+
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
97
|
+
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
98
|
+
esac
|
99
|
+
;;
|
100
|
+
status)
|
101
|
+
status_of_proc -p ${PIDFILE} && exit 0 || exit $?
|
102
|
+
;;
|
103
|
+
reload|force-reload)
|
104
|
+
log_daemon_msg "Reloading $DESC" "$NAME"
|
105
|
+
do_reload
|
106
|
+
log_end_msg $?
|
107
|
+
;;
|
108
|
+
restart)
|
109
|
+
log_daemon_msg "Restarting $DESC" "$NAME"
|
110
|
+
do_stop
|
111
|
+
case "$?" in
|
112
|
+
0|1)
|
113
|
+
do_start
|
114
|
+
case "$?" in
|
115
|
+
0) log_end_msg 0 ;;
|
116
|
+
1) log_end_msg 1 ;; # Old process is still running
|
117
|
+
*) log_end_msg 1 ;; # Failed to start
|
118
|
+
esac
|
119
|
+
;;
|
120
|
+
*)
|
121
|
+
# Failed to stop
|
122
|
+
log_end_msg 1
|
123
|
+
;;
|
124
|
+
esac
|
125
|
+
;;
|
126
|
+
*)
|
127
|
+
echo "Usage: $SCRIPTNAME {start|stop|status|restart|reload|force-reload}" >&2
|
128
|
+
exit 3
|
129
|
+
;;
|
130
|
+
esac
|
data/litmus_paper.gemspec
CHANGED
@@ -17,9 +17,7 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.version = LitmusPaper::VERSION
|
18
18
|
|
19
19
|
gem.add_dependency "sinatra", "~> 1.3.2"
|
20
|
-
gem.add_dependency "facter", "~> 1.7.5"
|
21
20
|
gem.add_dependency "remote_syslog_logger", "~> 1.0.3"
|
22
|
-
gem.add_dependency "popen4", "~> 0.1.2"
|
23
21
|
gem.add_dependency "unicorn", "~> 4.6.2"
|
24
22
|
gem.add_dependency "colorize"
|
25
23
|
|
@@ -1,47 +1,40 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'litmus_paper/
|
2
|
+
require 'litmus_paper/agent_check_handler'
|
3
3
|
|
4
|
-
describe LitmusPaper::
|
4
|
+
describe LitmusPaper::AgentCheckHandler do
|
5
5
|
before :each do
|
6
6
|
LitmusPaper.configure(TEST_CONFIG)
|
7
7
|
end
|
8
8
|
|
9
|
-
def agent_check(service)
|
10
|
-
output = StringIO.new
|
11
|
-
LitmusPaper::CLI::AgentCheck.new.output_service_status(service, output)
|
12
|
-
output.rewind
|
13
|
-
output.readline
|
14
|
-
end
|
15
|
-
|
16
9
|
describe "output_service_status" do
|
17
10
|
it "returns the forced health value for a healthy service" do
|
18
11
|
test_service = LitmusPaper::Service.new('test', [AlwaysAvailableDependency.new], [LitmusPaper::Metric::ConstantMetric.new(100)])
|
19
12
|
LitmusPaper.services['test'] = test_service
|
20
13
|
LitmusPaper::StatusFile.service_health_file("test").create("Forcing health", 88)
|
21
|
-
|
14
|
+
LitmusPaper::AgentCheckHandler.handle("test").should == "ready\tup\t88%"
|
22
15
|
end
|
23
16
|
|
24
17
|
it "returns the actual health value for an unhealthy service when the measured health is less than the forced value" do
|
25
18
|
test_service = LitmusPaper::Service.new('test', [NeverAvailableDependency.new], [LitmusPaper::Metric::ConstantMetric.new(100)])
|
26
19
|
LitmusPaper.services['test'] = test_service
|
27
20
|
LitmusPaper::StatusFile.service_health_file("test").create("Forcing health", 88)
|
28
|
-
|
21
|
+
LitmusPaper::AgentCheckHandler.handle("test").should == "ready\tup\t0%"
|
29
22
|
end
|
30
23
|
|
31
24
|
it "is 'ready' when the service is passing" do
|
32
25
|
test_service = LitmusPaper::Service.new('test', [AlwaysAvailableDependency.new], [LitmusPaper::Metric::ConstantMetric.new(100)])
|
33
26
|
LitmusPaper.services['test'] = test_service
|
34
|
-
|
27
|
+
LitmusPaper::AgentCheckHandler.handle("test").should == "ready\tup\t100%"
|
35
28
|
end
|
36
29
|
|
37
30
|
it "is 'down' when the check fails" do
|
38
31
|
test_service = LitmusPaper::Service.new('test', [NeverAvailableDependency.new], [LitmusPaper::Metric::ConstantMetric.new(100)])
|
39
32
|
LitmusPaper.services['test'] = test_service
|
40
|
-
|
33
|
+
LitmusPaper::AgentCheckHandler.handle("test").should == "down\t0%"
|
41
34
|
end
|
42
35
|
|
43
36
|
it "is 'failed' when the service is unknown" do
|
44
|
-
|
37
|
+
LitmusPaper::AgentCheckHandler.handle("unknown").should == "failed#NOT_FOUND"
|
45
38
|
end
|
46
39
|
|
47
40
|
it "is 'drain' when an up file and down file exists" do
|
@@ -49,7 +42,7 @@ describe LitmusPaper::CLI::AgentCheck do
|
|
49
42
|
LitmusPaper.services['test'] = test_service
|
50
43
|
LitmusPaper::StatusFile.service_up_file("test").create("Up for testing")
|
51
44
|
LitmusPaper::StatusFile.service_down_file("test").create("Down for testing")
|
52
|
-
|
45
|
+
LitmusPaper::AgentCheckHandler.handle("test").should == "drain\t0%"
|
53
46
|
end
|
54
47
|
|
55
48
|
it "is 'drain' when a global down file and up file exists" do
|
@@ -57,28 +50,28 @@ describe LitmusPaper::CLI::AgentCheck do
|
|
57
50
|
LitmusPaper.services['test'] = test_service
|
58
51
|
LitmusPaper::StatusFile.global_down_file.create("Down for testing")
|
59
52
|
LitmusPaper::StatusFile.global_up_file.create("Up for testing")
|
60
|
-
|
53
|
+
LitmusPaper::AgentCheckHandler.handle("test").should == "drain\t0%"
|
61
54
|
end
|
62
55
|
|
63
56
|
it "is 'ready' when an up file exists" do
|
64
57
|
test_service = LitmusPaper::Service.new('test', [NeverAvailableDependency.new], [LitmusPaper::Metric::ConstantMetric.new(100)])
|
65
58
|
LitmusPaper.services['test'] = test_service
|
66
59
|
LitmusPaper::StatusFile.service_up_file("test").create("Up for testing")
|
67
|
-
|
60
|
+
LitmusPaper::AgentCheckHandler.handle("test").should == "ready\tup\t100%"
|
68
61
|
end
|
69
62
|
|
70
63
|
it "is 'drain' when a global down file exists" do
|
71
64
|
test_service = LitmusPaper::Service.new('test', [AlwaysAvailableDependency.new], [LitmusPaper::Metric::ConstantMetric.new(100)])
|
72
65
|
LitmusPaper.services['test'] = test_service
|
73
66
|
LitmusPaper::StatusFile.global_down_file.create("Down for testing")
|
74
|
-
|
67
|
+
LitmusPaper::AgentCheckHandler.handle("test").should == "drain\t0%"
|
75
68
|
end
|
76
69
|
|
77
70
|
it "is 'ready' when a global up file exists" do
|
78
71
|
test_service = LitmusPaper::Service.new('test', [NeverAvailableDependency.new], [LitmusPaper::Metric::ConstantMetric.new(100)])
|
79
72
|
LitmusPaper.services['test'] = test_service
|
80
73
|
LitmusPaper::StatusFile.global_up_file.create("Up for testing")
|
81
|
-
|
74
|
+
LitmusPaper::AgentCheckHandler.handle("test").should == "ready\tup\t100%"
|
82
75
|
end
|
83
76
|
end
|
84
77
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'litmus_paper/agent_check_server'
|
3
|
+
|
4
|
+
describe LitmusPaper::AgentCheckServer do
|
5
|
+
pid = nil
|
6
|
+
|
7
|
+
before :all do
|
8
|
+
if ! Kernel.system("bundle exec litmus-agent-check -s passing_test:9191,test:9192 -c spec/support/test.config -w 10 -D")
|
9
|
+
fail('Unable to start server')
|
10
|
+
end
|
11
|
+
port_open = false
|
12
|
+
while ! port_open do
|
13
|
+
begin
|
14
|
+
TCPSocket.new('localhost', 9191)
|
15
|
+
rescue StandardError => e
|
16
|
+
sleep 0.1
|
17
|
+
next
|
18
|
+
end
|
19
|
+
port_open = true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
after :all do
|
24
|
+
Process.kill(:TERM, File.read('/tmp/litmus-agent-check.pid').to_i)
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "The agent-check text protocol" do
|
28
|
+
it "returns the health from a passing test" do
|
29
|
+
TCPSocket.open('localhost', 9191) do |s|
|
30
|
+
s.gets.should match(/ready\tup\t\d+%\r\n/)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
it "returns the health from a failing test" do
|
34
|
+
TCPSocket.open('localhost', 9192) do |s|
|
35
|
+
s.gets.should match(/down\t0%\r\n/)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "server" do
|
41
|
+
it "has the configured number of children running" do
|
42
|
+
pid = File.read('/tmp/litmus-agent-check.pid').to_i
|
43
|
+
children = `ps --no-headers --ppid #{pid}|wc -l`
|
44
|
+
children.strip.to_i == 10
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "server" do
|
49
|
+
it "if a child dies you get a new one" do
|
50
|
+
pid = File.read('/tmp/litmus-agent-check.pid').to_i
|
51
|
+
Kernel.system("kill -9 $(ps --no-headers --ppid #{pid} -o pid=|tail -1)")
|
52
|
+
sleep 0.5
|
53
|
+
children = `ps --no-headers --ppid #{pid}|wc -l`
|
54
|
+
children.strip.to_i == 10
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -418,22 +418,6 @@ describe LitmusPaper::App do
|
|
418
418
|
last_response.headers["X-Health-Forced"].should == "up"
|
419
419
|
last_response.body.should match(/Up for testing/)
|
420
420
|
end
|
421
|
-
|
422
|
-
it "resets the Facter cache" do
|
423
|
-
test_service = LitmusPaper::Service.new('test', [AlwaysAvailableDependency.new], [LitmusPaper::Metric::ConstantMetric.new(100)])
|
424
|
-
LitmusPaper.services['test'] = test_service
|
425
|
-
|
426
|
-
get "/test/status"
|
427
|
-
last_response.should be_ok
|
428
|
-
|
429
|
-
facter_uptime = Facter.value("uptime_seconds")
|
430
|
-
sleep 1
|
431
|
-
|
432
|
-
get "/test/status"
|
433
|
-
last_response.should be_ok
|
434
|
-
|
435
|
-
Facter.value("uptime_seconds").should > facter_uptime
|
436
|
-
end
|
437
421
|
end
|
438
422
|
|
439
423
|
describe "server errors" do
|
@@ -33,7 +33,7 @@ describe 'litmusctl' do
|
|
33
33
|
describe 'status' do
|
34
34
|
it 'returns the status of a service' do
|
35
35
|
_litmusctl('status test').should match("Health: 0")
|
36
|
-
_litmusctl('status passing_test').should match(/Health: \d
|
36
|
+
_litmusctl('status passing_test').should match(/Health: \d+/)
|
37
37
|
end
|
38
38
|
|
39
39
|
it "returns 'NOT FOUND' for a service that doesn't exist" do
|
@@ -79,7 +79,7 @@ describe 'litmusctl' do
|
|
79
79
|
_litmusctl('force up test -d').should match("File deleted")
|
80
80
|
|
81
81
|
status = _litmusctl('status passing_test')
|
82
|
-
status.should match(/Health: \d
|
82
|
+
status.should match(/Health: \d+/)
|
83
83
|
status.should_not match(/for testing/)
|
84
84
|
end
|
85
85
|
|
@@ -87,7 +87,7 @@ describe 'litmusctl' do
|
|
87
87
|
_litmusctl('force health 88 test -r "for testing"').should match("File created")
|
88
88
|
_litmusctl('force health test -d').should match("File deleted")
|
89
89
|
status = _litmusctl('status passing_test')
|
90
|
-
status.should match(/Health: \d
|
90
|
+
status.should match(/Health: \d+/)
|
91
91
|
status.should_not match(/for testing/)
|
92
92
|
end
|
93
93
|
|
@@ -7,8 +7,28 @@ describe LitmusPaper::Dependency::Script do
|
|
7
7
|
check.should be_available
|
8
8
|
end
|
9
9
|
|
10
|
+
it "is true when the script returns a lot of data" do
|
11
|
+
check = LitmusPaper::Dependency::Script.new("dd if=/dev/urandom bs=1M count=1|base64")
|
12
|
+
check.should be_available
|
13
|
+
end
|
14
|
+
|
10
15
|
it "is false when the script returns 1" do
|
11
|
-
check = LitmusPaper::Dependency::Script.new("false")
|
16
|
+
check = LitmusPaper::Dependency::Script.new("echo Hello && echo Goodbye 1>&2 && false")
|
17
|
+
check.should_not be_available
|
18
|
+
end
|
19
|
+
|
20
|
+
it "logs stdout and stderr when it fails" do
|
21
|
+
check = LitmusPaper::Dependency::Script.new("echo Hello && echo Goodbye 1>&2 && false")
|
22
|
+
count = 0
|
23
|
+
logs = [
|
24
|
+
"Available check to echo Hello && echo Goodbye 1>&2 && false failed with status 1",
|
25
|
+
"Failed stdout: Hello\n",
|
26
|
+
"Failed stderr: Goodbye\n",
|
27
|
+
]
|
28
|
+
LitmusPaper.logger.should_receive(:info).exactly(3).times do |log|
|
29
|
+
log.should == logs[count]
|
30
|
+
count += 1
|
31
|
+
end
|
12
32
|
check.should_not be_available
|
13
33
|
end
|
14
34
|
|
@@ -3,14 +3,20 @@ require 'spec_helper'
|
|
3
3
|
describe LitmusPaper::Metric::CPULoad do
|
4
4
|
describe "#current_health" do
|
5
5
|
it "is the percent of available cpu capacity" do
|
6
|
-
|
7
|
-
|
6
|
+
LitmusPaper::Metric::CPULoad.any_instance.stub(
|
7
|
+
:processor_count => 4,
|
8
|
+
:load_average => 1.00,
|
9
|
+
)
|
10
|
+
cpu_load = LitmusPaper::Metric::CPULoad.new(40)
|
8
11
|
cpu_load.current_health.should == 30
|
9
12
|
end
|
10
13
|
|
11
14
|
it "is one when the load is above one per core" do
|
12
|
-
|
13
|
-
|
15
|
+
LitmusPaper::Metric::CPULoad.any_instance.stub(
|
16
|
+
:processor_count => 4,
|
17
|
+
:load_average => 20.00,
|
18
|
+
)
|
19
|
+
cpu_load = LitmusPaper::Metric::CPULoad.new(50)
|
14
20
|
cpu_load.current_health.should == 1
|
15
21
|
end
|
16
22
|
end
|
@@ -22,7 +28,7 @@ describe LitmusPaper::Metric::CPULoad do
|
|
22
28
|
end
|
23
29
|
|
24
30
|
it "is cached" do
|
25
|
-
|
31
|
+
File.should_receive(:readlines).with('/proc/cpuinfo').once.and_return(["processor : 0\n"])
|
26
32
|
cpu_load = LitmusPaper::Metric::CPULoad.new(50)
|
27
33
|
cpu_load.processor_count
|
28
34
|
cpu_load.processor_count
|
@@ -35,6 +41,13 @@ describe LitmusPaper::Metric::CPULoad do
|
|
35
41
|
cpu_load = LitmusPaper::Metric::CPULoad.new(50)
|
36
42
|
cpu_load.load_average.should > 0.0
|
37
43
|
end
|
44
|
+
|
45
|
+
it "is not cached" do
|
46
|
+
File.should_receive(:read).with('/proc/loadavg').twice.and_return("0.08 0.12 0.15 2/1190 9152\n")
|
47
|
+
cpu_load = LitmusPaper::Metric::CPULoad.new(50)
|
48
|
+
cpu_load.load_average.should > 0.0
|
49
|
+
cpu_load.load_average.should > 0.0
|
50
|
+
end
|
38
51
|
end
|
39
52
|
|
40
53
|
describe "#to_s" do
|
@@ -7,6 +7,26 @@ describe LitmusPaper::Metric::Script do
|
|
7
7
|
check.current_health.should == 1
|
8
8
|
end
|
9
9
|
|
10
|
+
it "is true when the script returns a lot of data" do
|
11
|
+
check = LitmusPaper::Metric::Script.new("dd if=/dev/urandom bs=1M count=1|base64 >&2 && echo 1", 1)
|
12
|
+
check.current_health.should == 1
|
13
|
+
end
|
14
|
+
|
15
|
+
it "logs stdout and stderr when it fails" do
|
16
|
+
check = LitmusPaper::Metric::Script.new("echo Hello && echo Goodbye 1>&2 && false", 1)
|
17
|
+
count = 0
|
18
|
+
logs = [
|
19
|
+
"Available check to echo Hello && echo Goodbye 1>&2 && false failed with status 1",
|
20
|
+
"Failed stdout: Hello\n",
|
21
|
+
"Failed stderr: Goodbye\n",
|
22
|
+
]
|
23
|
+
LitmusPaper.logger.should_receive(:info).exactly(3).times do |log|
|
24
|
+
log.should == logs[count]
|
25
|
+
count += 1
|
26
|
+
end
|
27
|
+
check.current_health.should == 0
|
28
|
+
end
|
29
|
+
|
10
30
|
it "is zero when the script exits 1" do
|
11
31
|
check = LitmusPaper::Metric::Script.new("false", 1)
|
12
32
|
check.current_health.should == 0
|
data/spec/spec_helper.rb
CHANGED
data/spec/support/test.config
CHANGED
@@ -8,10 +8,9 @@ service :test do |s|
|
|
8
8
|
s.depends Dependency::HTTP, "http://localhost/heartbeat"
|
9
9
|
|
10
10
|
s.measure_health Metric::CPULoad, :weight => 50
|
11
|
-
s.measure_health Metric::AvailableMemory, :weight => 50
|
12
11
|
end
|
13
12
|
|
14
13
|
service :passing_test do |s|
|
15
14
|
s.measure_health Metric::CPULoad, :weight => 50
|
16
|
-
s.
|
15
|
+
s.depends Dependency::Script, "/bin/true"
|
17
16
|
end
|
@@ -8,10 +8,8 @@ service :foo do |s|
|
|
8
8
|
s.depends Dependency::HTTP, "http://localhost/heartbeat"
|
9
9
|
|
10
10
|
s.measure_health Metric::CPULoad, :weight => 50
|
11
|
-
s.measure_health Metric::AvailableMemory, :weight => 50
|
12
11
|
end
|
13
12
|
|
14
13
|
service :passing_test do |s|
|
15
14
|
s.measure_health Metric::CPULoad, :weight => 50
|
16
|
-
s.measure_health Metric::AvailableMemory, :weight => 50
|
17
15
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: litmus_paper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-06-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sinatra
|
@@ -27,22 +27,6 @@ dependencies:
|
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: 1.3.2
|
30
|
-
- !ruby/object:Gem::Dependency
|
31
|
-
name: facter
|
32
|
-
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
|
-
requirements:
|
35
|
-
- - ~>
|
36
|
-
- !ruby/object:Gem::Version
|
37
|
-
version: 1.7.5
|
38
|
-
type: :runtime
|
39
|
-
prerelease: false
|
40
|
-
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
|
-
requirements:
|
43
|
-
- - ~>
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version: 1.7.5
|
46
30
|
- !ruby/object:Gem::Dependency
|
47
31
|
name: remote_syslog_logger
|
48
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -59,22 +43,6 @@ dependencies:
|
|
59
43
|
- - ~>
|
60
44
|
- !ruby/object:Gem::Version
|
61
45
|
version: 1.0.3
|
62
|
-
- !ruby/object:Gem::Dependency
|
63
|
-
name: popen4
|
64
|
-
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
|
-
requirements:
|
67
|
-
- - ~>
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
version: 0.1.2
|
70
|
-
type: :runtime
|
71
|
-
prerelease: false
|
72
|
-
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
|
-
requirements:
|
75
|
-
- - ~>
|
76
|
-
- !ruby/object:Gem::Version
|
77
|
-
version: 0.1.2
|
78
46
|
- !ruby/object:Gem::Dependency
|
79
47
|
name: unicorn
|
80
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -193,8 +161,9 @@ files:
|
|
193
161
|
- bin/litmus-agent-check
|
194
162
|
- bin/litmusctl
|
195
163
|
- config.ru
|
196
|
-
- lib/facts/loadaverage.rb
|
197
164
|
- lib/litmus_paper.rb
|
165
|
+
- lib/litmus_paper/agent_check_handler.rb
|
166
|
+
- lib/litmus_paper/agent_check_server.rb
|
198
167
|
- lib/litmus_paper/app.rb
|
199
168
|
- lib/litmus_paper/cli/admin.rb
|
200
169
|
- lib/litmus_paper/cli/admin/command.rb
|
@@ -212,7 +181,6 @@ files:
|
|
212
181
|
- lib/litmus_paper/dependency/tcp.rb
|
213
182
|
- lib/litmus_paper/health.rb
|
214
183
|
- lib/litmus_paper/logger.rb
|
215
|
-
- lib/litmus_paper/metric/available_memory.rb
|
216
184
|
- lib/litmus_paper/metric/big_brother_service.rb
|
217
185
|
- lib/litmus_paper/metric/constant_metric.rb
|
218
186
|
- lib/litmus_paper/metric/cpu_load.rb
|
@@ -222,10 +190,12 @@ files:
|
|
222
190
|
- lib/litmus_paper/status_file.rb
|
223
191
|
- lib/litmus_paper/terminal_output.rb
|
224
192
|
- lib/litmus_paper/version.rb
|
193
|
+
- litmus-agent-check.init.sh
|
225
194
|
- litmus_paper.gemspec
|
195
|
+
- spec/litmus_paper/agent_check_handler_spec.rb
|
196
|
+
- spec/litmus_paper/agent_check_server_spec.rb
|
226
197
|
- spec/litmus_paper/app_spec.rb
|
227
198
|
- spec/litmus_paper/cli/admin_spec.rb
|
228
|
-
- spec/litmus_paper/cli/agent_check_spec.rb
|
229
199
|
- spec/litmus_paper/configuration_file_spec.rb
|
230
200
|
- spec/litmus_paper/dependency/file_contents_spec.rb
|
231
201
|
- spec/litmus_paper/dependency/haproxy_backends_spec.rb
|
@@ -233,7 +203,6 @@ files:
|
|
233
203
|
- spec/litmus_paper/dependency/script_spec.rb
|
234
204
|
- spec/litmus_paper/dependency/tcp_spec.rb
|
235
205
|
- spec/litmus_paper/health_spec.rb
|
236
|
-
- spec/litmus_paper/metric/available_memory_spec.rb
|
237
206
|
- spec/litmus_paper/metric/big_brother_service_spec.rb
|
238
207
|
- spec/litmus_paper/metric/constant_metric_spec.rb
|
239
208
|
- spec/litmus_paper/metric/cpu_load_spec.rb
|
@@ -254,12 +223,10 @@ files:
|
|
254
223
|
- spec/support/http_test_server_config.ru
|
255
224
|
- spec/support/never_available_dependency.rb
|
256
225
|
- spec/support/stdout_logger.rb
|
257
|
-
- spec/support/stub_facter.rb
|
258
226
|
- spec/support/test.config
|
259
227
|
- spec/support/test.d.config
|
260
228
|
- spec/support/test.reload.config
|
261
229
|
- spec/support/test.unicorn.config
|
262
|
-
- xinetd.conf
|
263
230
|
homepage: https://github.com/braintree/litmus_paper
|
264
231
|
licenses: []
|
265
232
|
post_install_message:
|
@@ -285,9 +252,10 @@ signing_key:
|
|
285
252
|
specification_version: 3
|
286
253
|
summary: Backend health tester for HA Services, partner project of big_brother
|
287
254
|
test_files:
|
255
|
+
- spec/litmus_paper/agent_check_handler_spec.rb
|
256
|
+
- spec/litmus_paper/agent_check_server_spec.rb
|
288
257
|
- spec/litmus_paper/app_spec.rb
|
289
258
|
- spec/litmus_paper/cli/admin_spec.rb
|
290
|
-
- spec/litmus_paper/cli/agent_check_spec.rb
|
291
259
|
- spec/litmus_paper/configuration_file_spec.rb
|
292
260
|
- spec/litmus_paper/dependency/file_contents_spec.rb
|
293
261
|
- spec/litmus_paper/dependency/haproxy_backends_spec.rb
|
@@ -295,7 +263,6 @@ test_files:
|
|
295
263
|
- spec/litmus_paper/dependency/script_spec.rb
|
296
264
|
- spec/litmus_paper/dependency/tcp_spec.rb
|
297
265
|
- spec/litmus_paper/health_spec.rb
|
298
|
-
- spec/litmus_paper/metric/available_memory_spec.rb
|
299
266
|
- spec/litmus_paper/metric/big_brother_service_spec.rb
|
300
267
|
- spec/litmus_paper/metric/constant_metric_spec.rb
|
301
268
|
- spec/litmus_paper/metric/cpu_load_spec.rb
|
@@ -316,7 +283,6 @@ test_files:
|
|
316
283
|
- spec/support/http_test_server_config.ru
|
317
284
|
- spec/support/never_available_dependency.rb
|
318
285
|
- spec/support/stdout_logger.rb
|
319
|
-
- spec/support/stub_facter.rb
|
320
286
|
- spec/support/test.config
|
321
287
|
- spec/support/test.d.config
|
322
288
|
- spec/support/test.reload.config
|
data/lib/facts/loadaverage.rb
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
module LitmusPaper
|
2
|
-
module Metric
|
3
|
-
class AvailableMemory
|
4
|
-
MULTIPLIER = {
|
5
|
-
"GB" => 1024*1024*1024,
|
6
|
-
"MB" => 1024*1024,
|
7
|
-
"KB" => 1024
|
8
|
-
}
|
9
|
-
|
10
|
-
def initialize(weight, facter = Facter)
|
11
|
-
@weight = weight
|
12
|
-
@facter = facter
|
13
|
-
end
|
14
|
-
|
15
|
-
def current_health
|
16
|
-
@weight * memory_free / memory_total
|
17
|
-
end
|
18
|
-
|
19
|
-
def memory_total
|
20
|
-
return @memory_total unless @memory_total.nil?
|
21
|
-
|
22
|
-
size, scale = @facter.value('memorysize').split(' ')
|
23
|
-
@memory_total = (size.to_f * MULTIPLIER[scale]).to_i
|
24
|
-
end
|
25
|
-
|
26
|
-
def memory_free
|
27
|
-
size, scale = @facter.value('memoryfree').split(' ')
|
28
|
-
(size.to_f * MULTIPLIER[scale]).to_i
|
29
|
-
end
|
30
|
-
|
31
|
-
def to_s
|
32
|
-
"Metric::AvailableMemory(#{@weight})"
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
@@ -1,58 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe LitmusPaper::Metric::AvailableMemory do
|
4
|
-
describe "#current_health" do
|
5
|
-
it "multiplies weight by memory available" do
|
6
|
-
facter = StubFacter.new({"memorysize" => "10 GB", "memoryfree" => "5 GB"})
|
7
|
-
memory = LitmusPaper::Metric::AvailableMemory.new(50, facter)
|
8
|
-
memory.current_health.should == 25
|
9
|
-
end
|
10
|
-
|
11
|
-
it "multiplies weight by memory available when handling floating point values" do
|
12
|
-
facter = StubFacter.new({"memorysize" => "2.0 GB", "memoryfree" => "1.8 GB"})
|
13
|
-
memory = LitmusPaper::Metric::AvailableMemory.new(50, facter)
|
14
|
-
memory.current_health.should == 44
|
15
|
-
end
|
16
|
-
|
17
|
-
describe "#memory_total" do
|
18
|
-
it "is a positive integer" do
|
19
|
-
metric = LitmusPaper::Metric::AvailableMemory.new(50)
|
20
|
-
metric.memory_total.should > 1_000
|
21
|
-
end
|
22
|
-
|
23
|
-
it "handles floating point values properly" do
|
24
|
-
facter = StubFacter.new("memorysize" => "1.80 GB")
|
25
|
-
memory = LitmusPaper::Metric::AvailableMemory.new(50, facter)
|
26
|
-
memory.memory_total.should == 1932735283
|
27
|
-
end
|
28
|
-
|
29
|
-
it "is cached" do
|
30
|
-
Facter.should_receive(:value).once.and_return("10 MB")
|
31
|
-
metric = LitmusPaper::Metric::AvailableMemory.new(50)
|
32
|
-
metric.memory_total
|
33
|
-
metric.memory_total
|
34
|
-
metric.memory_total
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
describe "#memory_free" do
|
39
|
-
it "is a positive integer" do
|
40
|
-
metric = LitmusPaper::Metric::AvailableMemory.new(50)
|
41
|
-
metric.memory_free.should > 100
|
42
|
-
end
|
43
|
-
|
44
|
-
it "handles floating point values properly" do
|
45
|
-
facter = StubFacter.new("memoryfree" => "1.80 GB")
|
46
|
-
memory = LitmusPaper::Metric::AvailableMemory.new(50, facter)
|
47
|
-
memory.memory_free.should == 1932735283
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
describe "#to_s" do
|
52
|
-
it "is the name of the check and the max weight" do
|
53
|
-
metric = LitmusPaper::Metric::AvailableMemory.new(50)
|
54
|
-
metric.to_s.should == "Metric::AvailableMemory(50)"
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
data/spec/support/stub_facter.rb
DELETED
data/xinetd.conf
DELETED