fix(net_http): instrument connection establishment (DNS/TCP/TLS)

Description

Net::HTTP establishes the connection — DNS resolution, TCP connect, TLS handshake — in #do_start, before any #request runs. Because Labkit::NetHttpPublisher#request begins with return super unless started?, the whole connect phase ran outside any instrumented block. As a result:

  • a request that hangs during connection setup (slow DNS, blackholed endpoint, TLS stall) contributed nothing to the request.external_http duration or count; and
  • a connection that failed before any request was sent (e.g. Net::OpenTimeout) emitted no event at all.

This is especially invisible for the explicit-start pattern Net::HTTP.start(host) { |http| http.request(...) }, where connection setup completes entirely before the first #request.

Fix

Instrument #do_start:

  • on success, fold the connection-establishment time into the following request's duration (counted once per connection), so a slow connect is attributed to the request instead of vanishing;
  • on failure, emit a standalone request.external_http event carrying the exception and elapsed time, so a hung or blackholed connection is still visible and counted.

This covers both the implicit-start and explicit-start patterns. #do_start is kept private, matching Ruby's private :do_start.

Follow-up

External HTTP trace span duration still needs separate follow-up work because tracing currently times the ActiveSupport notification block rather than payload[:duration]: #74

Testing

Two regression specs added to spec/labkit/net_http_publisher_spec.rb (both fail before the change, pass after): one asserting connection-setup time is included in the measured duration (explicit start), one asserting an event is emitted when connection setup fails before any request. Full net_http_publisher_spec passes (37 examples) and RuboCop is clean.

Surfaced by gitlab-org/gitlab#605416 (closed), which documents the downstream impact (archived CI trace reads via Gitlab::HttpIO hanging in connect, invisible in external_http_duration_s).

Note: the Excon and HTTPClient publishers likely share the same structural gap and are worth a follow-up audit; this MR scopes the fix to Net::HTTP.

🤖 Generated with Claude Code

Edited by Hercules Merscher

Merge request reports

Loading