diff options
Diffstat (limited to 'app/services/clusters/integrations/prometheus_health_check_service.rb')
-rw-r--r-- | app/services/clusters/integrations/prometheus_health_check_service.rb | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/app/services/clusters/integrations/prometheus_health_check_service.rb b/app/services/clusters/integrations/prometheus_health_check_service.rb new file mode 100644 index 00000000000..cd06e59449c --- /dev/null +++ b/app/services/clusters/integrations/prometheus_health_check_service.rb @@ -0,0 +1,101 @@ +# frozen_string_literal: true + +module Clusters + module Integrations + class PrometheusHealthCheckService + include Gitlab::Utils::StrongMemoize + include Gitlab::Routing + + def initialize(cluster) + @cluster = cluster + @logger = Gitlab::AppJsonLogger.build + end + + def execute + raise 'Invalid cluster type. Only project types are allowed.' unless @cluster.project_type? + + return unless prometheus_integration.enabled + + project = @cluster.clusterable + + @logger.info( + message: 'Prometheus health check', + cluster_id: @cluster.id, + newly_unhealthy: became_unhealthy?, + currently_healthy: currently_healthy?, + was_healthy: was_healthy? + ) + + send_notification(project) if became_unhealthy? + + prometheus_integration.update_columns(health_status: current_health_status) if health_changed? + end + + private + + def prometheus_integration + strong_memoize(:prometheus_integration) do + @cluster.integration_prometheus + end + end + + def current_health_status + if currently_healthy? + :healthy + else + :unhealthy + end + end + + def currently_healthy? + strong_memoize(:currently_healthy) do + prometheus_integration.prometheus_client.healthy? + end + end + + def became_unhealthy? + strong_memoize(:became_unhealthy) do + (was_healthy? || was_unknown?) && !currently_healthy? + end + end + + def was_healthy? + strong_memoize(:was_healthy) do + prometheus_integration.healthy? + end + end + + def was_unknown? + strong_memoize(:was_unknown) do + prometheus_integration.unknown? + end + end + + def health_changed? + was_healthy? != currently_healthy? + end + + def send_notification(project) + notification_payload = build_notification_payload(project) + integration = project.alert_management_http_integrations.active.first + + Projects::Alerting::NotifyService.new(project, notification_payload).execute(integration&.token, integration) + + @logger.info(message: 'Successfully notified of Prometheus newly unhealthy', cluster_id: @cluster.id, project_id: project.id) + end + + def build_notification_payload(project) + cluster_path = namespace_project_cluster_path( + project_id: project.path, + namespace_id: project.namespace.path, + id: @cluster.id + ) + + { + title: "Prometheus is Unhealthy. Cluster Name: #{@cluster.name}", + description: "Prometheus is unhealthy for the cluster: [#{@cluster.name}](#{cluster_path}) attached to project #{project.name}." + } + end + end + end +end |