summaryrefslogtreecommitdiff
path: root/lib/peek/views/external_http.rb
blob: bd0e4c64127cdfcdde04697c41b156c6beede783 (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
# frozen_string_literal: true

module Peek
  module Views
    class ExternalHttp < DetailedView
      DEFAULT_THRESHOLDS = {
        calls: 10,
        duration: 1000,
        individual_call: 100
      }.freeze

      THRESHOLDS = {
        production: {
          calls: 10,
          duration: 1000,
          individual_call: 100
        }
      }.freeze

      def key
        'external-http'
      end

      def results
        super.merge(calls: calls)
      end

      def self.thresholds
        @thresholds ||= THRESHOLDS.fetch(Rails.env.to_sym, DEFAULT_THRESHOLDS)
      end

      def format_call_details(call)
        full_path = generate_path(call)
        super.merge(
          label: "#{call[:method]} #{full_path}",
          code: code(call),
          proxy: proxy(call),
          error: error(call)
        )
      end

      private

      def duration
        ::Gitlab::Metrics::Subscribers::ExternalHttp.duration * 1000
      end

      def calls
        ::Gitlab::Metrics::Subscribers::ExternalHttp.request_count
      end

      def call_details
        ::Gitlab::Metrics::Subscribers::ExternalHttp.detail_store
      end

      def proxy(call)
        if call[:proxy_host].present?
          "Proxied via #{call[:proxy_host]}:#{call[:proxy_port]}"
        else
          nil
        end
      end

      def code(call)
        if call[:code].present?
          "Response status: #{call[:code]}"
        else
          nil
        end
      end

      def error(call)
        if call[:exception_object].present?
          "Exception: #{call[:exception_object]}"
        else
          nil
        end
      end

      def generate_path(call)
        uri = URI("")
        uri.scheme = call[:scheme]
        # The host can be a domain, IPv4 or IPv6.
        # Ruby handle IPv6 for us at
        # https://github.com/ruby/ruby/blob/v2_6_0/lib/uri/generic.rb#L662
        uri.hostname = call[:host]
        uri.port = call[:port]
        uri.path = call[:path]
        uri.query = call[:query]

        uri.to_s
      rescue URI::Error
        'unknown'
      end
    end
  end
end