Class: Profiler::Collectors::HttpCollector

Inherits:
BaseCollector show all
Defined in:
lib/profiler/collectors/http_collector.rb

Instance Attribute Summary

Attributes inherited from BaseCollector

#profile

Instance Method Summary collapse

Methods inherited from BaseCollector

descendants, #has_data?, inherited, #name, #panel_content, #render_html, #render_mode

Constructor Details

#initialize(profile) ⇒ HttpCollector

Returns a new instance of HttpCollector.



9
10
11
12
13
14
# File 'lib/profiler/collectors/http_collector.rb', line 9

def initialize(profile)
  super
  @requests = []
  @mutex = Mutex.new
  @collected = false
end

Instance Method Details

#collectObject



42
43
44
45
46
47
48
49
50
# File 'lib/profiler/collectors/http_collector.rb', line 42

def collect
  Thread.current[:profiler_http_collector] = nil

  data = @mutex.synchronize do
    @collected = true
    build_data(@requests)
  end
  store_data(data)
end

#complete_request(entry, **data) ⇒ Object

Called from NetHttpInstrumentation after the HTTP response is received.



64
65
66
67
# File 'lib/profiler/collectors/http_collector.rb', line 64

def complete_request(entry, **data)
  @mutex.synchronize { entry.merge!(data.merge(in_flight: false)) }
  save_if_collected
end

#fail_request(entry, error:, duration:) ⇒ Object

Called from NetHttpInstrumentation when the HTTP call raises.



70
71
72
73
# File 'lib/profiler/collectors/http_collector.rb', line 70

def fail_request(entry, error:, duration:)
  @mutex.synchronize { entry.merge!(in_flight: false, status: 0, duration: duration, error: error) }
  save_if_collected
end

#iconObject



16
17
18
# File 'lib/profiler/collectors/http_collector.rb', line 16

def icon
  "🔗"
end

#priorityObject



20
21
22
# File 'lib/profiler/collectors/http_collector.rb', line 20

def priority
  35
end

#register_pending(payload) ⇒ Object

Called from NetHttpInstrumentation before the actual HTTP call. Returns the mutable entry so the caller can update it on completion.



54
55
56
57
58
59
60
61
# File 'lib/profiler/collectors/http_collector.rb', line 54

def register_pending(payload)
  entry = payload.merge(in_flight: true, status: 0, duration: nil,
                        response_headers: {}, response_body: nil,
                        response_body_encoding: "text", response_size: 0)
  @mutex.synchronize { @requests << entry }
  save_if_collected
  entry
end

#subscribeObject



35
36
37
38
39
40
# File 'lib/profiler/collectors/http_collector.rb', line 35

def subscribe
  return unless Profiler.configuration.track_http

  Profiler::Instrumentation::NetHttpInstrumentation.install!
  Thread.current[:profiler_http_collector] = self
end

#tab_configObject



24
25
26
27
28
29
30
31
32
33
# File 'lib/profiler/collectors/http_collector.rb', line 24

def tab_config
  {
    key: "http",
    label: "Outbound HTTP",
    icon: icon,
    priority: priority,
    enabled: true,
    default_active: false
  }
end

#toolbar_summaryObject



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/profiler/collectors/http_collector.rb', line 75

def toolbar_summary
  requests = @mutex.synchronize { @requests.dup }
  total = requests.size
  return { text: "0 HTTP", color: "green" } if total == 0

  threshold = Profiler.configuration.slow_http_threshold
  in_flight = requests.count { |r| r[:in_flight] }
  errors = requests.count { |r| !r[:in_flight] && (r[:status] >= 400 || r[:status] == 0) }
  slow = requests.count { |r| !r[:in_flight] && r[:duration] && r[:duration] >= threshold }
  duration = requests.sum { |r| r[:duration].to_f }.round(2)

  color = if errors > 0 || slow > 0
            "red"
          elsif in_flight > 0 || total > 10
            "orange"
          else
            "green"
          end

  text = in_flight > 0 ? "#{total} HTTP (#{in_flight} pending, #{duration}ms)" : "#{total} HTTP (#{duration}ms)"
  { text: text, color: color }
end