-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Expose optional ResponseWriter interfaces. #979
Expose optional ResponseWriter interfaces. #979
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.
This PR doesn't seem in line with the purpose of this instrumentation. It does not use OpenTelemetry metric instruments to capture metric events (it doesn't seem to do any tracing either, not sure if I missed that based on the PR description).
If the user desires to expose these interfaces for a handler I don't see why they couldn't wrap their handler directly. It doesn't seem appropriate to make that decision for all users looking to use this instrumentation.
This PR is not about instrumentation or metrics. It fixes a bug in the otel http handler where the wrapped response writer object loses all the optional interfaces implemented by the underlying http.ResponseWriter. It is not possible for the user to recover or reimplement the missing interfaces. Currently if you use the otel http handler, the wrapped http.ResponseWriter that gets passed to the user's handlers does not implement any of the optional http interfaces (e.g. http.Hijacker, http.Flusher, etc). This is not acceptable since these interfaces are required for various HTTP applications. There is already a TODO comment in the code admitting this:
Properly wrapping a ResponseWriter to implement all the optional interfaces is not easy. It involves a combinatorial explosion of all the optional interfaces. The "httpsnoop" package handles it for you, and uses code generation to manage the complexity. |
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.
I think this is an important deficiency of the current othttp.Handler
to address and I'm generally in favor of the approach. My only concern would be that @MrAlias has previously expressed concern about the use of dependencies with the MIT license. Are there alternatives that are Apache 2.0 licensed?
Also, please ensure that all relevant go.mod
and go.sum
files are updated, this appears to be the cause of the CI build failures.
What is troublesome about the MIT license?
We don't know of any alternatives. Some packages just implement the wrapping logic themselves, so that is always an option. |
c4b304f
to
74d3355
Compare
I'm not aware of any problem utilizing MIT-licensed dependencies in an Apache-licensed project, but I'm not capable of speaking for the CNCF or project governance committee. I just know that a maintainer of this project has previously said "[t]he MIT license can be troublesome for dependencies". @MrAlias or @lizthegrey do you have any clarity to share? |
@Aneurysm9 thanks for pointing this out, but I'm pretty sure I was mistaking MPL-2.0 with MIT in that linked comment (the alternate github.com/hashicorp/go-multierror has that license and it looks like I was getting my signals crossed). Definitely my goof 🤦. @muirdm thanks for the clarification, I need to take a deeper look at this. Do you have any links to where others have wrapped the logic themselves? |
Opencensus implements something similar to httpsnoop: The AWS SDK xray implements something similar to httpsnoop: The gorilla "compress" handler attempts to wrap, but it does it incorrectly since it implements all the optional interfaces even if the underlying ResponseWriter doesn't (which causes panics): The gorilla "logging" handler implements it for a couple interfaces: |
Guessing this isn't going to be resolved before we want this in GA. |
Personally I think the dependency is worth it because it is hard to implement correctly, and it will require maintenance as they add more http interfaces to the standard library. For example, the httpsnoop package supports Go versions from before http.Pusher was added. On the other hand, I don't really like httpsnoop's interface, and can appreciate not wanting third party dependencies in a library. Up to you. We will be happy as long as the wrapping is fixed one way or another. |
I think this is adequate motivation, and I agree. I think we should move in this direction. @andy-retailnext can you sign the CLA, make the fixes @Aneurysm9 mentioned, and add the fix to the change log? |
We're working out the details of signing the CLA, but I'll sign it as soon as that's taken care of. I updated the commit with the additional go.sum changes. The build passes now. |
@andy-retailnext looks like edits by maintainers is off. Can you update the Changelog with this fix and sync with the base branch? |
I think the dependency looks OK. The OpenCensus code didn't look bad either but also looks like a lot to maintain. |
f9d0a7d
to
9642ee0
Compare
@MrAlias I updated the change log and rebased my branch onto the latest master. |
@andy-retailnext looks like the build is failing from uncommitted changes to some |
9642ee0
to
6d202ec
Compare
@MrAlias Fixed. |
@andy-retailnext if you can sync with |
http.ResponseWriters may implement additional interfaces (http.CloseNotifier, http.Flusher, http.Hijacker, http.Pusher, io.ReaderFrom) that get lost when the ResponseWriter is wrapped in another object. This change uses the httpsnoop package to wrap the ResponseWriter so that the resulting object implements any of the optional interfaces that the original ResponseWriter implements as well as using the replacement ResponseWriter methods that gather information for tracing.
6d202ec
to
234e12c
Compare
@MrAlias Done. |
http.ResponseWriters may implement additional interfaces
(http.CloseNotifier, http.Flusher, http.Hijacker, http.Pusher,
io.ReaderFrom) that get lost when the ResponseWriter is wrapped in
another object. This change uses the httpsnoop package to wrap the
ResponseWriter so that the resulting object implements any of the
optional interfaces that the original ResponseWriter implements as
well as using the replacement ResponseWriter methods that gather
information for tracing.