Open sbilello opened 3 years ago
graphql-java
comes with an instrumentation class graphql.execution.instrumentation.tracing.TracingInstrumentation
for this already as described here.
If you register this class using a @Bean
in your own code, the DGS framework will pick it up automatically.
I only now realize this issue is on the example app, and not on the framework itself. So yes, we should do exactly what I said in the previous reply for the example :-)
@sbilello sample PR https://github.com/Netflix/dgs-federation-example/pull/7/files
Thanks @berngp and @paulbakker ! I added some breakpoint to verify that the extensions are added but maybe there is something missing on the apollo-studio side of things because I don't see the tracing breakdown
query TracingTest {
shows {
id
reviews {
__typename
starRating
}
}
}
I was reading more about it in this https://www.apollographql.com/docs/federation/metrics/#gatsby-focus-wrapper and it looks like that it is not enough for apollo studio to make it work.
Accordingly to their documentation they require an ftv1
field
{
"data": {
"shows": [
{
"title": "Stranger Things"
},
{
"title": "Ozark"
},
{
"title": "The Crown"
},
{
"title": "Dead to Me"
},
{
"title": "Orange is the New Black"
}
]
},
"extensions": {
"tracing": {
"version": 1,
"startTime": "2021-05-11T21:40:35.438314Z",
"endTime": "2021-05-11T21:40:35.443742Z",
"duration": 5439178,
"parsing": {
"startOffset": 3342104,
"duration": 3316764
},
"validation": {
"startOffset": 3542869,
"duration": 166042
},
"execution": {
"resolvers": [
{
"path": [
"shows"
],
"parentType": "Query",
"returnType": "[Show]",
"fieldName": "shows",
"startOffset": 3665287,
"duration": 961267
},
{
"path": [
"shows",
0,
"title"
],
"parentType": "Show",
"returnType": "String",
"fieldName": "title",
"startOffset": 4706215,
"duration": 252633
},
{
"path": [
"shows",
1,
"title"
],
"parentType": "Show",
"returnType": "String",
"fieldName": "title",
"startOffset": 5052506,
"duration": 11554
},
{
"path": [
"shows",
2,
"title"
],
"parentType": "Show",
"returnType": "String",
"fieldName": "title",
"startOffset": 5128882,
"duration": 12249
},
{
"path": [
"shows",
3,
"title"
],
"parentType": "Show",
"returnType": "String",
"fieldName": "title",
"startOffset": 5164359,
"duration": 7933
},
{
"path": [
"shows",
4,
"title"
],
"parentType": "Show",
"returnType": "String",
"fieldName": "title",
"startOffset": 5195543,
"duration": 7960
}
]
}
}
}
}
I think we need to explicitly enable the feature in the Apollo Server. ref. https://github.com/Netflix/dgs-federation-example/pull/8
I tested this one but it is not enough to make it work. I need to find some time to try this project: https://github.com/braintree/apollo-tracing-uploader-java Thanks @berngp
Finally I found the time to integrate the apollo-tracing-uploader-java
[Disclaimer: Not polished code] I had to add just one simple class like this one:
package us.test.graphql.server.instrumentation;
import com.braintreepayments.apollo_tracing_uploader.TracingUploadInstrumentation;
import com.braintreepayments.apollo_tracing_uploader.VariablesSanitizer;
import com.braintreepayments.apollo_tracing_uploader.impl.HttpTracingUploader;
import com.braintreepayments.apollo_tracing_uploader.impl.ScheduledBatchingTraceProducer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.Duration;
import java.util.concurrent.Executors;
@Configuration
public class ApolloTracingUploadInstrumentation {
@Value("${apollo.secret}")
private String apolloSecret;
@Bean
public TracingUploadInstrumentation tracingUploadInstrumentation(ScheduledBatchingTraceProducer producer) {
return TracingUploadInstrumentation.newBuilder()
.sendTracesIf(() -> true)
.customizeTrace((trace, context) -> trace.setClientName("testClient " + context.toString()))
.sanitizeVariables(VariablesSanitizer.valuesTo("X"))
.producer(producer)
.build();
}
@Bean
public ScheduledBatchingTraceProducer scheduledBatchingTraceProducer(HttpTracingUploader httpTracingUploader) {
return ScheduledBatchingTraceProducer.newBuilder().batchingWindow(Duration.ofSeconds(1))
.threadPoolSize(1)
.customizeHeader(header -> header.setService("test-graphql-server"))
.uploader(httpTracingUploader)
.build();
}
@Bean
public HttpTracingUploader httpTracingUploader() {
return HttpTracingUploader.newBuilder()
.executor(Executors.newSingleThreadScheduledExecutor())
.apiKey(apolloSecret)
.retries(3)
.retryDelay(Duration.ofSeconds(5))
.connectTimeout(Duration.ofSeconds(5))
.readTimeout(Duration.ofSeconds(5))
.build();
}
}
There is no documentation on how to integrate it. I had to read the source code so I hope this snippet can save somebody some time!
CC: @berngp @srinivasankavitha @paulbakker
Last but not least: I also enabled the tracing: true
flag in the apollo-server for the gateway. https://github.com/apollographql/apollo-server/blob/main/packages/apollo-server-core/src/graphqlOptions.ts#L58
Do you think that would it be worth creating a dedicated module to integrate tracing with apollo or document this approach?
It's a bit easier than that. What you need to do is first import this dependency (I'm using version 0.6.4):
<dependency>
<groupId>com.apollographql.federation</groupId>
<artifactId>federation-graphql-java-support</artifactId>
<version>${graphql.federation.version}</version>
</dependency>
Next, expose a bean of type: com.apollographql.federation.graphqljava.tracing.FederatedTracingInstrumentation
For example as follows:
import com.apollographql.federation.graphqljava.tracing.FederatedTracingInstrumentation;
import graphql.execution.instrumentation.SimpleInstrumentation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class InstrumentationConfig {
@Bean
public SimpleInstrumentation tracingInstrumentation() {
return new FederatedTracingInstrumentation();
}
}
Now the DGS framework will pick up this bean and voila, tracing has been enabled in Apollo Studio.
Check out a more complete working example here.
I was playing with this demo and I noticed that the traces are not available. Is there some parameter or does need to be implemented the exposure of the fields for the tracing? Please check the apollo-tracing specification and the relative PR GraphQL-Java-PR