summaryrefslogtreecommitdiff
path: root/lib/gitlab/prometheus/queries/matched_metrics_query.rb
blob: fc97bca486cbe8f8ec8224b6842a6893f8746e03 (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
module Gitlab::Prometheus::Queries
  class MatchedMetricsQuery < BaseQuery
    MAX_QUERY_ITEMS = 40.freeze

    def query
      groups_data.map do |group, data|
        {
          group: group.name,
          priority: group.priority,
          active_metrics: data[:active_metrics],
          metrics_missing_requirements: data[:metrics_missing_requirements]
        }
      end
    end

    private

    def groups_data
      metrics_groups = groups_with_active_metrics(Gitlab::Prometheus::MetricGroup.all)
      lookup = active_series_lookup(metrics_groups)

      groups = {}

      metrics_groups.each do |group|
        groups[group] ||= { active_metrics: 0, metrics_missing_requirements: 0 }
        active_metrics = group.metrics.count { |metric| metric.required_metrics.all?(&lookup.method(:has_key?)) }

        groups[group][:active_metrics] += active_metrics
        groups[group][:metrics_missing_requirements] += group.metrics.count - active_metrics
      end

      groups
    end

    def active_series_lookup(metric_groups)
      timeframe_start = 8.hours.ago
      timeframe_end = Time.now

      series = metric_groups.flat_map(&:metrics).flat_map(&:required_metrics).uniq

      lookup = series.each_slice(MAX_QUERY_ITEMS).flat_map do |batched_series|
        client_series(*batched_series, start: timeframe_start, stop: timeframe_end)
          .select(&method(:has_matching_label))
          .map { |series_info| [series_info['__name__'], true] }
      end
      lookup.to_h
    end

    def has_matching_label(series_info)
      series_info.key?('environment')
    end

    def available_metrics
      @available_metrics ||= client_label_values || []
    end

    def filter_active_metrics(metric_group)
      metric_group.metrics.select! do |metric|
        metric.required_metrics.all?(&available_metrics.method(:include?))
      end
      metric_group
    end

    def groups_with_active_metrics(metric_groups)
      metric_groups.map(&method(:filter_active_metrics)).select { |group| group.metrics.any? }
    end

    def metrics_with_required_series(metric_groups)
      metric_groups.flat_map do |group|
        group.metrics.select do |metric|
          metric.required_metrics.all?(&available_metrics.method(:include?))
        end
      end
    end
  end
end