summaryrefslogtreecommitdiff
path: root/lib/gitlab/alert_management/payload/prometheus.rb
blob: 336e9b319e80323ec991914f3b9f0070f8d93983 (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
91
92
93
94
95
96
97
98
99
# frozen_string_literal: true

# Attribute mapping for alerts via prometheus alerting integration.
module Gitlab
  module AlertManagement
    module Payload
      class Prometheus < Base
        attribute :alert_markdown, paths: %w(annotations gitlab_incident_markdown)
        attribute :annotations, paths: 'annotations'
        attribute :description, paths: %w(annotations description)
        attribute :ends_at, paths: 'endsAt', type: :time
        attribute :environment_name, paths: %w(labels gitlab_environment_name)
        attribute :generator_url, paths: %w(generatorURL)
        attribute :gitlab_y_label,
                  paths: [%w(annotations gitlab_y_label),
                          %w(annotations title),
                          %w(annotations summary),
                          %w(labels alertname)]
        attribute :runbook, paths: %w(annotations runbook)
        attribute :starts_at,
                  paths: 'startsAt',
                  type: :time,
                  fallback: -> { Time.current.utc }
        attribute :status, paths: 'status'
        attribute :title,
                  paths: [%w(annotations title),
                          %w(annotations summary),
                          %w(labels alertname)]

        attribute :starts_at_raw,
                  paths: [%w(startsAt)]
        private :starts_at_raw

        METRIC_TIME_WINDOW = 30.minutes

        def monitoring_tool
          Gitlab::AlertManagement::Payload::MONITORING_TOOLS[:prometheus]
        end

        # Parses `g0.expr` from `generatorURL`.
        #
        # Example: http://localhost:9090/graph?g0.expr=vector%281%29&g0.tab=1
        def full_query
          return unless generator_url

          uri = URI(generator_url)

          Rack::Utils.parse_query(uri.query).fetch('g0.expr')
        rescue URI::InvalidURIError, KeyError
        end

        def metrics_dashboard_url
          return unless environment && full_query && title

          metrics_dashboard_project_environment_url(
            project,
            environment,
            embed_json: dashboard_json,
            embedded: true,
            **alert_embed_window_params
          )
        end

        def has_required_attributes?
          project && title && starts_at_raw
        end

        private

        def plain_gitlab_fingerprint
          [starts_at_raw, title, full_query].join('/')
        end

        # Formatted for parsing by JS
        def alert_embed_window_params
          {
            start: (starts_at - METRIC_TIME_WINDOW).utc.strftime('%FT%TZ'),
            end: (starts_at + METRIC_TIME_WINDOW).utc.strftime('%FT%TZ')
          }
        end

        def dashboard_json
          {
            panel_groups: [{
              panels: [{
                type: 'area-chart',
                title: title,
                y_label: gitlab_y_label,
                metrics: [{
                  query_range: full_query
                }]
              }]
            }]
          }.to_json
        end
      end
    end
  end
end