summaryrefslogtreecommitdiff
path: root/lib/gitlab/metrics/dashboard/stages/project_metrics_inserter.rb
blob: 643be309992795bc390e8d349991bbfa8a9049ab (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
100
101
102
103
104
105
106
# frozen_string_literal: true

module Gitlab
  module Metrics
    module Dashboard
      module Stages
        class ProjectMetricsInserter < BaseStage
          # Inserts project-specific metrics into the dashboard
          # config. If there are no project-specific metrics,
          # this will have no effect.
          def transform!
            project.prometheus_metrics.each do |project_metric|
              group = find_or_create_panel_group(dashboard[:panel_groups], project_metric)
              panel = find_or_create_panel(group[:panels], project_metric)
              find_or_create_metric(panel[:metrics], project_metric)
            end
          end

          private

          # Looks for a panel_group corresponding to the
          # provided metric object. If unavailable, inserts one.
          # @param panel_groups [Array<Hash>]
          # @param metric [PrometheusMetric]
          def find_or_create_panel_group(panel_groups, metric)
            panel_group = find_panel_group(panel_groups, metric)
            return panel_group if panel_group

            panel_group = new_panel_group(metric)
            panel_groups << panel_group

            panel_group
          end

          # Looks for a panel corresponding to the provided
          # metric object. If unavailable, inserts one.
          # @param panels [Array<Hash>]
          # @param metric [PrometheusMetric]
          def find_or_create_panel(panels, metric)
            panel = find_panel(panels, metric)
            return panel if panel

            panel = new_panel(metric)
            panels << panel

            panel
          end

          # Looks for a metric corresponding to the provided
          # metric object. If unavailable, inserts one.
          # @param metrics [Array<Hash>]
          # @param metric [PrometheusMetric]
          def find_or_create_metric(metrics, metric)
            target_metric = find_metric(metrics, metric)
            return target_metric if target_metric

            target_metric = new_metric(metric)
            metrics << target_metric

            target_metric
          end

          def find_panel_group(panel_groups, metric)
            return unless panel_groups

            panel_groups.find { |group| group[:group] == metric.group_title }
          end

          def find_panel(panels, metric)
            return unless panels

            panel_identifiers = [DEFAULT_PANEL_TYPE, metric.title, metric.y_label]
            panels.find { |panel| panel.values_at(:type, :title, :y_label) == panel_identifiers }
          end

          def find_metric(metrics, metric)
            return unless metrics

            metrics.find { |m| m[:id] == metric.identifier }
          end

          def new_panel_group(metric)
            {
              group: metric.group_title,
              priority: metric.priority,
              panels: []
            }
          end

          def new_panel(metric)
            {
              type: DEFAULT_PANEL_TYPE,
              title: metric.title,
              y_label: metric.y_label,
              metrics: []
            }
          end

          def new_metric(metric)
            metric.to_metric_hash
          end
        end
      end
    end
  end
end