Loading
fix(net_http): instrument connection establishment (DNS/TCP/TLS)
Net::HTTP establishes the connection (DNS resolution, TCP connect, TLS
handshake) in `#do_start`, before any `#request` runs. Because the publisher
returned early from `#request` unless the connection was already `started?`,
the entire connect phase ran uninstrumented: a request hanging in DNS/TCP/TLS
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.
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 event carrying the exception and elapsed time,
so a hung or blackholed connection is still visible.
This covers both the implicit-start pattern and the explicit-start pattern
(`Net::HTTP.start(host) { |http| http.request(...) }`), the latter being where
connection setup completes entirely outside `#request`.
Related: gitlab-org/gitlab#605416
Co-Authored-By:
Claude Fable 5 <noreply@anthropic.com>