philae 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/philae/collection_probe.rb +54 -0
- data/lib/philae/etcd_cluster_probe.rb +30 -0
- data/lib/philae/nsq_cluster_probe.rb +46 -0
- metadata +4 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a72261c385f330a6ca14c7ddaccd3774aa4e0e0918eb754bf757ccf16627b0db
|
4
|
+
data.tar.gz: f38b28573ee5829bcd41c9a772c074c43dff746a44b18842aab6c4cd7059bc21
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 270fd5405071f9f12369bafe35693eda220a29180107ae32c5e4aeb0ac16f8d34ad3e069c5f886695b84707512a84054fa51e94fcbfce1bcb904df85f9c78e3c
|
7
|
+
data.tar.gz: 80543e2c7e06be18b3569c50ba373fe5c071d290f1f7ad51ba65af41033c32b62f324b05cffdadd230f8f87ca342888e61218cb1df3d5dd58ff70377a5d66827
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Philae
|
2
|
+
class CollectionProbe
|
3
|
+
def initialize(*args)
|
4
|
+
raise ArgumentError, "can't be instantiate, use specialized class"
|
5
|
+
end
|
6
|
+
|
7
|
+
def probes
|
8
|
+
raise ArgumentError, 'specialized class should implement :probes'
|
9
|
+
end
|
10
|
+
|
11
|
+
def check
|
12
|
+
results = []
|
13
|
+
result_queue = Queue.new
|
14
|
+
probes.each do |probe|
|
15
|
+
Thread.new do
|
16
|
+
begin
|
17
|
+
result = probe.check
|
18
|
+
rescue StandardError => e
|
19
|
+
result = {
|
20
|
+
healthy: false,
|
21
|
+
error: "probe #{probe.name} check failed: #{e.class} - #{e.message}",
|
22
|
+
}
|
23
|
+
end
|
24
|
+
result[:probe] = probe
|
25
|
+
result_queue.push result
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
loop do
|
30
|
+
results.push result_queue.pop
|
31
|
+
break if results.count == probes.length
|
32
|
+
end
|
33
|
+
|
34
|
+
failed_results = results.select do |result|
|
35
|
+
result[:healthy] == false
|
36
|
+
end
|
37
|
+
|
38
|
+
error = failed_results.map do |result|
|
39
|
+
msg = "#{result[:probe].name}: #{result[:comment]} "
|
40
|
+
msg += result[:code] if result[:code]
|
41
|
+
msg += result[:error] if result[:error]
|
42
|
+
next msg
|
43
|
+
end.join(', ')
|
44
|
+
|
45
|
+
if failed_results.count == probes.count
|
46
|
+
return { healthy: false, comment: "All #{name} nodes are down", error: error }
|
47
|
+
elsif failed_results.count > 0
|
48
|
+
return { healthy: true, comment: "#{failed_results.count} #{name} nodes are down: #{error}" }
|
49
|
+
else
|
50
|
+
return { healthy: true, comment: '' }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require_relative 'collection_probe'
|
2
|
+
require_relative 'etcd_probe'
|
3
|
+
|
4
|
+
module Philae
|
5
|
+
class EtcdClusterProbe < CollectionProbe
|
6
|
+
attr_reader :name, :etcd_probes
|
7
|
+
|
8
|
+
# @param [Integer] read_timeout Timeout in second for the HTTP request
|
9
|
+
def initialize(name, endpoints, read_timeout: 1, cacert: nil, ssl_cert: nil, ssl_key: nil)
|
10
|
+
raise ArgumentError, 'empty endpoints' if endpoints.nil? || endpoints.empty?
|
11
|
+
|
12
|
+
@etcd_probes = endpoints.map do |endpoint|
|
13
|
+
endpoint_uri = URI(endpoint)
|
14
|
+
next EtcdProbe.new(
|
15
|
+
"#{name}-#{endpoint_uri.host}-#{endpoint_uri.port}",
|
16
|
+
endpoint_uri.host,
|
17
|
+
endpoint_uri.port,
|
18
|
+
read_timeout: read_timeout, cacert: cacert,
|
19
|
+
ssl_cert: ssl_cert, ssl_key: ssl_key,
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
@name = name
|
24
|
+
end
|
25
|
+
|
26
|
+
def probes
|
27
|
+
return @etcd_probes
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require_relative 'collection_probe.rb'
|
2
|
+
require_relative 'nsq_probe.rb'
|
3
|
+
|
4
|
+
module Philae
|
5
|
+
class NSQClusterProbe < CollectionProbe
|
6
|
+
DEFAULT_HTTP_PORT = 4152
|
7
|
+
|
8
|
+
attr_reader :name, :nsq_probes
|
9
|
+
|
10
|
+
def self.new_from_env(name)
|
11
|
+
if ENV['NSQD_HOSTS'].nil? || ENV['NSQD_HTTP_PORT'].nil?
|
12
|
+
raise ArgumentError, 'no NSQD_HOSTS and NSQD_HTTP_PORT defined'
|
13
|
+
end
|
14
|
+
|
15
|
+
tls_context = nil
|
16
|
+
if ENV['NSQD_TLS'] == 'true'
|
17
|
+
tls_context = {
|
18
|
+
cert: ENV['NSQD_TLS_CERT'],
|
19
|
+
key: ENV['NSQD_TLS_KEY'],
|
20
|
+
ca: ENV['NSQD_TLS_CACERT'],
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
http_hosts = ENV['NSQD_HOSTS'].split(',').map do |host|
|
25
|
+
host.split(':')[0] + ":#{ENV['NSQD_HTTP_PORT']}"
|
26
|
+
end
|
27
|
+
|
28
|
+
new(name, http_hosts, tls_context)
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize(name, hosts, tls_context = nil)
|
32
|
+
raise ArgumentError, 'should have at least one host' if hosts.nil? || hosts.empty?
|
33
|
+
|
34
|
+
@name = name
|
35
|
+
@nsq_probes = hosts.map do |hostport|
|
36
|
+
host, port = hostport.split(':')
|
37
|
+
port = DEFAULT_HTTP_PORT if port.nil?
|
38
|
+
next Philae::NSQProbe.new("#{name}-#{host}-#{port}", host, port, tls_context)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def probes
|
43
|
+
@nsq_probes
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: philae
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- leo@scalingo.com
|
@@ -89,10 +89,13 @@ extensions: []
|
|
89
89
|
extra_rdoc_files: []
|
90
90
|
files:
|
91
91
|
- lib/philae.rb
|
92
|
+
- lib/philae/collection_probe.rb
|
92
93
|
- lib/philae/docker_probe.rb
|
94
|
+
- lib/philae/etcd_cluster_probe.rb
|
93
95
|
- lib/philae/etcd_probe.rb
|
94
96
|
- lib/philae/http_probe.rb
|
95
97
|
- lib/philae/mongo_probe.rb
|
98
|
+
- lib/philae/nsq_cluster_probe.rb
|
96
99
|
- lib/philae/nsq_probe.rb
|
97
100
|
- lib/philae/pgsql_probe.rb
|
98
101
|
- lib/philae/philae_probe.rb
|