diff options
Diffstat (limited to 'app/services')
-rw-r--r-- | app/services/clusters/applications/prometheus_health_check_service.rb | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/app/services/clusters/applications/prometheus_health_check_service.rb b/app/services/clusters/applications/prometheus_health_check_service.rb new file mode 100644 index 00000000000..e609d9f0b7b --- /dev/null +++ b/app/services/clusters/applications/prometheus_health_check_service.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +module Clusters + module Applications + 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_application.installed? + + 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_application.update_columns(healthy: currently_healthy?) if health_changed? + end + + private + + def prometheus_application + strong_memoize(:prometheus_application) do + @cluster.application_prometheus + end + end + + def currently_healthy? + strong_memoize(:currently_healthy) do + prometheus_application.prometheus_client.healthy? + end + end + + def became_unhealthy? + strong_memoize(:became_unhealthy) do + (was_healthy? || was_healthy?.nil?) && !currently_healthy? + end + end + + def was_healthy? + strong_memoize(:was_healthy) do + prometheus_application.healthy + end + end + + def health_changed? + was_healthy? != currently_healthy? + end + + def send_notification(project) + notification_payload = build_notification_payload(project) + token = project.alerts_service.data.token + Projects::Alerting::NotifyService.new(project, nil, notification_payload).execute(token) + @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 |