summaryrefslogtreecommitdiff
path: root/app/controllers/health_controller.rb
diff options
context:
space:
mode:
authorPaweł Chojnacki <pawel@chojnacki.ws>2017-04-07 10:27:15 +0000
committerDouwe Maan <douwe@gitlab.com>2017-04-07 10:27:15 +0000
commitc3e43c9ba38f8cc0f2fd4a918d052c3977a93421 (patch)
tree3c5e09e7955663f69573ee9f47e9344011993532 /app/controllers/health_controller.rb
parent15e87cea3a374e8d929c28f6843170b182fe159a (diff)
downloadgitlab-ce-c3e43c9ba38f8cc0f2fd4a918d052c3977a93421.tar.gz
Add /-/readiness /-/liveness and /-/health_metrics endpoints to track application readiness
Diffstat (limited to 'app/controllers/health_controller.rb')
-rw-r--r--app/controllers/health_controller.rb60
1 files changed, 60 insertions, 0 deletions
diff --git a/app/controllers/health_controller.rb b/app/controllers/health_controller.rb
new file mode 100644
index 00000000000..df0fc3132ed
--- /dev/null
+++ b/app/controllers/health_controller.rb
@@ -0,0 +1,60 @@
+class HealthController < ActionController::Base
+ protect_from_forgery with: :exception
+ include RequiresHealthToken
+
+ CHECKS = [
+ Gitlab::HealthChecks::DbCheck,
+ Gitlab::HealthChecks::RedisCheck,
+ Gitlab::HealthChecks::FsShardsCheck,
+ ].freeze
+
+ def readiness
+ results = CHECKS.map { |check| [check.name, check.readiness] }
+
+ render_check_results(results)
+ end
+
+ def liveness
+ results = CHECKS.map { |check| [check.name, check.liveness] }
+
+ render_check_results(results)
+ end
+
+ def metrics
+ results = CHECKS.flat_map(&:metrics)
+
+ response = results.map(&method(:metric_to_prom_line)).join("\n")
+
+ render text: response, content_type: 'text/plain; version=0.0.4'
+ end
+
+ private
+
+ def metric_to_prom_line(metric)
+ labels = metric.labels&.map { |key, value| "#{key}=\"#{value}\"" }&.join(',') || ''
+ if labels.empty?
+ "#{metric.name} #{metric.value}"
+ else
+ "#{metric.name}{#{labels}} #{metric.value}"
+ end
+ end
+
+ def render_check_results(results)
+ flattened = results.flat_map do |name, result|
+ if result.is_a?(Gitlab::HealthChecks::Result)
+ [[name, result]]
+ else
+ result.map { |r| [name, r] }
+ end
+ end
+ success = flattened.all? { |name, r| r.success }
+
+ response = flattened.map do |name, r|
+ info = { status: r.success ? 'ok' : 'failed' }
+ info['message'] = r.message if r.message
+ info[:labels] = r.labels if r.labels
+ [name, info]
+ end
+ render json: response.to_h, status: success ? :ok : :service_unavailable
+ end
+end