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

Propagate Tracing Headers in ext_proc #21119

Closed
scrocquesel opened this issue May 2, 2022 · 15 comments · Fixed by #33665
Closed

Propagate Tracing Headers in ext_proc #21119

scrocquesel opened this issue May 2, 2022 · 15 comments · Fixed by #33665
Labels
area/ext_proc enhancement Feature requests. Not bugs or questions. help wanted Needs help!

Comments

@scrocquesel
Copy link
Contributor

Title: B3 headers should be propagated to the gRPC context call

Description:

Unlike ext_authz, ext_proc do not send tracing headers. Or I don't find how to do it.

[optional Relevant Links:]

We should be able to fetch the header like in ext_authz with injectContext : #6520

@scrocquesel scrocquesel added enhancement Feature requests. Not bugs or questions. triage Issue requires triage labels May 2, 2022
@scrocquesel
Copy link
Contributor Author

@scrocquesel
Copy link
Contributor Author

From what I understand, tracing span for streaming grpc call was not implemented during #1885.

@wbpcode wbpcode added area/ext_proc and removed triage Issue requires triage labels May 3, 2022
@wbpcode
Copy link
Member

wbpcode commented May 3, 2022

cc @snowp

@wbpcode
Copy link
Member

wbpcode commented May 3, 2022

ext_proc will sends all request headers include B3 headers to the server as part of grpc requests.

So do you mean that you want to add tracing support of grpc rqeuests self?

@scrocquesel
Copy link
Contributor Author

Yes, span should begin with the start of the stream and should end at the end of it. And a child span can be created in the filter to align with how ext_authz is doing it. Use the header from the request as parent span seems not right as envoy may have create child span itself.

Maybe a new span be created for each message in the stream and pass as metadata also but it seems that gRPC tracing interceptor are not working this way. At least, https://github.com/opentracing-contrib/java-grpc/blob/master/src/main/java/io/opentracing/contrib/grpc/TracingServerInterceptor.java, is just creating a span for the whole stream and adding logs.

@scrocquesel
Copy link
Contributor Author

I tried to set the initial_metadata with %REQ(x-b3-traceid)% but if the downstream request do not have those headers, envoy generate a new trace and I don't get those values at all (stream request nor message request)

@wbpcode
Copy link
Member

wbpcode commented May 10, 2022

if the downstream request do not have those headers, envoy generate a new trace and I don't get those values at all (stream request nor message request)

This is because Envoy inject the tracing headers at the last of request header processing. So you get nothing in the ext_proc.

@wbpcode
Copy link
Member

wbpcode commented May 10, 2022

Looks like this is a general issue for the external grpc requests. But sorry I have no enough bandwidth for this recently. 😞 I will mark this help wanted.

@wbpcode wbpcode added the help wanted Needs help! label May 10, 2022
@xvzf
Copy link

xvzf commented Jan 19, 2023

@wbpcode would love to get my hands dirty on this, but don't really know where to start - wanna give me a hand?

@nahk-ivanov
Copy link

@xvzf It seems like the reason lies in the fact that ext_proc filter is using stream API, while ext_authz is using simple request/response. For request/response (aka send), there is a dedicated parent_span parameter in the gRPC client, which will eventually add tracing information to the outgoing request. For the gRPC stream API, there is no mentioning of trace headers anywhere near.

I ain't no gRPC expert, but it appears to me that with streaming, you only send the headers once and not per message, so perhaps what needs to happen is AsyncClientImpl::startRaw should be updated to take in parent_span (similar to basic send), then we spawn new child span like this in the AsyncStreamImpl constructor, and finally populate the trace headers in AsyncStreamImpl::initialize before sending them like this. I don't know if gRPC streaming API headers (Http::RequestMessagePtr) are handled anyhow different compared to basic request/response (Http::RequestHeaderMap), so there might be some additional work we need to do to adopt/shim one to another.

In the ext_proc code you can then get the span information from decoder_callbacks_ field, like this and pass it to the start (that you will modify to accept span information) here.

We were thinking to work-around this by adding a Lua filter at the beginning of the filter chain, that will inject tracing header(s) with our manually generated IDs, so that we can reference it through initial_metadata with %REQ(..) and therefore share between main request processing pipeline and calls to ext_proc, but it seems like that is not going to work either, because connection manager will generate new Span structure at the beginning before calling filters (which I assume makes sense, as filters can log/trace), and that structure is used throughout the code, instead of reading headers all the time. It doesn't seem to care about any headers' changes afterwards. So you will still get different IDs in the main processing pipeline and everything that tries to read the trace id from the headers, unless I missed something.

@wbpcode
Copy link
Member

wbpcode commented Mar 29, 2023

cc @xvzf sorry for the delayed respnose. I almost forget this PR. But I think @nahk-ivanov has given a great explanation about this work.
Sorry again for the delay.

@cainelli
Copy link
Contributor

It's been some time since the last comment. Is there an update on this issue? We're transitioning from Lua filters to exproc, but it appears that traces are still not being propagated to the grpc server.

@cainelli
Copy link
Contributor

cainelli commented Apr 16, 2024

I'm really interested on this and decided to take a stab #33665. Thank you for the very detailed pointers @nahk-ivanov, it was sufficient for one with no prior C++ knowledge to follow. I would appreciate any review.

@nahk-ivanov
Copy link

@cainelli LEGEND!!!!

htuch pushed a commit that referenced this issue Jun 14, 2024
Following up on #33665, which adds tracing to Envoy gRPC streams, this PR introduces the same support using Google gRPC for completeness to #21119.

Risk Level: Low
Testing: The same manual tests described in #33665, besides the integration tests of extproc are also testing google grpc now.

Signed-off-by: Fernando Cainelli <fernando.cainelli-external@getyourguide.com>
Nealsoni00 pushed a commit to Nealsoni00/envoy that referenced this issue Jun 18, 2024
…proxy#34395)

Following up on envoyproxy#33665, which adds tracing to Envoy gRPC streams, this PR introduces the same support using Google gRPC for completeness to envoyproxy#21119.

Risk Level: Low
Testing: The same manual tests described in envoyproxy#33665, besides the integration tests of extproc are also testing google grpc now.

Signed-off-by: Fernando Cainelli <fernando.cainelli-external@getyourguide.com>
Signed-off-by: Neal Soni <Nealsoni00@gmail.com>
@ekkinox
Copy link

ekkinox commented Sep 30, 2024

coming after the war but @cainelli thanks a lot for this work !!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/ext_proc enhancement Feature requests. Not bugs or questions. help wanted Needs help!
Projects
None yet
6 participants