litmus_paper 1.5.0 → 1.6.0
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.
- 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
|