-
Notifications
You must be signed in to change notification settings - Fork 576
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
otelhttp: Record metrics on timed out requests #4634
Conversation
There was a problem hiding this 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()
Codecov Report
Additional details and impacted files@@ 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
|
…entelemetry-go-contrib into metrics-for-timed-out-requests
Hi @pellared, I attempted to test |
if ctx.Done() == nil { | ||
return ctx | ||
} | ||
return withoutCancelCtx{ctx} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not?
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.
There was a problem hiding this comment.
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).
@carrbs Has my suggestion helped? |
@pellared, yes, thank you! I'd overlooked that when trying to track down how to test this. It's passing now and I confirmed |
Please do not forget to add an entry in "Fixed" section in |
Co-authored-by: Robert Pająk <pellared@hotmail.com>
@carrbs Thank you for your contribution. Do not hesitate to leave suggestions that could make future contributions easier. |
@Aneurysm9 @dmathieu PTAL as code owners. |
what's up with the |
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 |
The fix would not be needed if open-telemetry/opentelemetry-go#4671 is accepted and merged. |
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 { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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)?
There was a problem hiding this comment.
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!
…entelemetry-go-contrib into metrics-for-timed-out-requests
I am changing to draft because of open-telemetry/opentelemetry-go#4671 @carrbs Feel free to review the referenced PR. |
Closing per open-telemetry/opentelemetry-go#4671 |
fixes: #4542
Copied verbatim the
withoutCancel
flow (referenced in #4542) and used it to ensure the metrics are recorded even if the parentctx
is closed. This "patch" (as well as the one in:instrumentation/google.golang.org/grpc/otelgrpc/stats_handler.go
) can be updated to use thecontext.WithoutContext
in Go 1.21 once we are no longer supporting Go 1.20.