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
Apollo Federation and Apollo Opentracing #293
Comments
I am unsure how apollo federation works, does it allow you to write the resolvers for the services yourself? |
@DanielMSchmidt There is a good blog post about it here: https://blog.apollographql.com/apollo-federation-f260cf525d21 It has a gateway layer which gets the GraphQL queries and then the gateway knows which portion of the query to send to which microservice. So, it splits the GQL query to multiple services where resolvers are written and then gets the aggregated response from all the services back to the gateway. |
@tvvignesh Hello, looking for the same thing, did u manage to find solution? |
@DotSpy None out of the box as of now since Federation is pretty new. We have to manually instrument the services using open tracing and trace it using jaeger. |
@tvvignesh i stuck at gateway, because i'm not used to JS, i would really appreciate if u can provide some pieces of code for it |
I was able to get this to work by using a custom datasource and overriding the willSendRequest() call. On the |
For now u can use just https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-node |
@sysadmind can you share your |
@nadilas i tried this solution, to use it u need not only custom GraphQLDataSource but also change sources of apollo server. For now i suggest u just to include opentelemetry-js |
@DotSpy thanks. I may oversimplify this, but wouldn’t setting the span Id in the outgoing header and setting that as a parent id on the root span solve the stitching issue? |
@nadilas yeap, it will, but to do so you need receive parent id via context as @sysadmind told |
Here is the willSendRequest that I was able to use. Note that you need to implement the context willSendRequest({ request, context }) {
const tracer = opentracing.globalTracer();
const networkSpan = tracer.startSpan('federated request', {
childOf: context.rootSpan ? context.rootSpan : undefined,
});
let injectHeaders = {};
tracer.inject(networkSpan, opentracing.FORMAT_HTTP_HEADERS, injectHeaders);
for (const [key, value] of Object.entries(injectHeaders)) {
request.http.headers.set(key, value);
}
return () => {
networkSpan.finish();
};
} |
thanks for sharing @sysadmind. Let me check if I got this right. You are using By "implement the context" you probably something Edit: I just realized you meant in the gateway and not within the federated service - as it already extracts incoming headers. One more thing, are you sure |
context: ({ req }) => {
var externalSpan =
req && req.headers
? tracer.extract(opentracing.FORMAT_HTTP_HEADERS, req.headers)
: undefined;
return {
rootSpan: externalSpan,
};
},
|
Thanks great summary! Sounds about right :-) What I still can’t figure out is, how I can attach the federated service to the span of the field which actually initiated the call to the federated service. I haven’t tested this yet, but it will attach all federated calls to the root and hence show a different (faster) timeline than what actually happens, right? I somehow fear that without info on willSendRequest we would need to hook into the fieldWillResolve and overwrite the rootSpan with the one from Info.span so we can grab that particular field. Now the only question is, what happens in race scenarios? Maybe a map on context (url => span) would solve this, if we had the url available. |
@nadilas few weeks ago i did https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-propagator-jaeger , u can try to use it |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Hi. May I know how does this work with Apollo Federation in place where the Apollo Gateway is going to send requests to multiple different microservices behind the scenes? In such cases, how do we configure this - At the gateway level or service level? Any sample implementations behind this?
Thanks in advance.
The text was updated successfully, but these errors were encountered: