kubernetes-health 3.4.1 → 3.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 +4 -4
- data/README.md +28 -13
- data/Rakefile +1 -1
- data/config/initializers/enable_rack_on_sidekiq.rb +7 -0
- data/lib/kubernetes/health/config.rb +9 -0
- data/lib/kubernetes/health/rack_on_migrate.rake +3 -2
- data/lib/kubernetes/health/rack_on_sidekiq.rb +57 -0
- data/lib/kubernetes/health/version.rb +1 -1
- data/lib/puma/kubernetes/app.rb +22 -4
- metadata +8 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f0b091b68d3acd2e69b0e2e259ad841eef9b5030ae7f7a8a404f7d0535722c7
|
4
|
+
data.tar.gz: 2ab614dc570e2b8202533101566a4eb0f6aca71ad2490d27ac10d4739e9cc322
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 26068d438952f640c22b9e7ce3d416aeec53fd32bec73013de08c4037ad1183619dd13cd8f23fe1561d2a57f191272a895138b9cb0279bc90fa41cba309d8d2a
|
7
|
+
data.tar.gz: 5c89c1531a8f10b858ba3bcd7626fe7d34fc308bde57bb0ba56fbd26e45e85b50caa72332186e4ce2e04c4e50a17c26226dabb0a7d13738eea02acdd9805491f
|
data/README.md
CHANGED
@@ -1,21 +1,22 @@
|
|
1
1
|
# Kubernetes::Health
|
2
|
-
|
3
|
-
This gem allows kubernetes monitoring your app while it is running migrates and after it starts.
|
2
|
+
This gem open a HTTP port for monitoring your rails app while it is running Migrates, Sidekiq and Puma.
|
4
3
|
|
5
4
|
# Features
|
6
|
-
-
|
7
|
-
-
|
8
|
-
-
|
9
|
-
-
|
5
|
+
- Puma and Sidekiq metrics for autoscaling.
|
6
|
+
- Prometheus and JSON metrics (tested using https://github.com/zalando-incubator/kube-metrics-adapter and JSON format).
|
7
|
+
- add routes `/_readiness`, `/_liveness` on Rails Stack.
|
8
|
+
- add routes `/_readiness`, `/_liveness` and `/_metrics` as a puma plugin at another port to avoid problems when your app get busy. (code copied from `puma-metrics` gem).
|
10
9
|
- add routes `/_readiness` and `/_liveness` while `rake db:migrate` runs. (optional)
|
11
|
-
- add
|
12
|
-
|
10
|
+
- add routes `/_readiness` and `/_liveness` while `sidekiq` runs. (optional)
|
11
|
+
- add support to avoid parallel running of `rake db:migrate` while keep kubernetes waiting (PostgreSQL required).
|
12
|
+
- allow custom checks for `/_readiness` and `/_liveness`.
|
13
|
+
|
13
14
|
## Installation
|
14
15
|
|
15
16
|
Add this line to your application's Gemfile:
|
16
17
|
|
17
18
|
```ruby
|
18
|
-
gem 'kubernetes-health', '~> 3.
|
19
|
+
gem 'kubernetes-health', '~> 3.6'
|
19
20
|
```
|
20
21
|
|
21
22
|
## Enabling puma plugin
|
@@ -48,6 +49,7 @@ In Kubernetes you need to configure your deployment `readinessProbe` and `livene
|
|
48
49
|
```
|
49
50
|
|
50
51
|
Setting `failureThreshold` is import to avoid problems when app finish migrates and is starting the web process.
|
52
|
+
|
51
53
|
## Enabling monitoring while `rake db:migrate` runs
|
52
54
|
|
53
55
|
Your Dockerfile's entry script needs to run migrates before start your web app.
|
@@ -60,9 +62,22 @@ or add in your `application.rb`.
|
|
60
62
|
# default: false
|
61
63
|
Kubernetes::Health::Config.enable_rack_on_migrate = true
|
62
64
|
```
|
65
|
+
The defined port at `config/puma.rb` will be used.
|
66
|
+
|
67
|
+
## Enabling monitoring for `sidekiq`
|
68
|
+
|
69
|
+
Add `KUBERNETES_HEALTH_ENABLE_RACK_ON_SIDEKIQ=true` environment variable.
|
70
|
+
|
71
|
+
or add in your `application.rb`.
|
72
|
+
|
73
|
+
```
|
74
|
+
# default: false
|
75
|
+
Kubernetes::Health::Config.enable_rack_on_sidekiq = true
|
76
|
+
```
|
77
|
+
The defined port at `config/puma.rb` will be used.
|
63
78
|
|
64
|
-
### How `rake db:migrate` monitoring works
|
65
|
-
It will run a RACK server for `/_readiness
|
79
|
+
### How `rake db:migrate` and `sidekiq` monitoring works
|
80
|
+
It will run a RACK server for `/_readiness`, `/_liveness` and `/_metrics`.
|
66
81
|
|
67
82
|
## Avoiding migrations running in parallel and making kubernetes happy.
|
68
83
|
Rails already avoid migrations running in parallel, but it raise exceptions. This gem will just wait for other migrations without exit.
|
@@ -128,7 +143,7 @@ Kubernetes::Health::Config.response_format = 'json'
|
|
128
143
|
## Customizing requests logs
|
129
144
|
|
130
145
|
```
|
131
|
-
Kubernetes::Health::Config.request_log_callback = lambda { |req, http_code|
|
132
|
-
Rails.logger.debug "Kubernetes Health: Rack on Migrate - Request: Path: #{req.path_info} / Params: #{req.params} / HTTP Code: #{http_code}" rescue nil
|
146
|
+
Kubernetes::Health::Config.request_log_callback = lambda { |req, http_code, content|
|
147
|
+
Rails.logger.debug "Kubernetes Health: Rack on Migrate - Request: Path: #{req.path_info} / Params: #{req.params} / HTTP Code: #{http_code}\n#{content}" rescue nil
|
133
148
|
}
|
134
149
|
```
|
data/Rakefile
CHANGED
@@ -5,6 +5,7 @@ module Kubernetes
|
|
5
5
|
@@ready_if = lambda { true }
|
6
6
|
@@enable_lock_on_migrate = [true, 'true'].include? ENV['KUBERNETES_HEALTH_ENABLE_LOCK_ON_MIGRATE']
|
7
7
|
@@enable_rack_on_migrate = [true, 'true'].include? ENV['KUBERNETES_HEALTH_ENABLE_RACK_ON_MIGRATE']
|
8
|
+
@@enable_rack_on_sidekiq = [true, 'true'].include? ENV['KUBERNETES_HEALTH_ENABLE_RACK_ON_SIDEKIQ']
|
8
9
|
@@route_liveness = '/_liveness'
|
9
10
|
@@route_readiness = '/_readiness'
|
10
11
|
@@route_metrics = '/_metrics'
|
@@ -57,6 +58,14 @@ module Kubernetes
|
|
57
58
|
@@enable_rack_on_migrate = value
|
58
59
|
end
|
59
60
|
|
61
|
+
def self.enable_rack_on_sidekiq
|
62
|
+
@@enable_rack_on_sidekiq
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.enable_rack_on_sidekiq=(value)
|
66
|
+
@@enable_rack_on_sidekiq = value
|
67
|
+
end
|
68
|
+
|
60
69
|
def self.route_metrics
|
61
70
|
@@route_metrics
|
62
71
|
end
|
@@ -1,10 +1,11 @@
|
|
1
1
|
require 'rack'
|
2
2
|
require "kubernetes/health/rack_on_migrate"
|
3
|
+
|
3
4
|
namespace :kubernetes_health do
|
4
5
|
task :rack_on_migrate do
|
5
|
-
Thread.new
|
6
|
+
Thread.new do
|
6
7
|
Rack::Handler.default.run Kubernetes::Health::RackOnMigrate.new
|
7
|
-
|
8
|
+
end
|
8
9
|
end
|
9
10
|
end
|
10
11
|
Rake::Task['db:migrate'].enhance(['kubernetes_health:rack_on_migrate'])
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'rack'
|
2
|
+
require 'prometheus/client'
|
3
|
+
require 'prometheus/client/formats/text'
|
4
|
+
|
5
|
+
module Kubernetes
|
6
|
+
module Health
|
7
|
+
class RackOnSidekiq
|
8
|
+
def call(env)
|
9
|
+
req = ::Rack::Request.new(env)
|
10
|
+
content = ''
|
11
|
+
type = ::Kubernetes::Health::Config.response_format == 'json' ? { 'Content-Type' => 'application/json' } : { 'Content-Type' => 'text/plain' }
|
12
|
+
case req.path_info
|
13
|
+
when Kubernetes::Health::Config.route_metrics
|
14
|
+
http_code = 200
|
15
|
+
|
16
|
+
@sidekiq_metrics = sidekiq_metrics
|
17
|
+
|
18
|
+
if ::Kubernetes::Health::Config.response_format == 'json'
|
19
|
+
content = @sidekiq_metrics.to_json
|
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])
|
24
|
+
content = Prometheus::Client::Formats::Text.marshal(prometheus_registry)
|
25
|
+
end
|
26
|
+
else
|
27
|
+
http_code = 404
|
28
|
+
end
|
29
|
+
::Kubernetes::Health::Config.request_log_callback.call(req, http_code, content)
|
30
|
+
|
31
|
+
[http_code, type, [content]]
|
32
|
+
end
|
33
|
+
|
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
|
42
|
+
end
|
43
|
+
|
44
|
+
def sidekiq_metrics
|
45
|
+
sidekiq_info = Sidekiq::ProcessSet.new.to_a.filter { |p| p.identity == Sidekiq.options[:identity] }
|
46
|
+
|
47
|
+
stats = {
|
48
|
+
sidekiq_capacity: Sidekiq.options[:concurrency],
|
49
|
+
sidekiq_busy: sidekiq_info.size.zero? ? 0 : sidekiq_info[0]['busy']
|
50
|
+
}
|
51
|
+
|
52
|
+
stats[:sidekiq_usage] = (stats[:sidekiq_busy] / stats[:sidekiq_capacity].to_f).round(2)
|
53
|
+
stats
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/puma/kubernetes/app.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'kubernetes/health/config'
|
2
2
|
require 'prometheus/client/formats/text'
|
3
3
|
require 'puma/kubernetes/parser'
|
4
4
|
require 'rack'
|
@@ -28,15 +28,17 @@ module Puma
|
|
28
28
|
when ::Kubernetes::Health::Config.route_metrics
|
29
29
|
http_code = 200
|
30
30
|
if ::Kubernetes::Health::Config.response_format == 'json'
|
31
|
-
content = include_puma_key_prefix(include_usage(
|
31
|
+
content = include_puma_key_prefix(include_usage(merge_worker_status_if_needed(@launcher.stats))).to_json
|
32
32
|
else
|
33
|
-
@parser.parse include_usage(
|
33
|
+
@parser.parse include_usage(merge_worker_status_if_needed(@launcher.stats))
|
34
34
|
content = Prometheus::Client::Formats::Text.marshal(Prometheus::Client.registry)
|
35
35
|
end
|
36
36
|
else
|
37
37
|
http_code = 404
|
38
38
|
end
|
39
|
-
rescue
|
39
|
+
rescue => e
|
40
|
+
puts e.message
|
41
|
+
puts e.backtrace.join("\n")
|
40
42
|
http_code = 500
|
41
43
|
content = ''
|
42
44
|
end
|
@@ -44,7 +46,23 @@ module Puma
|
|
44
46
|
[http_code, type, [content]]
|
45
47
|
end
|
46
48
|
|
49
|
+
def merge_worker_status_if_needed(stats)
|
50
|
+
return stats unless stats[:worker_status]
|
51
|
+
|
52
|
+
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]
|
55
|
+
merded_stats
|
56
|
+
end
|
57
|
+
|
47
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
|
48
66
|
stats['usage'] = (1 - stats['pool_capacity'].to_f / stats['max_threads']).round(2)
|
49
67
|
stats
|
50
68
|
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.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wagner Caixeta
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-04-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -128,6 +128,7 @@ files:
|
|
128
128
|
- app/controllers/kubernetes/health_controller.rb
|
129
129
|
- bin/console
|
130
130
|
- bin/setup
|
131
|
+
- config/initializers/enable_rack_on_sidekiq.rb
|
131
132
|
- config/routes.rb
|
132
133
|
- kubernetes-health.gemspec
|
133
134
|
- lib/kubernetes/health.rb
|
@@ -136,6 +137,7 @@ files:
|
|
136
137
|
- lib/kubernetes/health/lock_on_migrate.rake
|
137
138
|
- lib/kubernetes/health/rack_on_migrate.rake
|
138
139
|
- lib/kubernetes/health/rack_on_migrate.rb
|
140
|
+
- lib/kubernetes/health/rack_on_sidekiq.rb
|
139
141
|
- lib/kubernetes/health/railtie.rb
|
140
142
|
- lib/kubernetes/health/version.rb
|
141
143
|
- lib/puma/kubernetes/app.rb
|
@@ -145,7 +147,7 @@ files:
|
|
145
147
|
homepage: https://github.com/platbr/kubernetes-health
|
146
148
|
licenses: []
|
147
149
|
metadata: {}
|
148
|
-
post_install_message:
|
150
|
+
post_install_message:
|
149
151
|
rdoc_options: []
|
150
152
|
require_paths:
|
151
153
|
- lib
|
@@ -160,8 +162,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
160
162
|
- !ruby/object:Gem::Version
|
161
163
|
version: '0'
|
162
164
|
requirements: []
|
163
|
-
rubygems_version: 3.
|
164
|
-
signing_key:
|
165
|
+
rubygems_version: 3.1.4
|
166
|
+
signing_key:
|
165
167
|
specification_version: 4
|
166
168
|
summary: This gem allows kubernetes monitoring your app while it is running migrates
|
167
169
|
and after it started.
|