summaryrefslogtreecommitdiff
path: root/lib/gitlab/prometheus/queries/additional_metrics_query.rb
blob: 7ef4ee3a91a4b60bad2a504fa879551ee6626db7 (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
module Gitlab::Prometheus::Queries
  class AdditionalMetricsQuery < BaseQuery
    def query(environment_id)
      environment = Environment.find_by(id: environment_id)
      query_context = {
        environment_slug: environment.slug,
        environment_filter: %{container_name!="POD",environment="#{environment.slug}"},
        timeframe_start: 8.hours.ago.to_f,
        timeframe_end: Time.now.to_f
      }

      query_metrics(query_context)
    end

    protected

    def query_metrics(query_context)
      query_processor = method(:process_query).curry[query_context]

      groups = matched_metrics.map do |group|
        metrics = group.metrics.map do |metric|
          {
            title: metric.title,
            weight: metric.weight,
            y_label: metric.y_label,
            queries: metric.queries.map(&query_processor).select(&method(:query_with_result))
          }
        end

        {
          group: group.name,
          priority: group.priority,
          metrics: metrics.select(&method(:metric_with_any_queries))
        }
      end

      groups.select(&method(:group_with_any_metrics))
    end

    private

    def metric_with_any_queries(metric)
      metric[:queries]&.count&.> 0
    end

    def group_with_any_metrics(group)
      group[:metrics]&.count&.> 0
    end

    def query_with_result(query)
      query[:result]&.any? do |item|
        item&.[](:values)&.any? || item&.[](:value)&.any?
      end
    end

    def process_query(context, query)
      query_with_result = query.dup
      query_with_result[:result] =
        if query.has_key?(:query_range)
          client_query_range(query[:query_range] % context, start: context[:timeframe_start], stop: context[:timeframe_end])
        else
          client_query(query[:query] % context, time: context[:timeframe_end])
        end
      query_with_result
    end

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

    def matched_metrics
      result = Gitlab::Prometheus::MetricGroup.all.map do |group|
        group.metrics.select! do |metric|
          metric.required_metrics.all?(&available_metrics.method(:include?))
        end
        group
      end

      result.select { |group| group.metrics.any? }
    end
  end
end