-
Notifications
You must be signed in to change notification settings - Fork 628
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
Add traceresponse headers for asgi apps (FastAPI, Starlette) #817
Add traceresponse headers for asgi apps (FastAPI, Starlette) #817
Conversation
67ff3c6
to
03c1f55
Compare
@@ -17,6 +22,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
|
|||
## [1.7.1-0.26b1](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v1.7.0-0.26b0) - 2021-11-11 | |||
|
|||
### Added |
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 wasn't included in the last release but seemed like the right format
headers = [] | ||
carrier["headers"] = headers | ||
|
||
headers.append([key.lower().encode(), value.encode()]) |
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 know the Access-Control-Expose-Headers
usually is cased, but the docs explicitly say lowercase.
self.send_input({"type": "websocket.disconnect"}) | ||
_, socket_send, *_ = self.get_all_output() | ||
|
||
# traceresponse header corresponds to the 2nd websocket.send span |
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.
Same question here about which span exactly should be returned.
self.seed_app(app) | ||
self.send_default_request() | ||
|
||
# traceresponse header corresponds to http.response.start span |
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 one was a bit surprising to me, I'm not so sure it makes intuitive sense at first glance. I kind of feel like the span returned in the response header should be the final "kind": trace_api.SpanKind.SERVER
span.
What do you think?
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.
Yes, response headers should represent the SERVER span.
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.
Got it, done!
@owais anything else we need to do here? |
headers = [] | ||
carrier["headers"] = headers | ||
|
||
headers.append([key.lower().encode(), value.encode()]) |
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.
Might be a stupid question but why do we encode the key and values in the header? Is this because asgi requires them to be byte strings?
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.
@lzchen good question, it's non-obvious. From the spec:
Keys:
type (Unicode string) – "http.response.start".
status (int) – HTTP status code.
headers (Iterable[[byte string, byte string]]) – An iterable of [name, value] two-item iterables, where name is the > header name, and value is the header value. Order must be preserved in the HTTP response. Header names must be lowercased. Optional; if missing defaults to an empty list. Pseudo headers (present in HTTP/2 and HTTP/3) must not be present.
Important parts:
- headers (Iterable[[byte string, byte string]]) - spec says they should be encoded
- Header names must be lowercased
6c9afa6
to
18e8cab
Compare
4ab8ea2
to
33d98b0
Compare
@owais hopefully this is the last one, latest changes includes fixes for Pylint from the failure at https://github.com/open-telemetry/opentelemetry-python-contrib/runs/4598037270?check_suite_focus=true
|
33d98b0
to
de560ed
Compare
otel_send = self._get_otel_send( | ||
span, | ||
span_name, | ||
trace.context_api.get_current(), |
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.
At line 328, we start a SERVER span explicitly and it is present in the scope bound to the variable span
. I recommend renaming that variable to server_span
and then using it directly instead of relying on context API to fetch current context. This would be a lot more explicit and the intention would be very obvious making future contributions easier.
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.
Got it, great suggestion!
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.
Looks good. Suggest one last simplification before we can merge.
This asgi version is modeled after the original wsgi version in open-telemetry#436 and corresponds to the SERVER span. Also cleans up some of the existing ASGI functionality to reduce complexity and make future contributions more straightforward.
de560ed
to
d0d2422
Compare
context=set_span_in_context( | ||
server_span, trace.context_api.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.
IMO this is a bit obtuse but I'm sure there is a good extensibility reason for it. What I really wanted to do was:
propagator.inject(
message,
span=server_span,
setter=asgi_setter,
)
But for now I will consider this yak shaved!
@owais latest updates include an update from dev and also all of my previous commits squashed together. Thanks for reviewing! |
Description
Adds a
traceresponse
header for ASGI apps just like the WSGI version in #436.Fixes #803
Type of change
Please delete options that are not relevant.
How Has This Been Tested?
Yes. Added unit tests to assert whether or not the
traceresponse
header is included.Does This PR Require a Core Repo Change?
Checklist:
See contributing.md for styleguide, changelog guidelines, and more.