kubernetes-health 3.6.0 → 3.7.1
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 +4 -4
- data/kubernetes-health.gemspec +1 -1
- data/lib/kubernetes/health/rack_on_sidekiq.rb +13 -14
- data/lib/kubernetes/health/version.rb +1 -1
- data/lib/puma/kubernetes/app.rb +43 -23
- data/lib/puma/kubernetes/parser.rb +43 -18
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a53b0ea476aa3faef08ebb62fd3b7e9a625881fc8177b17d612625b44a220424
|
4
|
+
data.tar.gz: d031a5233193abb0da1b5fd2ec00acf253e3b5ea2711ad547cbed131ac0be223
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cbf4b8efc0b5114eab92e2cb718e94f2f4cae89986e95f3bb8435ab4dc322401718a7d0a3398deec062e6ba5469a0bda5ad9a03f748f872707ae1baa9483a1c4
|
7
|
+
data.tar.gz: f4fffaa2f5a1a5eed2e5266a81361207dd4d16b8723489188ee535ad0a7e514b5c5958ccca731f27072aad7dab013a517cf228cbcfd356b8947199cf90ba9a24
|
data/kubernetes-health.gemspec
CHANGED
@@ -31,6 +31,6 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.add_development_dependency "rspec"
|
32
32
|
spec.add_dependency "rack"
|
33
33
|
spec.add_dependency "rails"
|
34
|
-
spec.add_runtime_dependency 'prometheus-client', '~>
|
34
|
+
spec.add_runtime_dependency 'prometheus-client', '~> 1.0'
|
35
35
|
spec.add_runtime_dependency 'puma'
|
36
36
|
end
|
@@ -13,14 +13,15 @@ module Kubernetes
|
|
13
13
|
when Kubernetes::Health::Config.route_metrics
|
14
14
|
http_code = 200
|
15
15
|
|
16
|
-
|
16
|
+
sidekiq_metrics = generate_sidekiq_metrics
|
17
17
|
|
18
18
|
if ::Kubernetes::Health::Config.response_format == 'json'
|
19
|
-
content =
|
19
|
+
content = sidekiq_metrics.to_json
|
20
20
|
else
|
21
|
-
prometheus_registry
|
22
|
-
prometheus_registry.get(:
|
23
|
-
prometheus_registry.get(:
|
21
|
+
prometheus_registry = generate_prometheus_registry
|
22
|
+
prometheus_registry.get(:sidekiq_capacity).set({}, sidekiq_metrics[:sidekiq_capacity])
|
23
|
+
prometheus_registry.get(:sidekiq_busy).set({}, sidekiq_metrics[:sidekiq_busy])
|
24
|
+
prometheus_registry.get(:sidekiq_usage).set({}, sidekiq_metrics[:sidekiq_usage])
|
24
25
|
content = Prometheus::Client::Formats::Text.marshal(prometheus_registry)
|
25
26
|
end
|
26
27
|
else
|
@@ -31,17 +32,15 @@ module Kubernetes
|
|
31
32
|
[http_code, type, [content]]
|
32
33
|
end
|
33
34
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
@prometheus_registry.gauge(:sidekiq_usage, 'Result of sidekiq_busy/sidekiq_capacity', index: 0)
|
41
|
-
@prometheus_registry
|
35
|
+
def generate_prometheus_registry
|
36
|
+
prometheus_registry = Prometheus::Client.registry
|
37
|
+
prometheus_registry.gauge(:sidekiq_capacity, 'Sidekiq Threads Number', index: 0)
|
38
|
+
prometheus_registry.gauge(:sidekiq_busy, 'Sidekiq Busy Threads', index: 0)
|
39
|
+
prometheus_registry.gauge(:sidekiq_usage, 'Result of sidekiq_busy/sidekiq_capacity', index: 0)
|
40
|
+
prometheus_registry
|
42
41
|
end
|
43
42
|
|
44
|
-
def
|
43
|
+
def generate_sidekiq_metrics
|
45
44
|
sidekiq_info = Sidekiq::ProcessSet.new.to_a.filter { |p| p.identity == Sidekiq.options[:identity] }
|
46
45
|
|
47
46
|
stats = {
|
data/lib/puma/kubernetes/app.rb
CHANGED
@@ -9,7 +9,7 @@ module Puma
|
|
9
9
|
def initialize(launcher)
|
10
10
|
@launcher = launcher
|
11
11
|
clustered = (@launcher.options[:workers] || 0) > 0
|
12
|
-
@parser = Parser.new clustered
|
12
|
+
@parser = Parser.new(clustered: clustered)
|
13
13
|
end
|
14
14
|
|
15
15
|
def call(_env)
|
@@ -18,25 +18,26 @@ module Puma
|
|
18
18
|
type = {}
|
19
19
|
content = ''
|
20
20
|
type = ::Kubernetes::Health::Config.response_format == 'json' ? { 'Content-Type' => 'application/json' } : { 'Content-Type' => 'text/plain' }
|
21
|
+
extended_puma_stats = generate_extended_puma_stats
|
21
22
|
case req.path_info
|
22
23
|
when ::Kubernetes::Health::Config.route_liveness
|
23
|
-
i_am_live = ::Kubernetes::Health::Config.live_if.arity
|
24
|
-
http_code = i_am_live ? 200 : 503
|
24
|
+
i_am_live = ::Kubernetes::Health::Config.live_if.arity.zero? ? ::Kubernetes::Health::Config.live_if.call : ::Kubernetes::Health::Config.live_if.call(req.params)
|
25
|
+
http_code = puma_already_started?(extended_puma_stats) && i_am_live ? 200 : 503
|
25
26
|
when ::Kubernetes::Health::Config.route_readiness
|
26
|
-
i_am_ready = ::Kubernetes::Health::Config.ready_if.arity
|
27
|
-
http_code = i_am_ready ? 200 : 503
|
27
|
+
i_am_ready = ::Kubernetes::Health::Config.ready_if.arity.zero? ? ::Kubernetes::Health::Config.ready_if.call : ::Kubernetes::Health::Config.ready_if.call(req.params)
|
28
|
+
http_code = puma_already_started?(extended_puma_stats) && i_am_ready ? 200 : 503
|
28
29
|
when ::Kubernetes::Health::Config.route_metrics
|
29
30
|
http_code = 200
|
30
31
|
if ::Kubernetes::Health::Config.response_format == 'json'
|
31
|
-
content =
|
32
|
+
content = puma_status_json(extended_puma_stats)
|
32
33
|
else
|
33
|
-
|
34
|
+
prometheus_parse_status!(extended_puma_stats)
|
34
35
|
content = Prometheus::Client::Formats::Text.marshal(Prometheus::Client.registry)
|
35
36
|
end
|
36
37
|
else
|
37
38
|
http_code = 404
|
38
39
|
end
|
39
|
-
rescue => e
|
40
|
+
rescue StandardError => e
|
40
41
|
puts e.message
|
41
42
|
puts e.backtrace.join("\n")
|
42
43
|
http_code = 500
|
@@ -46,33 +47,52 @@ module Puma
|
|
46
47
|
[http_code, type, [content]]
|
47
48
|
end
|
48
49
|
|
49
|
-
|
50
|
-
return stats unless stats[:worker_status]
|
50
|
+
private
|
51
51
|
|
52
|
+
def prometheus_parse_status!(extended_puma_stats)
|
53
|
+
@parser.parse(extended_puma_stats)
|
54
|
+
end
|
55
|
+
|
56
|
+
def generate_extended_puma_stats
|
57
|
+
puma_stats = @launcher.stats
|
58
|
+
# On puma <= 4 puma_stats is a String
|
59
|
+
puma_stats = JSON.parse(puma_stats, symbolize_names: true) unless puma_stats.is_a?(Hash)
|
60
|
+
# Including usage stats.
|
61
|
+
puma_stats = merge_worker_status(puma_stats) if puma_stats[:worker_status].present?
|
62
|
+
puma_stats[:usage] = (1 - puma_stats[:pool_capacity].to_f / puma_stats[:max_threads]).round(2)
|
63
|
+
puma_stats
|
64
|
+
end
|
65
|
+
|
66
|
+
def merge_worker_status(stats)
|
52
67
|
merded_stats = stats[:worker_status].map { |ws| ws[:last_status] }.inject({}) { |sum, hash| sum.merge(hash) { |_key, val1, val2| val1+val2 } }
|
53
|
-
|
54
|
-
|
68
|
+
stats.each_key do |k|
|
69
|
+
merded_stats[k] = stats[k]
|
70
|
+
end
|
71
|
+
|
55
72
|
merded_stats
|
56
73
|
end
|
57
74
|
|
58
|
-
def
|
59
|
-
|
60
|
-
# puma <= 4.
|
61
|
-
stats = JSON.parse(stats)
|
62
|
-
else
|
63
|
-
# Puma >=5 uses symbol.
|
64
|
-
stats = JSON.parse(stats.to_json)
|
65
|
-
end
|
66
|
-
stats['usage'] = (1 - stats['pool_capacity'].to_f / stats['max_threads']).round(2)
|
67
|
-
stats
|
75
|
+
def puma_status_json(extended_puma_stats)
|
76
|
+
include_puma_key_prefix(extended_puma_stats).to_json
|
68
77
|
end
|
78
|
+
|
69
79
|
def include_puma_key_prefix(stats)
|
70
80
|
result = {}
|
71
|
-
stats.each do |k,v|
|
81
|
+
stats.each do |k, v|
|
72
82
|
result["puma_#{k}"] = v
|
73
83
|
end
|
74
84
|
result
|
75
85
|
end
|
86
|
+
|
87
|
+
def puma_already_started?(extended_puma_stats)
|
88
|
+
if extended_puma_stats[:booted_workers].present?
|
89
|
+
# Cluster Mode
|
90
|
+
extended_puma_stats[:booted_workers].positive?
|
91
|
+
else
|
92
|
+
# Single Mode
|
93
|
+
extended_puma_stats[:running].positive?
|
94
|
+
end
|
95
|
+
end
|
76
96
|
end
|
77
97
|
end
|
78
98
|
end
|
@@ -3,33 +3,58 @@ require 'prometheus/client'
|
|
3
3
|
module Puma
|
4
4
|
module Kubernetes
|
5
5
|
class Parser
|
6
|
-
def initialize(clustered
|
7
|
-
|
8
|
-
|
6
|
+
def initialize(clustered: false)
|
7
|
+
register_default_metrics
|
8
|
+
register_clustered_metrics if clustered
|
9
9
|
end
|
10
10
|
|
11
|
-
def parse(
|
12
|
-
|
13
|
-
value.each { |s| parse(s, labels.merge(index: s[
|
14
|
-
parse(value, labels) if key ==
|
11
|
+
def parse(symbol_keyed_stats, labels = {})
|
12
|
+
symbol_keyed_stats.each do |key, value|
|
13
|
+
value.each { |s| parse(s, labels.merge(index: s[:index])) } if key == :worker_status
|
14
|
+
parse(value, labels) if key == :last_status
|
15
15
|
update_metric(key, value, labels)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
19
|
private
|
20
20
|
|
21
|
-
def
|
22
|
-
registry.gauge(:puma_booted_workers,
|
23
|
-
|
21
|
+
def register_clustered_metrics
|
22
|
+
registry.gauge(:puma_booted_workers,
|
23
|
+
docstring: 'Number of booted workers')
|
24
|
+
.set(1)
|
25
|
+
registry.gauge(:puma_old_workers,
|
26
|
+
docstring: 'Number of old workers')
|
27
|
+
.set(0)
|
24
28
|
end
|
25
29
|
|
26
|
-
def
|
27
|
-
registry.gauge(:puma_backlog,
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
registry.gauge(:
|
32
|
-
|
30
|
+
def register_default_metrics # rubocop:disable Metrics/MethodLength
|
31
|
+
registry.gauge(:puma_backlog,
|
32
|
+
docstring: 'Number of established but unaccepted connections in the backlog',
|
33
|
+
labels: [:index],
|
34
|
+
preset_labels: { index: 0 })
|
35
|
+
registry.gauge(:puma_running,
|
36
|
+
docstring: 'Number of running worker threads',
|
37
|
+
labels: [:index],
|
38
|
+
preset_labels: { index: 0 })
|
39
|
+
registry.gauge(:puma_pool_capacity,
|
40
|
+
docstring: 'Number of allocatable worker threads',
|
41
|
+
labels: [:index],
|
42
|
+
preset_labels: { index: 0 })
|
43
|
+
registry.gauge(:puma_max_threads,
|
44
|
+
docstring: 'Maximum number of worker threads',
|
45
|
+
labels: [:index],
|
46
|
+
preset_labels: { index: 0 })
|
47
|
+
registry.gauge(:puma_requests_count,
|
48
|
+
docstring: 'Number of processed requests',
|
49
|
+
labels: [:index],
|
50
|
+
preset_labels: { index: 0 })
|
51
|
+
registry.gauge(:puma_usage,
|
52
|
+
docstring: 'Result of (1 - puma_pool_capacity/puma_max_threads)',
|
53
|
+
labels: [:index],
|
54
|
+
preset_labels: { index: 0 })
|
55
|
+
registry.gauge(:puma_workers,
|
56
|
+
docstring: 'Number of configured workers')
|
57
|
+
.set(1)
|
33
58
|
end
|
34
59
|
|
35
60
|
def registry
|
@@ -39,7 +64,7 @@ module Puma
|
|
39
64
|
def update_metric(key, value, labels)
|
40
65
|
return if registry.get("puma_#{key}").nil?
|
41
66
|
|
42
|
-
registry.get("puma_#{key}").set(
|
67
|
+
registry.get("puma_#{key}").set(value, labels: labels)
|
43
68
|
end
|
44
69
|
end
|
45
70
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kubernetes-health
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wagner Caixeta
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-05-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
89
|
+
version: '1.0'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
96
|
+
version: '1.0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: puma
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|