Skip to content

feat(nethttp): add httptrace join-points for otelhttptrace support#458

Open
gyanranjanpanda wants to merge 4 commits into
open-telemetry:mainfrom
gyanranjanpanda:feat/add-httptrace-join-points
Open

feat(nethttp): add httptrace join-points for otelhttptrace support#458
gyanranjanpanda wants to merge 4 commits into
open-telemetry:mainfrom
gyanranjanpanda:feat/add-httptrace-join-points

Conversation

@gyanranjanpanda
Copy link
Copy Markdown
Contributor

Summary

Adds compile-time instrumentation support for net/http/httptrace, implementing the join-points needed to support otelhttptrace from opentelemetry-go-contrib (closes #201, part of umbrella #164).

What Changed

New Package: pkg/instrumentation/nethttp/httptrace/

A clientTracer implementation that hooks into Go's net/http/httptrace.ClientTrace callbacks to create detailed sub-spans for each HTTP client request lifecycle phase:

Phase Span Name Key Attributes
Connection acquisition http.getconn net.host.name, connection reuse info
DNS resolution http.dns net.host.name, resolved addresses
TCP connection http.connect remote addr, network type
TLS handshake http.tls error status on failure
Request send http.send error status on write failure
Response receive http.receive

Integration into Existing Client Hook

The existing BeforeRoundTrip hook in pkg/instrumentation/nethttp/client/ is enhanced with 7 lines to attach an httptrace.ClientTrace to the request context after creating the parent client span. No new YAML rules needed — the httptrace functionality piggybacks on the existing RoundTrip join-point.

Span Hierarchy

HTTP GET (parent client span)
├── http.getconn
│   ├── http.dns
│   ├── http.connect
│   └── http.tls
├── http.send
└── http.receive

Testing

  • 14 new unit tests covering all lifecycle phases, error scenarios, connection reuse attributes, and full request lifecycle
  • All existing client/server tests remain green
  • make format/go — ✅ PASS
  • make lint/go — ✅ 0 issues
  • make lint/license-header — ✅ All headers present
  • make build — ✅ Built successfully

Files Changed

New files (3):

  • pkg/instrumentation/nethttp/httptrace/httptrace_hook.go
  • pkg/instrumentation/nethttp/httptrace/httptrace_hook_test.go
  • pkg/instrumentation/nethttp/httptrace/go.mod

Modified files (2 meaningful):

  • pkg/instrumentation/nethttp/client/client_hook.go — wire httptrace into BeforeRoundTrip
  • pkg/instrumentation/nethttp/client/go.mod — add httptrace dependency
  • pkg/instrumentation/nethttp/server/go.mod — add httptrace replace directive (transitive)

@gyanranjanpanda gyanranjanpanda requested a review from a team as a code owner May 3, 2026 19:39
@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla Bot commented May 3, 2026

CLA Signed

The committers listed above are authorized under a signed CLA.

@github-actions github-actions Bot added the scope:feat A new feature being added label May 3, 2026
Add compile-time instrumentation support for net/http/httptrace to
automatically create sub-spans for HTTP client request lifecycle phases.

This creates a new pkg/instrumentation/nethttp/httptrace package that
implements a clientTracer producing sub-spans for:
- DNS resolution (http.dns)
- TCP connection (http.connect)
- TLS handshake (http.tls)
- Connection acquisition (http.getconn)
- Request send (http.send)
- Response receive (http.receive)

The existing BeforeRoundTrip hook in the client package is enhanced to
attach an httptrace.ClientTrace to the request context after creating
the parent client span. No new YAML rules are needed — the httptrace
functionality piggybacks on the existing RoundTrip join-point.

Includes 14 unit tests covering all lifecycle phases, error scenarios,
connection reuse attributes, and full request lifecycle verification.

Closes open-telemetry#201

Assisted-by: Gemini Antigravity
@gyanranjanpanda gyanranjanpanda force-pushed the feat/add-httptrace-join-points branch from 22984a6 to cea4087 Compare May 3, 2026 19:42
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 22984a67f2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +180 to +182
func (ct *clientTracer) putIdleConn(err error) {
ct.end("http.receive", err)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge End http.receive spans without relying on PutIdleConn

http.receive is started in gotFirstResponseByte but only ended in putIdleConn; however, net/http/httptrace does not invoke PutIdleConn for HTTP/2 requests (and also skips it when keep-alives are disabled), so in those common paths the receive span never ends and is never exported. This causes missing sub-spans and incomplete trace data for successful requests over those transports.

Useful? React with 👍 / 👎.

Comment on lines +163 to +164
func (ct *clientTracer) getConn(host string) {
ct.start("http.getconn", "http.getconn", HTTPHostAttribute.String(host))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Strip port before setting net.host.name on getconn span

GetConn receives a host:port string, but this code writes it directly to net.host.name, which should contain only the hostname. As a result, spans will carry invalid host-name values like example.com:443, reducing semantic correctness and potentially breaking grouping/queries that expect normalized host names.

Useful? React with 👍 / 👎.

1. Remove http.receive span entirely because PutIdleConn is not reliably invoked (e.g. for HTTP/2 or when keep-alives are disabled), preventing hanging spans. 2. Strip port from hostPort before setting net.host.name on getconn span.
@gyanranjanpanda gyanranjanpanda deleted the feat/add-httptrace-join-points branch May 3, 2026 19:50
@gyanranjanpanda gyanranjanpanda restored the feat/add-httptrace-join-points branch May 3, 2026 19:51
@gyanranjanpanda
Copy link
Copy Markdown
Contributor Author

could @kakkoyun @txabman42 review this

@kakkoyun kakkoyun added AI/ML Assisted Used AI/ML tools to help creating this PR labels May 5, 2026
@kakkoyun kakkoyun requested review from kakkoyun May 5, 2026 13:02
@codecov
Copy link
Copy Markdown

codecov Bot commented May 5, 2026

Codecov Report

❌ Patch coverage is 85.71429% with 17 lines in your changes missing coverage. Please review.
✅ Project coverage is 62.94%. Comparing base (8935b00) to head (e77b8b4).

Files with missing lines Patch % Lines
...nstrumentation/nethttp/httptrace/httptrace_hook.go 85.21% 16 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #458      +/-   ##
==========================================
+ Coverage   62.26%   62.94%   +0.68%     
==========================================
  Files          62       63       +1     
  Lines        4717     4836     +119     
==========================================
+ Hits         2937     3044     +107     
- Misses       1535     1546      +11     
- Partials      245      246       +1     
Flag Coverage Δ
pkg 62.94% <85.71%> (+0.68%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@gyanranjanpanda
Copy link
Copy Markdown
Contributor Author

is there any thing i hve to change @kakkoyun i would like to change

@txabman42
Copy link
Copy Markdown
Contributor

This PR is related to #202

Let's align first on a common approach for go-contrib join points.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI/ML Assisted Used AI/ML tools to help creating this PR scope:feat A new feature being added

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add join-points to support opentelemetry-go-contrib/instrumentation/net/http/httptrace/otelhttptrace

3 participants