Welcome to mirror list, hosted at ThFree Co, Russian Federation.

patroni_apdex.rb « indicators « health_status « background_migration « database « gitlab « lib - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 0dd6dd5c2a4c56b50dd0777446399ea3fc8dcd91 (plain)
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
# frozen_string_literal: true

module Gitlab
  module Database
    module BackgroundMigration
      module HealthStatus
        module Indicators
          class PatroniApdex
            include Gitlab::Utils::StrongMemoize

            def initialize(context)
              @context = context
            end

            def evaluate
              return Signals::NotAvailable.new(self.class, reason: 'indicator disabled') unless enabled?

              connection_error_message = fetch_connection_error_message
              return unknown_signal(connection_error_message) if connection_error_message.present?

              apdex_sli = fetch_sli(apdex_sli_query)
              return unknown_signal('Patroni service apdex can not be calculated') unless apdex_sli.present?

              if apdex_sli.to_f > apdex_slo.to_f
                Signals::Normal.new(self.class, reason: 'Patroni service apdex is above SLO')
              else
                Signals::Stop.new(self.class, reason: 'Patroni service apdex is below SLO')
              end
            end

            private

            attr_reader :context

            def enabled?
              Feature.enabled?(:batched_migrations_health_status_patroni_apdex, type: :ops)
            end

            def unknown_signal(reason)
              Signals::Unknown.new(self.class, reason: reason)
            end

            def fetch_connection_error_message
              return 'Patroni Apdex Settings not configured' unless database_apdex_settings.present?
              return 'Prometheus client is not ready' unless client.ready?
              return 'Apdex SLI query is not configured' unless apdex_sli_query
              return 'Apdex SLO is not configured' unless apdex_slo
            end

            def client
              @client ||= Gitlab::PrometheusClient.new(
                database_apdex_settings[:prometheus_api_url],
                allow_local_requests: true,
                verify: true
              )
            end

            def database_apdex_settings
              @database_apdex_settings ||= Gitlab::CurrentSettings.database_apdex_settings&.with_indifferent_access
            end

            def apdex_sli_query
              {
                gitlab_main: database_apdex_settings[:apdex_sli_query][:main],
                gitlab_ci: database_apdex_settings[:apdex_sli_query][:ci]
              }.fetch(context.gitlab_schema.to_sym)
            end
            strong_memoize_attr :apdex_sli_query

            def apdex_slo
              {
                gitlab_main: database_apdex_settings[:apdex_slo][:main],
                gitlab_ci: database_apdex_settings[:apdex_slo][:ci]
              }.fetch(context.gitlab_schema.to_sym)
            end
            strong_memoize_attr :apdex_slo

            def fetch_sli(query)
              response = client.query(query)
              metric = response&.first || {}
              value = metric.fetch('value', [])

              Array.wrap(value).second
            end
          end
        end
      end
    end
  end
end