2

We have Sleuth enabled on all endpoints Spring 2.7.x ( that comes out of the box). Just plain and simple traceId/spanId tracking. Now as in Spring Sleuth is no more available in Spring Boot 3.0.0. Is there a way to enable this new Observation Api on all endpoints.

Before had this:

/*
 List all beers in database
 */
public Mono<ServerResponse> listBeer() {
    return beerService.listBeers(null,  null, PageRequest.ofSize(50), true)
            .flatMap(beerDto -> ServerResponse.ok().bodyValue(beerDto))
            .switchIfEmpty(ServerResponse.notFound().build());


}

Now with new Api in every endpoint need to do this:

/*
 List all beers in database
 */
public Mono<ServerResponse> listBeer() {
    Observation observation = Observation.start("listBeer-sample", observationRegistry);
    return Mono.just(observation).flatMap(span -> {

                observation.scoped(() -> log.info("I can fetch trace id <TRACE:{}> ",
                        this.tracer.currentSpan().context().traceId())
                );
                return beerService.listBeers(null, null, PageRequest.ofSize(50), true)
                        .flatMap(beerDto -> ServerResponse.ok().bodyValue(beerDto))
                        .switchIfEmpty(ServerResponse.notFound().build());
            }).doFinally(signalType -> observation.stop())
            .contextWrite(context -> context.put(ObservationThreadLocalAccessor.KEY, observation));

}

}

Is there a way to enable traceId/spanId out of the box on all endpoints without all of this clutter?

Levijatanu
  • 371
  • 2
  • 17
  • You should be able to make this an `ExchangeFunction` and use that as a filter when creating the `WebClient`. That way it will apply to all the requests done with the `WebClient`. You can take a look on how Zipkin did it and then take that approach again. Should be a matter of configuration. – M. Deinum Dec 08 '22 at 07:54
  • @M.Deinum can some example of this be found? – Levijatanu Dec 08 '22 at 08:47
  • On hindsight I believe that should work out of the box if the right dependencies are on the classpath. That is what the [`WebFluxObservationAutoConfiguration`](https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfiguration.java) should setup. Using `tap` should be all you need (if I read correctly). See also https://tanzu.vmware.com/developer/guides/observability-reactive-spring-boot-3/ – M. Deinum Dec 08 '22 at 09:36

2 Answers2

1

Currently there's no other way but to be a little bit more verbose and use the tap or handle operator that will automatically put observations in scope. We will be working on better, automated solutions in the future

Marcin Grzejszczak
  • 10,624
  • 1
  • 16
  • 32
  • G. Is there some examples of tap or handle operator to be found? We are looking most generic/simple solution where traceId will be propagated through our services and callbacks. – Levijatanu Dec 09 '22 at 06:37
  • 1
    Check this out https://micrometer.io/docs/observation#instrumentation_of_reactive_libraries – Marcin Grzejszczak Dec 13 '22 at 10:31
  • 1
    @Levijatanu have a look at this article: https://openvalue.blog/posts/2022/12/16/tracing-in-spring-boot-2-and-3/ – dbaltor Feb 28 '23 at 16:37
0

Based on your description, I think you want to integrate micrometar without changing the original code

Fortunately it can be implemented through @Observed + aop

You can refer to the official documentation Refer to Section 4.6 observation

add config code

  @Bean
  public ObservedAspect observedAspect(ObservationRegistry observationRegistry) {
      return new ObservedAspect(observationRegistry, this::skipControllers);
  }
 
  private boolean skipControllers(ProceedingJoinPoint pjp) {
      Class<?> targetClass = pjp.getTarget().getClass();
      return targetClass.isAnnotationPresent(RestController.class) || targetClass.isAnnotationPresent(Controller.class);
  }
Jilliss
  • 119
  • 7