litmus_paper 1.5.0 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +2 -3
- data/README.md +6 -1
- data/lib/litmus_paper.rb +2 -0
- data/lib/litmus_paper/configuration_file.rb +10 -0
- data/lib/litmus_paper/metric/socket_utilization.rb +48 -0
- data/lib/litmus_paper/metric/tcp_socket_utilization.rb +27 -0
- data/lib/litmus_paper/metric/unix_socket_utilization.rb +17 -31
- data/lib/litmus_paper/version.rb +1 -1
- data/litmus_paper.gemspec +1 -0
- data/spec/litmus_paper/app_spec.rb +2 -2
- data/spec/litmus_paper/metric/tcp_socket_utilization_spec.rb +59 -0
- data/spec/litmus_paper/metric/unix_socket_utilization_spec.rb +16 -9
- metadata +10 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 90d66e516c05b1928cca5f319524f41b6578b885
|
4
|
+
data.tar.gz: a6f9aed4e14be636749bfa4536bc295044481704
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18c970635472e70bb906be5f2be7fa126dcb6c134ca0a5a606239da7f25a0ec24f4aa6f0f36acf9cbdbff07dcdf66c04397e85b947d723e4f1561f3577fe03ef
|
7
|
+
data.tar.gz: 701a21b78fbd8b7e528e074bf1d18e8131b1f4d60a807d4c1fc781fc9afcab2efe3bcb3d9d4a1bf36c2aeeec77fae8d47c8e60bec6d12840b3ce307a180b778d
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -176,7 +176,12 @@ Here are all the types of checks currently implemented:
|
|
176
176
|
* weight (0-100)
|
177
177
|
* timeout (defaults to 5s)
|
178
178
|
|
179
|
-
- `
|
179
|
+
- `tcp_socket_utilization` (`Metric::TcpSocketUtilization`): Compares the number of active, queued requests against the maximum number of expected connections, [see](lib/litmus_paper/metric/socket_utilization.rb) for the implementation of the algorithm.
|
180
|
+
* weight (0-100)
|
181
|
+
* address (IP:port combination, e.g. `0.0.0.0:8192`)
|
182
|
+
* maxconn (maximum number of concurrent connection the server backing the socket is supposed to handle)
|
183
|
+
|
184
|
+
- `unix_socket_utilization` (`Metric::UnixSocketUtilization`): Compares the number of active, queued requests against the maximum number of expected connections, [see](lib/litmus_paper/metric/socket_utilization.rb) for the implementation of the algorithm.
|
180
185
|
* weight (0-100)
|
181
186
|
* socket_path (path on the filesystem where the socket is located)
|
182
187
|
* maxconn (maximum number of concurrent connection the server backing the socket is supposed to handle)
|
data/lib/litmus_paper.rb
CHANGED
@@ -31,6 +31,8 @@ require 'litmus_paper/metric/cpu_load'
|
|
31
31
|
require 'litmus_paper/metric/haproxy_backends_health'
|
32
32
|
require 'litmus_paper/metric/internet_health'
|
33
33
|
require 'litmus_paper/metric/script'
|
34
|
+
require 'litmus_paper/metric/socket_utilization'
|
35
|
+
require 'litmus_paper/metric/tcp_socket_utilization'
|
34
36
|
require 'litmus_paper/metric/unix_socket_utilization'
|
35
37
|
require 'litmus_paper/service'
|
36
38
|
require 'litmus_paper/status_file'
|
@@ -84,6 +84,16 @@ module LitmusPaper
|
|
84
84
|
domain_socket = dep_config.delete(:domain_socket)
|
85
85
|
cluster = dep_config.delete(:cluster)
|
86
86
|
Metric::HaproxyBackendsHealth.new(weight, domain_socket, cluster, check_config)
|
87
|
+
when :tcp_socket_utilization
|
88
|
+
weight = check_config.delete(:weight)
|
89
|
+
address = check_config.delete(:address)
|
90
|
+
maxconn = check_config.delete(:maxconn)
|
91
|
+
Metric::TcpSocketUtilization.new(weight, address, maxconn)
|
92
|
+
when :unix_socket_utilization
|
93
|
+
weight = check_config.delete(:weight)
|
94
|
+
socket_path = check_config.delete(:socket_path)
|
95
|
+
maxconn = check_config.delete(:maxconn)
|
96
|
+
Metric::UnixSocketUtilization.new(weight, socket_path, maxconn)
|
87
97
|
end
|
88
98
|
end
|
89
99
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'raindrops'
|
2
|
+
|
3
|
+
module LitmusPaper
|
4
|
+
module Metric
|
5
|
+
class SocketUtilization
|
6
|
+
attr_reader :weight, :maxconn
|
7
|
+
|
8
|
+
def initialize(weight, maxconn)
|
9
|
+
@weight = weight
|
10
|
+
@maxconn = maxconn
|
11
|
+
end
|
12
|
+
|
13
|
+
def current_health
|
14
|
+
stats = _stats
|
15
|
+
|
16
|
+
if stats.queued == 0
|
17
|
+
return weight
|
18
|
+
end
|
19
|
+
|
20
|
+
[
|
21
|
+
weight - (
|
22
|
+
(weight * stats.active.to_f) / (3 * maxconn.to_f) +
|
23
|
+
(2 * weight * stats.queued.to_f) / (3 * maxconn.to_f)
|
24
|
+
),
|
25
|
+
1
|
26
|
+
].max
|
27
|
+
end
|
28
|
+
|
29
|
+
def stats
|
30
|
+
stats = _stats
|
31
|
+
|
32
|
+
{
|
33
|
+
:socket_active => stats.active,
|
34
|
+
:socket_queued => stats.queued,
|
35
|
+
:socket_utilization => ((stats.queued / maxconn.to_f) * 100).round,
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def _stats
|
40
|
+
raise "Sub-classes must implement _stats"
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_s
|
44
|
+
raise "Sub-classes must implement to_s"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'raindrops'
|
2
|
+
|
3
|
+
module LitmusPaper
|
4
|
+
module Metric
|
5
|
+
class TcpSocketUtilization < SocketUtilization
|
6
|
+
attr_reader :address
|
7
|
+
|
8
|
+
def initialize(weight, address, maxconn)
|
9
|
+
super(weight, maxconn)
|
10
|
+
@address = address
|
11
|
+
end
|
12
|
+
|
13
|
+
def _stats
|
14
|
+
Raindrops::Linux.tcp_listener_stats([address])[address]
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
current_stats = stats
|
19
|
+
active = current_stats[:socket_active]
|
20
|
+
queued = current_stats[:socket_queued]
|
21
|
+
utilization = current_stats[:socket_utilization]
|
22
|
+
|
23
|
+
"Metric::TcpSocketUtilitization(weight: #{weight}, maxconn: #{maxconn}, active: #{active}, queued: #{queued}, utilization: #{utilization}, address: #{address})"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -2,46 +2,32 @@ require 'raindrops'
|
|
2
2
|
|
3
3
|
module LitmusPaper
|
4
4
|
module Metric
|
5
|
-
class
|
5
|
+
class UnixSocketUtilization < SocketUtilization
|
6
|
+
attr_reader :socket_path
|
7
|
+
|
6
8
|
def initialize(weight, socket_path, maxconn)
|
7
|
-
|
9
|
+
super(weight, maxconn)
|
8
10
|
@socket_path = socket_path
|
9
|
-
@maxconn = maxconn
|
10
|
-
end
|
11
|
-
|
12
|
-
def current_health
|
13
|
-
stats = _stats
|
14
|
-
|
15
|
-
if stats.queued == 0
|
16
|
-
return @weight
|
17
|
-
end
|
18
|
-
|
19
|
-
[
|
20
|
-
@weight - (
|
21
|
-
(@weight * stats.active.to_f) / (3 * @maxconn.to_f) +
|
22
|
-
(2 * @weight * stats.queued.to_f) / (3 * @maxconn.to_f)
|
23
|
-
),
|
24
|
-
1
|
25
|
-
].max
|
26
|
-
end
|
27
|
-
|
28
|
-
def stats
|
29
|
-
stats = _stats
|
30
|
-
|
31
|
-
{
|
32
|
-
:socket_active => stats.active,
|
33
|
-
:socket_queued => stats.queued,
|
34
|
-
:socket_utilization => ((stats.queued / @maxconn.to_f) * 100).round,
|
35
|
-
}
|
36
11
|
end
|
37
12
|
|
38
13
|
def _stats
|
39
|
-
Raindrops::Linux.unix_listener_stats([
|
14
|
+
Raindrops::Linux.unix_listener_stats([socket_path])[socket_path]
|
40
15
|
end
|
41
16
|
|
42
17
|
def to_s
|
43
|
-
|
18
|
+
current_stats = stats
|
19
|
+
active = current_stats[:socket_active]
|
20
|
+
queued = current_stats[:socket_queued]
|
21
|
+
utilization = current_stats[:socket_utilization]
|
22
|
+
|
23
|
+
"Metric::UnixSocketUtilization(weight: #{weight}, maxconn: #{maxconn}, active: #{active}, queued: #{queued}, utilization: #{utilization}, path: #{socket_path})"
|
44
24
|
end
|
45
25
|
end
|
26
|
+
|
27
|
+
def self.const_missing(const_name)
|
28
|
+
super unless const_name == :UnixSocketUtilitization
|
29
|
+
warn "`LitmusPaper::Metric::UnixSocketUtilitization` has been deprecated. Use `LitmusPaper::Metric::UnixSocketUtilization` instead."
|
30
|
+
UnixSocketUtilization
|
31
|
+
end
|
46
32
|
end
|
47
33
|
end
|
data/lib/litmus_paper/version.rb
CHANGED
data/litmus_paper.gemspec
CHANGED
@@ -8,6 +8,7 @@ Gem::Specification.new do |gem|
|
|
8
8
|
gem.description = %q{Backend health tester for HA Services}
|
9
9
|
gem.summary = %q{Backend health tester for HA Services, partner project of big_brother}
|
10
10
|
gem.homepage = "https://github.com/braintree/litmus_paper"
|
11
|
+
gem.licenses = ['MIT']
|
11
12
|
|
12
13
|
gem.files = `git ls-files`.split($\)
|
13
14
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
@@ -461,14 +461,14 @@ describe LitmusPaper::App do
|
|
461
461
|
|
462
462
|
describe "GET /:service/metrics" do
|
463
463
|
it "returns the forced health value for a healthy service" do
|
464
|
-
LitmusPaper::Metric::
|
464
|
+
LitmusPaper::Metric::UnixSocketUtilization.any_instance.stub(
|
465
465
|
:_stats => OpenStruct.new({:queued => 7, :active => 10}),
|
466
466
|
)
|
467
467
|
LitmusPaper::Metric::CPULoad.any_instance.stub(
|
468
468
|
:load_average => 0.1
|
469
469
|
)
|
470
470
|
cpu_load = LitmusPaper::Metric::CPULoad.new(50)
|
471
|
-
socket_utilization = LitmusPaper::Metric::
|
471
|
+
socket_utilization = LitmusPaper::Metric::UnixSocketUtilization.new(100, '/var/run/foo.sock', 10)
|
472
472
|
internet_health = LitmusPaper::Metric::InternetHealth.new(100, [
|
473
473
|
"127.0.0.1:3000",
|
474
474
|
"127.0.0.1:3001",
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe LitmusPaper::Metric::TcpSocketUtilization do
|
4
|
+
describe "#current_health" do
|
5
|
+
it "returns supplied weight when there is no queued request" do
|
6
|
+
LitmusPaper::Metric::TcpSocketUtilization.any_instance.stub(
|
7
|
+
:_stats => OpenStruct.new({:queued => 0, :active => 10}),
|
8
|
+
)
|
9
|
+
health = LitmusPaper::Metric::TcpSocketUtilization.new(
|
10
|
+
100,
|
11
|
+
'127.0.0.1:8123',
|
12
|
+
10
|
13
|
+
).current_health
|
14
|
+
health.should == 100
|
15
|
+
end
|
16
|
+
|
17
|
+
it "adjusts weight based on queued requests" do
|
18
|
+
LitmusPaper::Metric::TcpSocketUtilization.any_instance.stub(
|
19
|
+
:_stats => OpenStruct.new({:queued => 7, :active => 10}),
|
20
|
+
)
|
21
|
+
health = LitmusPaper::Metric::TcpSocketUtilization.new(
|
22
|
+
100,
|
23
|
+
'127.0.0.1:8123',
|
24
|
+
10
|
25
|
+
).current_health
|
26
|
+
health.to_i.should == 20
|
27
|
+
end
|
28
|
+
|
29
|
+
it "sets weight to 1 when queued requests is more than maxconn" do
|
30
|
+
LitmusPaper::Metric::TcpSocketUtilization.any_instance.stub(
|
31
|
+
:_stats => OpenStruct.new({:queued => 11, :active => 10}),
|
32
|
+
)
|
33
|
+
health = LitmusPaper::Metric::TcpSocketUtilization.new(
|
34
|
+
100,
|
35
|
+
'127.0.0.1:8123',
|
36
|
+
10
|
37
|
+
).current_health
|
38
|
+
health.should == 1
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "#stats" do
|
43
|
+
it "reports metrics" do
|
44
|
+
LitmusPaper::Metric::TcpSocketUtilization.any_instance.stub(
|
45
|
+
:_stats => OpenStruct.new({:queued => 7, :active => 10}),
|
46
|
+
)
|
47
|
+
metric = LitmusPaper::Metric::TcpSocketUtilization.new(
|
48
|
+
100,
|
49
|
+
'127.0.0.1:8123',
|
50
|
+
10
|
51
|
+
)
|
52
|
+
metric.stats.should == {
|
53
|
+
:socket_active => 10,
|
54
|
+
:socket_queued => 7,
|
55
|
+
:socket_utilization => 70,
|
56
|
+
}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -1,12 +1,19 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe LitmusPaper::Metric::
|
3
|
+
describe LitmusPaper::Metric::UnixSocketUtilization do
|
4
|
+
describe "mispelled const compatibility is retained" do
|
5
|
+
it 'compatibility is retained' do
|
6
|
+
LitmusPaper::Metric::UnixSocketUtilitization.should ==
|
7
|
+
LitmusPaper::Metric::UnixSocketUtilization
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
4
11
|
describe "#current_health" do
|
5
12
|
it "returns supplied weight when there is no queued request" do
|
6
|
-
LitmusPaper::Metric::
|
13
|
+
LitmusPaper::Metric::UnixSocketUtilization.any_instance.stub(
|
7
14
|
:_stats => OpenStruct.new({:queued => 0, :active => 10}),
|
8
15
|
)
|
9
|
-
health = LitmusPaper::Metric::
|
16
|
+
health = LitmusPaper::Metric::UnixSocketUtilization.new(
|
10
17
|
100,
|
11
18
|
'/var/run/foo.sock',
|
12
19
|
10
|
@@ -15,10 +22,10 @@ describe LitmusPaper::Metric::UnixSocketUtilitization do
|
|
15
22
|
end
|
16
23
|
|
17
24
|
it "adjusts weight based on queued requests" do
|
18
|
-
LitmusPaper::Metric::
|
25
|
+
LitmusPaper::Metric::UnixSocketUtilization.any_instance.stub(
|
19
26
|
:_stats => OpenStruct.new({:queued => 7, :active => 10}),
|
20
27
|
)
|
21
|
-
health = LitmusPaper::Metric::
|
28
|
+
health = LitmusPaper::Metric::UnixSocketUtilization.new(
|
22
29
|
100,
|
23
30
|
'/var/run/foo.sock',
|
24
31
|
10
|
@@ -27,10 +34,10 @@ describe LitmusPaper::Metric::UnixSocketUtilitization do
|
|
27
34
|
end
|
28
35
|
|
29
36
|
it "sets weight to 1 when queued requests is more than maxconn" do
|
30
|
-
LitmusPaper::Metric::
|
37
|
+
LitmusPaper::Metric::UnixSocketUtilization.any_instance.stub(
|
31
38
|
:_stats => OpenStruct.new({:queued => 11, :active => 10}),
|
32
39
|
)
|
33
|
-
health = LitmusPaper::Metric::
|
40
|
+
health = LitmusPaper::Metric::UnixSocketUtilization.new(
|
34
41
|
100,
|
35
42
|
'/var/run/foo.sock',
|
36
43
|
10
|
@@ -41,10 +48,10 @@ describe LitmusPaper::Metric::UnixSocketUtilitization do
|
|
41
48
|
|
42
49
|
describe "#stats" do
|
43
50
|
it "reports metrics" do
|
44
|
-
LitmusPaper::Metric::
|
51
|
+
LitmusPaper::Metric::UnixSocketUtilization.any_instance.stub(
|
45
52
|
:_stats => OpenStruct.new({:queued => 7, :active => 10}),
|
46
53
|
)
|
47
|
-
metric = LitmusPaper::Metric::
|
54
|
+
metric = LitmusPaper::Metric::UnixSocketUtilization.new(
|
48
55
|
100,
|
49
56
|
'/var/run/foo.sock',
|
50
57
|
10
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: litmus_paper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Braintreeps
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sinatra
|
@@ -189,6 +189,8 @@ files:
|
|
189
189
|
- lib/litmus_paper/metric/haproxy_backends_health.rb
|
190
190
|
- lib/litmus_paper/metric/internet_health.rb
|
191
191
|
- lib/litmus_paper/metric/script.rb
|
192
|
+
- lib/litmus_paper/metric/socket_utilization.rb
|
193
|
+
- lib/litmus_paper/metric/tcp_socket_utilization.rb
|
192
194
|
- lib/litmus_paper/metric/unix_socket_utilization.rb
|
193
195
|
- lib/litmus_paper/service.rb
|
194
196
|
- lib/litmus_paper/status_file.rb
|
@@ -216,6 +218,7 @@ files:
|
|
216
218
|
- spec/litmus_paper/metric/haproxy_backends_health_spec.rb
|
217
219
|
- spec/litmus_paper/metric/internet_health_spec.rb
|
218
220
|
- spec/litmus_paper/metric/script_spec.rb
|
221
|
+
- spec/litmus_paper/metric/tcp_socket_utilization_spec.rb
|
219
222
|
- spec/litmus_paper/metric/unix_socket_utilization_spec.rb
|
220
223
|
- spec/litmus_paper/service_spec.rb
|
221
224
|
- spec/litmus_paper/status_file_spec.rb
|
@@ -245,7 +248,8 @@ files:
|
|
245
248
|
- spec/support/test.reload.config
|
246
249
|
- spec/support/test.unicorn.config
|
247
250
|
homepage: https://github.com/braintree/litmus_paper
|
248
|
-
licenses:
|
251
|
+
licenses:
|
252
|
+
- MIT
|
249
253
|
metadata: {}
|
250
254
|
post_install_message:
|
251
255
|
rdoc_options: []
|
@@ -262,7 +266,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
262
266
|
- !ruby/object:Gem::Version
|
263
267
|
version: '0'
|
264
268
|
requirements: []
|
265
|
-
|
269
|
+
rubyforge_project:
|
270
|
+
rubygems_version: 2.5.2.1
|
266
271
|
signing_key:
|
267
272
|
specification_version: 4
|
268
273
|
summary: Backend health tester for HA Services, partner project of big_brother
|
@@ -285,6 +290,7 @@ test_files:
|
|
285
290
|
- spec/litmus_paper/metric/haproxy_backends_health_spec.rb
|
286
291
|
- spec/litmus_paper/metric/internet_health_spec.rb
|
287
292
|
- spec/litmus_paper/metric/script_spec.rb
|
293
|
+
- spec/litmus_paper/metric/tcp_socket_utilization_spec.rb
|
288
294
|
- spec/litmus_paper/metric/unix_socket_utilization_spec.rb
|
289
295
|
- spec/litmus_paper/service_spec.rb
|
290
296
|
- spec/litmus_paper/status_file_spec.rb
|