Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GraphQL + Spring Boot: how to collect (error) metrics?

I've been working on adding monitoring metrics in our GraphQL gateway recently.

We're using graphql-spring-boot starter for the gateway.

After reading the following documentations, I manage to send the basic graphql.timer.query.* metrics to Datadog

  • https://www.baeldung.com/spring-boot-actuators
  • https://docs.spring.io/spring-boot/docs/2.0.x/actuator-api/html/#metrics
  • https://github.com/graphql-java-kickstart/graphql-spring-boot#tracing-and-metrics

What I've achieved so far is, when I send a GraphQL query/mutation, I'd collect the request count and time accordingly. e.g. sending the query below

query HelloWorldQuery {
  greeting(
    name: "Bob"
  ) {
    message
  }
}

I'll see metrics graphql.timer.query.count / graphql.timer.query.sum with tags operationName=HelloWorldQuery

It works like perfectly, until I want to test a query with errors. I realise there is no metrics/tags related to a failed query. For example, if I the above query returns null data and some GraphQL errors, I'd still collect graphql.timer.query.count (operationName=HelloWorldQuery), but there's no additional tags for me to tell there is an error for that query.

In the gateway, I have implemented a custom GraphQLErrorHandler, so I was thinking maybe I should add error counter (via MeterRegistry) in that class, but I am unable to get the operationName simply from GraphQLError type. the best I can get is error.getPath() which gives the method name (e.g. greeting) rather than the custom query name (HelloWorldQuery - to be consistent with what graphql.timer.query.* provides).

My question is, how to solve the above problem? And generally what is the best way of collecting GraphQL query metrics (including errors)?

------------------- Update -------------------

2019-12-31 I read a bit more about GraphQL Instrumentation here and checked the MetricsInstrumentation implementation in graphql-spring-boot repo, the I have an idea of extending the MetricsInstrumentation class by adding error metrics there.

2020-01-02 I tried to ingest my CustomMetricsInstrumentation class, but with no luck. There is internal AutoConfiguration wiring, which I cannot insert my auto configuration in the middle.

like image 266
xialin Avatar asked Oct 17 '25 16:10

xialin


1 Answers

You can override the default TracingInstrumentation with your own implementation. It will be picked automatically due to the @ConditionalOnMissingBean annotation in the GraphQLInstrumentationAutoConfiguration class. Here is a simple example that adds two custom metrics: graphql.counter.query.success and graphql.counter.query.error:

@Component
public class CustomMetricsInstrumentation extends TracingInstrumentation {

    private static final String QUERY_STATUS_COUNTER_METRIC_NAME = "graphql.counter.query";
    private static final String OPERATION_NAME_TAG = "operationName";
    private static final String UNKNOWN_OPERATION_NAME = "unknown";

    private MeterRegistry meterRegistry;

    public CustomMetricsInstrumentation(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
    }

    @Override
    public CompletableFuture<ExecutionResult> instrumentExecutionResult(ExecutionResult executionResult,
                                                                        InstrumentationExecutionParameters parameters) {

        String status = CollectionUtils.isEmpty(executionResult.getErrors()) ? "success" : "error";
        String operation = parameters.getOperation() != null ? parameters.getOperation() : UNKNOWN_OPERATION_NAME;
        Collection<Tag> tags = Arrays.asList(Tag.of(OPERATION_NAME_TAG, operation));

        meterRegistry.counter(QUERY_STATUS_COUNTER_METRIC_NAME + "." + status, tags).increment();

        return super.instrumentExecutionResult(executionResult, parameters);
    }
}

My application.yaml, just in case:

graphql:
  servlet:
    tracing-enabled: true
    actuator-metrics: true
management:
  endpoint:
  metrics:
    enabled: true
  endpoints:
    web:
      exposure:
        include: health,metrics

I'm using spring-boot-starter-parent:2.2.2.RELEASE, graphql-spring-boot-starter:6.0.0

I hope it helps.

like image 180
Mafor Avatar answered Oct 20 '25 08:10

Mafor



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!