Using a custom ThreadPoolTaskExecutor bean I'd expect it to be picked up by TaskExecutorMetricsAutoConfiguration to provide me with the metrics.
But when using the spring.main.lazy-initialization=true it doesn't bind the metrics. Also marking the bean with @Lazy(false) doesn't help.
Using Spring Boot 3.1.4 (but same issue on 3.0.x)
Code to reproduce:
@SpringBootApplication
public class DemoApplication {
@Bean(name = "custom")
ThreadPoolTaskExecutor webhookTaskExecutor(TaskExecutorBuilder builder) {
builder.awaitTermination(false);
return builder.build();
}
@Bean
ApplicationRunner applicationRunner(ThreadPoolTaskExecutor executor) {
return args -> {
executor.submit(() -> System.out.println("Hello World")).get();
};
}
public static void main(String[] args) {
var app = new SpringApplication(DemoApplication.class);
app.setDefaultProperties(Map.of("spring.main.lazy-initialization","true"));
var ctx = app.run(args);
System.out.println(ctx.getBean(MeterRegistry.class).get("executor.completed").tags("name", "custom").meters().size());
}
}
It fails with
Exception in thread "main" io.micrometer.core.instrument.search.MeterNotFoundException: Unable to find a meter that matches all the requirements at once. Here's what was found:
FAIL: No meter with name 'executor.completed' was found.
FAIL: No meters have the required tag 'name'.
at io.micrometer.core.instrument.search.MeterNotFoundException$FromRequiredSearch.build(MeterNotFoundException.java:245)
at io.micrometer.core.instrument.search.MeterNotFoundException$FromRequiredSearch.access$100(MeterNotFoundException.java:49)
at io.micrometer.core.instrument.search.MeterNotFoundException.forSearch(MeterNotFoundException.java:46)
at io.micrometer.core.instrument.search.RequiredSearch.meters(RequiredSearch.java:220)
at com.example.demo.DemoApplication.main(DemoApplication.java:37)
Comment From: wilkinsona
Thanks for the report. As far as I can tell, this isn't specific to custom executors and affects the auto-configured executor as well.
You can work around the problem by excluding TaskExecutorMetricsAutoConfiguration from lazy initialization:
@Bean
static LazyInitializationExcludeFilter eagerTaskExecutorMetrics() {
return LazyInitializationExcludeFilter.forBeanTypes(TaskExecutorMetricsAutoConfiguration.class);
}