-
Notifications
You must be signed in to change notification settings - Fork 368
Expand file tree
/
Copy pathapi_metrics_webserver.rb
More file actions
102 lines (80 loc) · 2.79 KB
/
api_metrics_webserver.rb
File metadata and controls
102 lines (80 loc) · 2.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
require 'rack'
require 'prometheus/middleware/exporter'
module VCAP
module CloudController
class ApiMetricsWebserver
attr_reader :app
def initialize
@app = build_app
end
def start(config)
@server = Puma::Server.new(@app)
if config.get(:nginx, :metrics_socket).nil? || config.get(:nginx, :metrics_socket).empty?
@server.add_tcp_listener('127.0.0.1', 9395)
else
@server.add_unix_listener(config.get(:nginx, :metrics_socket))
end
@server.run
end
def stop
@server.stop(true)
end
private
def build_app
status_proc = method(:status)
Rack::Builder.new do
use Prometheus::Middleware::Exporter, path: '/internal/v4/metrics'
map '/internal/v4/status' do
run ->(_env) { status_proc.call }
end
map '/' do
run lambda { |_env|
# Return 404 for any other request
['404', { 'Content-Type' => 'text/plain' }, ['Not Found']]
}
end
end
end
def status
stats = Puma.stats_hash
worker_statuses = stats[:worker_status]
all_busy = all_workers_busy?(worker_statuses)
current_requests_count_sum = worker_requests_count_sum(worker_statuses)
track_request_count_increase(current_requests_count_sum)
unhealthy = determine_unhealthy_state(all_busy)
build_status_response(all_busy, unhealthy)
rescue StandardError => e
[500, { 'Content-Type' => 'text/plain' }, ["Readiness check error: #{e}"]]
end
def track_request_count_increase(current_requests_count_sum)
now = Time.now
prev = @previous_requests_count_sum
@last_requests_count_increase_time = now if prev.nil? || current_requests_count_sum > prev
@previous_requests_count_sum = current_requests_count_sum
end
def determine_unhealthy_state(all_busy)
return false unless all_busy && @last_requests_count_increase_time
(Time.now - @last_requests_count_increase_time) > 60
end
def build_status_response(all_busy, unhealthy)
if all_busy && unhealthy
[503, { 'Content-Type' => 'text/plain' }, ['UNHEALTHY']]
elsif all_busy
[429, { 'Content-Type' => 'text/plain' }, ['BUSY']]
else
[200, { 'Content-Type' => 'text/plain' }, ['OK']]
end
end
def all_workers_busy?(worker_statuses)
worker_statuses.all? do |worker|
worker[:last_status][:busy_threads] == worker[:last_status][:running]
end
end
def worker_requests_count_sum(worker_statuses)
worker_statuses.sum do |worker|
worker[:last_status][:requests_count] || 0
end
end
end
end
end