Search code examples
spring-webfluxmicrometer-tracingspring-boot-3armeria

BraveService decorator fails to propagate context on gRPC service in Armeria


I am serving a gRPC service with Armeria, Spring Boot 3, and WebFlux. I want to use Brave to print traceId and spanId to the log. I used the following guide (https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#actuator.micrometer-tracing) to configure Brave. I also adapted the configuration in Micrometer's guide for Context-Propagation in WebFlux. However, these configurations only work well with Spring Controller.

They do not apply to the gRPC service being served by Armeria.

So I added a decorator to Armeria using BraveService as follows. Tracing is set up to use MDC.

@Bean
public ArmeriaServerConfigurator armeriaServerConfigurator() {

    Tracing tracing = Tracing.newBuilder()
        .currentTraceContext(
            RequestContextCurrentTraceContext.builder()
                .addScopeDecorator(MDCScopeDecorator.get())
                .build())
            ...
            .build();
    return builder -> builder
        .service(grpcService()) // any implementations of grpc services
        .decorator(BraveService.newDecorator(tracing));
}

With this implementation, only the gRPC Service that receives the gRPC request will write the traceId and spanId to the log correctly. However, the traceId and spanId are not propagated to the other threads that the gRPC service calls in the project.

Below is an example of a log.

2023-08-28T22:23:38.263+09:00  INFO [Armeria WebFlux,d3d5b84a174e6bbb,d3d5b84a174e6bbb] 39599 --- [rker-kqueue-3-2] c.m.a.grpc.TestGrpcService               : traceId: d3d5b84a174e6bbb
2023-08-28T22:23:38.266+09:00  INFO [Armeria WebFlux,,] 39599 --- [oundedElastic-1] c.m.a.service.JustService                : traceId: null
2023-08-28T22:23:38.266+09:00  INFO [Armeria WebFlux,,] 39599 --- [     parallel-1] c.m.a.repository.JustRepository          : traceId: null

I've been searching for something related but haven't found anything that might give me a hint, please help. Thanks in advance.


Solution

  • I found the answer.

    Armeria supports Spring WebFlux, but it's not Spring WebFlux. Armeria has its own context propagation method, so the following configuration will not work.

    Hooks.enableAutomaticContextPropagation();
    

    Instead, you can use the following context tools for Armeria

    import com.linecorp.armeria.common.reactor3.RequestContextHooks;
    ...
    RequestContextHooks.enable();
    

    This needs armeria-reactor3 dependency and will allow you to propagate the context. The Brave configuration works fine.