Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

otelhttp: Record metrics on timed out requests #4634

Closed

Conversation

carrbs
Copy link
Contributor

@carrbs carrbs commented Nov 27, 2023

fixes: #4542

Copied verbatim the withoutCancel flow (referenced in #4542) and used it to ensure the metrics are recorded even if the parent ctx is closed. This "patch" (as well as the one in: instrumentation/google.golang.org/grpc/otelgrpc/stats_handler.go) can be updated to use the context.WithoutContext in Go 1.21 once we are no longer supporting Go 1.20.

Copy link

linux-foundation-easycla bot commented Nov 27, 2023

CLA Signed

The committers listed above are authorized under a signed CLA.

Copy link
Member

@pellared pellared left a comment

Choose a reason for hiding this comment

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

Implementation looks OK.

I suggest adding a test in instrumentation/net/http/otelhttp/test/handler_test.go.

I would try adding a server that would always have a canceled request. I guess that something like this should work:

	// here setup a handler instrumented with otelhttp

	ctx, cancel := context.WithCancel(context.Background())
	cancel()
	l, err := net.Listen("tcp", "localhost:0")
	require.NoError(t, err)
	srv := &http.Server{
		BaseContext:  func(_ net.Listener) context.Context { return ctx },
		ReadTimeout:  time.Second,
		WriteTimeout: 10 * time.Second,
		Handler:      otelHandler,
	}
	go func() {
		// When Shutdown is called, Serve immediately returns ErrServerClosed.
		assert.Equal(t, http.ErrServerClosed, srv.Serve(l))
	}()
	t.Cleanup(func() {
		assert.NoError(t, srv.Shutdown(context.Background()) 
	})

	// here make a call using HTTP Client. The address of the server is l.Addr().String()

Copy link

codecov bot commented Nov 28, 2023

Codecov Report

Merging #4634 (b76e57b) into main (6009b31) will decrease coverage by 0.1%.
The diff coverage is 44.4%.

❗ Current head b76e57b differs from pull request most recent head 85a8e2b. Consider uploading reports for the commit 85a8e2b to get more accurate results

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##            main   #4634     +/-   ##
=======================================
- Coverage   80.8%   80.7%   -0.1%     
=======================================
  Files        150     150             
  Lines      10374   10389     +15     
=======================================
+ Hits        8388    8393      +5     
- Misses      1844    1853      +9     
- Partials     142     143      +1     
Files Coverage Δ
instrumentation/net/http/otelhttp/handler.go 83.4% <44.4%> (-4.0%) ⬇️

@carrbs
Copy link
Contributor Author

carrbs commented Dec 2, 2023

Hi @pellared, I attempted to test ctxWithoutCancel with your suggestion, but I think something is amiss either with my request or how I've instrumented the handler. The test passes whether or not ctxWithoutCancel is used. Likely (I hope) it's something obvious you can redirect me with on how I set up the test.

Comment on lines 288 to 291
if ctx.Done() == nil {
return ctx
}
return withoutCancelCtx{ctx}
Copy link
Member

Choose a reason for hiding this comment

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

Why not?

Suggested change
if ctx.Done() == nil {
return ctx
}
return withoutCancelCtx{ctx}
if parent == nil {
panic("cannot create context from nil parent")
}
return withoutCancelCtx{parent}

It is copied from https://cs.opensource.google/go/go/+/refs/tags/go1.21.4:src/context/context.go;l=563-571 therefore I would keep it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good, I didn't know this had been copied from this. The thinking was that, if a context that wasn't cancellable was passed to withoutCancel it seemed like we could return/no-op (and, if it was nil, we'd get a panic).

@pellared
Copy link
Member

pellared commented Dec 5, 2023

@carrbs Has my suggestion helped?

@carrbs
Copy link
Contributor Author

carrbs commented Dec 5, 2023

@pellared, yes, thank you! I'd overlooked that when trying to track down how to test this. It's passing now and I confirmed
here:
https://github.com/open-telemetry/opentelemetry-go/blob/6cee2b4a4c76b581115d0d0ca150ad8b2e683db6/sdk/metric/instrument.go#L208-L210
and here:
https://github.com/open-telemetry/opentelemetry-go/blob/6cee2b4a4c76b581115d0d0ca150ad8b2e683db6/sdk/metric/instrument.go#L208-L210
The expected behavior of the withoutCancelCtx. I'm gonna clean the PR up and take it out of draft.

@carrbs carrbs changed the title [WIP] otelhttp: Record metrics on timed out requests by using a context that doesn't cancel otelhttp: Record metrics on timed out requests by using a context that doesn't cancel Dec 5, 2023
@pellared
Copy link
Member

pellared commented Dec 5, 2023

I'm gonna clean the PR up and take it out of draft.

Please do not forget to add an entry in "Fixed" section in CHANGELOG.md 😉

@carrbs carrbs marked this pull request as ready for review December 5, 2023 17:53
@carrbs carrbs requested a review from a team December 5, 2023 17:53
CHANGELOG.md Outdated Show resolved Hide resolved
Co-authored-by: Robert Pająk <pellared@hotmail.com>
@pellared pellared changed the title otelhttp: Record metrics on timed out requests by using a context that doesn't cancel otelhttp: Record metrics on timed out requests Dec 5, 2023
@pellared
Copy link
Member

pellared commented Dec 5, 2023

@carrbs Thank you for your contribution. Do not hesitate to leave suggestions that could make future contributions easier.

@pellared
Copy link
Member

pellared commented Dec 5, 2023

@Aneurysm9 @dmathieu PTAL as code owners.

@carrbs
Copy link
Contributor Author

carrbs commented Dec 5, 2023

what's up with the codecov/patch failed test? Is it expecting some unit testing?

@pellared
Copy link
Member

pellared commented Dec 5, 2023

what's up with the codecov/patch failed test? Is it expecting some unit testing?

It is fine. It just notifies that some new code is not covered by tests which is fine. See: https://app.codecov.io/gh/open-telemetry/opentelemetry-go-contrib/pull/4634?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=checks&utm_campaign=pr+comments&utm_term=open-telemetry

@pellared
Copy link
Member

pellared commented Dec 6, 2023

The fix would not be needed if open-telemetry/opentelemetry-go#4671 is accepted and merged.

@dmathieu
Copy link
Member

dmathieu commented Dec 6, 2023

The SDK native solution seems more elegant, as we wouldn't have to set it up for every instrumentation.

@@ -281,3 +283,34 @@ func WithRouteTag(route string, h http.Handler) http.Handler {
h.ServeHTTP(w, r)
})
}

func withoutCancel(parent context.Context) context.Context {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please add a note, including a link, about where this is copied from.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Happy to do this, but it sounding like the better option might be the SDK native one (so long as we would not need the flexibility of calling those .Add and .Record methods in such a way where we want different behavior based on the context's cancelled state)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added, in case we opt to merge this PR. Thanks @MrAlias!

@pellared
Copy link
Member

pellared commented Dec 8, 2023

I am changing to draft because of open-telemetry/opentelemetry-go#4671

@carrbs Feel free to review the referenced PR.

@pellared pellared marked this pull request as draft December 8, 2023 13:29
@pellared
Copy link
Member

Closing per open-telemetry/opentelemetry-go#4671

@pellared pellared closed this Dec 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

otelhttp: Record metrics on timed out requests
4 participants