Tracing of logs with @Scheduled in spring boot 3.0
Asked Answered
S

2

5

Since moving to spring boot 3.0 tracing has stopped working with scheduled jobs @Scheduled(fixedDelay = 69, timeUnit = TimeUnit.SECONDS)

According to migration docs we should be wrapping the executor service with ContextScheduledExecutorService.wrap() https://github.com/micrometer-metrics/tracing/wiki/Spring-Cloud-Sleuth-3.1-Migration-Guide#async-instrumentation

And according to spring docs we should be able to do it like this

@Configuration
    @EnableScheduling
    public class AppConfig implements SchedulingConfigurer {

        @Override
        public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
            taskRegistrar.setScheduler(taskExecutor());
        }

        @Bean(destroyMethod="shutdown")
        public Executor taskExecutor() {
            return ContextScheduledExecutorService.wrap(Executors.newScheduledThreadPool(100));
        }
    }

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/annotation/EnableScheduling.html

The correct scheduler is being used as I can see custom thread name when setting one, but log tracing does not show up (traceId, spanId). Otherwise tracing works as I can see it when calling api methods in same application.

Semiliquid answered 6/1, 2023 at 11:52 Comment(0)
K
7

I also faced the same issue and found some solution which worked for me. You can do something like this.

import io.micrometer.tracing.Tracer;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
@RequiredArgsConstructor
public class ScheduledSpanAspect {
  private final Tracer tracer;

  @Pointcut("@annotation(org.springframework.scheduling.annotation.Scheduled)")
  public void annotatedWithScheduled() {}

  @Around("annotatedWithScheduled()")
  public Object wrapScheduledIntoSpan(ProceedingJoinPoint pjp) throws Throwable {
    var methodName = pjp.getSignature().getDeclaringTypeName() + "." + pjp.getSignature().getName();

    var span = tracer.nextSpan()
        .name(methodName)
        .start();
    try (var ignoredSpanInScope = tracer.withSpan(span.start())) {
      return pjp.proceed();
    } finally {
      span.end();
    }
  }
}

Find it here

Kwon answered 25/1, 2023 at 9:51 Comment(0)
G
4

Update: This should be available from Spring Boot 3.2.0 / Spring Framework 6.1.0 (2023 November).

We are planning to add it in the future: https://github.com/spring-projects/spring-framework/issues/29883

In the meantime, as a workaround, you can add an @Observed annotation (+create an ObservedAspect bean) on your @Scheduled method or create an Observation manually in it.

Gorski answered 31/5, 2023 at 19:8 Comment(2)
Fixed on 3.2.0-M1 I've confirmed the fix on 3.2.0-M3. The RC is scheduled for 19/10. See the issue pageMildredmildrid
Works on 3.2.0. Thanks!Ferri

© 2022 - 2024 — McMap. All rights reserved.