kubernetes-health 3.6.0 → 3.7.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6f0b091b68d3acd2e69b0e2e259ad841eef9b5030ae7f7a8a404f7d0535722c7
4
- data.tar.gz: 2ab614dc570e2b8202533101566a4eb0f6aca71ad2490d27ac10d4739e9cc322
3
+ metadata.gz: a53b0ea476aa3faef08ebb62fd3b7e9a625881fc8177b17d612625b44a220424
4
+ data.tar.gz: d031a5233193abb0da1b5fd2ec00acf253e3b5ea2711ad547cbed131ac0be223
5
5
  SHA512:
6
- metadata.gz: 26068d438952f640c22b9e7ce3d416aeec53fd32bec73013de08c4037ad1183619dd13cd8f23fe1561d2a57f191272a895138b9cb0279bc90fa41cba309d8d2a
7
- data.tar.gz: 5c89c1531a8f10b858ba3bcd7626fe7d34fc308bde57bb0ba56fbd26e45e85b50caa72332186e4ce2e04c4e50a17c26226dabb0a7d13738eea02acdd9805491f
6
+ metadata.gz: cbf4b8efc0b5114eab92e2cb718e94f2f4cae89986e95f3bb8435ab4dc322401718a7d0a3398deec062e6ba5469a0bda5ad9a03f748f872707ae1baa9483a1c4
7
+ data.tar.gz: f4fffaa2f5a1a5eed2e5266a81361207dd4d16b8723489188ee535ad0a7e514b5c5958ccca731f27072aad7dab013a517cf228cbcfd356b8947199cf90ba9a24
@@ -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', '~> 0.9.0'
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
- @sidekiq_metrics = sidekiq_metrics
16
+ sidekiq_metrics = generate_sidekiq_metrics
17
17
 
18
18
  if ::Kubernetes::Health::Config.response_format == 'json'
19
- content = @sidekiq_metrics.to_json
19
+ content = sidekiq_metrics.to_json
20
20
  else
21
- prometheus_registry.get(:sidekiq_capacity).set({}, @sidekiq_metrics[:sidekiq_capacity])
22
- prometheus_registry.get(:sidekiq_busy).set({}, @sidekiq_metrics[:sidekiq_busy])
23
- prometheus_registry.get(:sidekiq_usage).set({}, @sidekiq_metrics[:sidekiq_usage])
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 prometheus_registry
35
- return @prometheus_registry if @prometheus_registry
36
-
37
- @prometheus_registry = Prometheus::Client.registry
38
- @prometheus_registry.gauge(:sidekiq_capacity, 'Sidekiq Threads Number', index: 0)
39
- @prometheus_registry.gauge(:sidekiq_busy, 'Sidekiq Busy Threads', index: 0)
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 sidekiq_metrics
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 = {
@@ -1,5 +1,5 @@
1
1
  module Kubernetes
2
2
  module Health
3
- VERSION = '3.6.0'.freeze
3
+ VERSION = '3.7.1'.freeze
4
4
  end
5
5
  end
@@ -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 == 0 ? ::Kubernetes::Health::Config.live_if.call : ::Kubernetes::Health::Config.live_if.call(req.params)
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 == 0 ? ::Kubernetes::Health::Config.ready_if.call : ::Kubernetes::Health::Config.ready_if.call(req.params)
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 = include_puma_key_prefix(include_usage(merge_worker_status_if_needed(@launcher.stats))).to_json
32
+ content = puma_status_json(extended_puma_stats)
32
33
  else
33
- @parser.parse include_usage(merge_worker_status_if_needed(@launcher.stats))
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
- def merge_worker_status_if_needed(stats)
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
- merded_stats[:puma_started_at] = stats[:puma_started_at]
54
- merded_stats[:worker_status] = stats[:worker_status]
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 include_usage(stats)
59
- if stats.is_a?(String)
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 = false)
7
- register_default_kubernetes
8
- register_clustered_kubernetes if clustered
6
+ def initialize(clustered: false)
7
+ register_default_metrics
8
+ register_clustered_metrics if clustered
9
9
  end
10
10
 
11
- def parse(stats, labels = {})
12
- 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'
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 register_clustered_kubernetes
22
- registry.gauge(:puma_booted_workers, 'Number of booted workers').set({}, 1)
23
- registry.gauge(:puma_old_workers, 'Number of old workers').set({}, 0)
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 register_default_kubernetes
27
- registry.gauge(:puma_backlog, 'Number of established but unaccepted connections in the backlog', index: 0)
28
- registry.gauge(:puma_running, 'Number of running worker threads', index: 0)
29
- registry.gauge(:puma_pool_capacity, 'Number of allocatable worker threads', index: 0)
30
- registry.gauge(:puma_max_threads, 'Maximum number of worker threads', index: 0)
31
- registry.gauge(:puma_workers, 'Number of configured workers').set({}, 1)
32
- registry.gauge(:puma_usage, 'Result of (1 - puma_pool_capacity/puma_max_threads)', index: 0)
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(labels, value)
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.6.0
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-04-13 00:00:00.000000000 Z
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: 0.9.0
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: 0.9.0
96
+ version: '1.0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: puma
99
99
  requirement: !ruby/object:Gem::Requirement