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

    def self.metrics
      @metrics ||= YAML.load_file(Rails.root.join('config/additional_metrics.yml')).map(&:deep_symbolize_keys)
    end

    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

    def groups_data
      metrics_series = metrics_with_series(Gitlab::Prometheus::MetricGroup.all)
      lookup = active_series_lookup(metrics_series)

      groups = {}

      metrics_series.each do |metrics, series|
        groups[metrics.group] ||= { active_metrics: 0, metrics_missing_requirements: 0 }
        group = groups[metrics.group]

        if series.all?(&lookup.method(:has_key?))
          group[:active_metrics] += 1
        else
          group[:metrics_missing_requirements] += 1
        end
        group
      end

      groups
    end

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

      series = metrics.flat_map { |metrics, series| series }.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.has_key?('environment')
    end

    def metrics_with_series(metric_groups)
      label_values = client_label_values || []

      metrics = metric_groups.flat_map do |group|
        group.metrics.map do |metric|
          matcher = Regexp.compile(metric.detect)
          [metric, label_values.select(&matcher.method(:match))]
        end
      end

      metrics.select { |metric, labels| labels&.any? }
    end
  end
end