lib/release_tools/promotion/checks/gitlab_deployment_health.rb (75 lines of code) (raw):
# frozen_string_literal: true
module ReleaseTools
module Promotion
module Checks
# GitlabDeploymentHealth checks our production metrics to allow a deployment
class GitlabDeploymentHealth
include ::ReleaseTools::Promotion::Check
include ::SemanticLogger::Loggable
HEADING = ':crystal_ball: GitLab Deployment Health Status'
def name
'services health'
end
def fine?
!ok_count.zero? && ok_count == services.size
end
def to_issue_body
text = StringIO.new
text.puts("#{HEADING} - [overview](#{current_grafana_url})\n\n")
if fine?
text.puts("* #{ok_icon} All services healthy")
else
services_status_markup.each do |status|
text.puts("* #{status}")
end
end
text.string
end
def to_slack_blocks
[
{
type: 'section',
text: mrkdwn("#{HEADING} - #{Slack::Utilities.api_link('overview', current_grafana_url)}")
},
{
type: 'context',
elements: services_status_markup.map { |status| mrkdwn(status) }
}
]
end
ErrorService = Struct.new(:exception) do
def fine?
false
end
def name
"Cannot detect gitlab deployment health, #{exception.message}"
end
end
def current_grafana_url
Mimir::Utils.explore_pane_url(
query: 'gitlab_deployment_health:service{env="gprd"}',
from: 'now-6h',
to: 'now'
)
end
def services
@services ||=
begin
::ReleaseTools::Prometheus::ServiceHealth.new.services
rescue StandardError => ex
logger.error('Cannot detect gitlab deployment health', error: ex)
::ReleaseTools::ErrorTracking.capture_exception(ex)
[ErrorService.new(ex)]
end
end
def ok_count
services.count(&:fine?)
end
# services_status_markup produces a markup compatible with both
# GitLab markdown and Slack mrkdwn syntax.
#
# @return [Array<String>] one markup line for each service
def services_status_markup
return ["#{failure_icon} no data"] if services.empty?
services.map do |service|
"#{icon(service)} #{service.name}"
end
end
end
end
end
end