line / armeria

Your go-to microservice framework for any situation, from the creator of Netty et al. You can build any type of microservice leveraging your favorite technologies, including gRPC, Thrift, Kotlin, Retrofit, Reactive Streams, Spring Boot and Dropwizard.
https://armeria.dev
Apache License 2.0
4.81k stars 915 forks source link

gRPC AsyncServerInterceptor throws an exception when opentelemetry-javaagent is enabled #5937

Open kabigon-sung opened 5 days ago

kabigon-sung commented 5 days ago

Hi team, I found that the AsyncServerInterceptor throws an exception when opentelemetry-javaagent is enabled. Here is the exception and stacktrace:

截圖 2024-10-14 下午2 44 41

Armeria Version - 1.30.1

Possible root cause: The default method interceptCall in AsyncServerInterceptor creates an instance of DeferredListener. The constructor of DeferredListener performs checking on the ServerCall<I, O> call parameter. The checking requires that the passed call should be a subclass of com.linecorp.armeria.internal.server.grpc.AbstractServerCall. When opentelemetry-javagent is enabled, the original com.linecorp.armeria.server.grpc.UnaryServerCall object is replaced by io.opentelemetry.javaagent.shaded.instrumentation.grpc.v1_6.TracingServerInterceptor$TracingServerCall. Since TracingServerCall is not a subclass of AbstractServerCall, the constructor of DeferredListener throws an exception.

How to reproduce the problem

  1. Implement a AsyncServerInterceptor
    public static class MyInterceptor implements AsyncServerInterceptor {
        @Override
        public <I, O> CompletableFuture<Listener<I>> asyncInterceptCall(ServerCall<I, O> call,
                                                                        Metadata headers,
                                                                        ServerCallHandler<I, O> next) {
            final Context context = Context.current();
            return CompletableFuture.supplyAsync(() -> {
                try {
                    return context.call(() -> next.startCall(call, headers));
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            });
        }
    }
  2. Add the interceptor to the GrpcService
    sb.service(GrpcService.builder()
                                        .intercept(new MyInterceptor()) // add the interceptor
                                        .addService(new MyHelloService())
                                        .build());
  3. Download the opentelemetry-javaagent from https://github.com/open-telemetry/opentelemetry-java-instrumentation.
  4. Run the server with opentelemetry-javaagent.
  5. Sending a gRCP request causes the error.
jrhee17 commented 5 days ago

Did a local check, and it seems like the delegate method cannot be found for some reason:

스크린샷 2024-10-14 오후 6 44 01

jrhee17 commented 5 days ago

I realized delegateMH doesn't work as expected 😅 We'll fix this from armeria-side in the next version 🙏

kabigon-sung commented 5 days ago

Hi @jrhee17 , I think you are right. Thanks for checking the issues.