Suresh Naik
Suresh Naik

Reputation: 305

How to enable ExecutorServiceMetrics in SpringBoot 2.1.2?

How to enable ExecutorServiceMetrics listed here ?

https://github.com/micrometer-metrics/micrometer/blob/master/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/ExecutorServiceMetrics.java

SpringBoot version: 2.1.2.RELEASE

Under /actuator/metrics I can see jvm and some other outofbox auto configured metrics, but not executor metrics.

I have tried setting this, but no luck.

management:
  metrics:
    enable.executor: true

any help is appreciated.

Upvotes: 7

Views: 12420

Answers (4)

袁文涛
袁文涛

Reputation: 856

If you don't know whether a meterRegistry bean exists, you could try to use ObjectProvider

@Configuration
public class ExecutorConfig {
    @Bean
    public ExecutorService executorService(ObjectProvider<MeterRegistry> meterRegistryProvider) {
        ExecutorService executorService = Executors.newFixedThreadPool(20);
        meterRegistryProvider.ifAvailable(registry -> ExecutorServiceMetrics.monitor(registry, executorService, "my executor", Tags.of("key", "value")));
        return executorService;
    }
}

Upvotes: 1

Ian Rowlands
Ian Rowlands

Reputation: 173

I found that you had to do it manually if you want to lock it in with Spring Boot. I'm using Spring Boot 2.2.9.RELEASE.

Create a ExecutorServiceMetrics bean, using the "applicationTaskExecutor" bean (that way, you get whatever bean size has previously been configured). It will automatically get bound.

Something like:

@Bean
@ConditionalOnMissingBean
public ExecutorServiceMetrics executorServiceMetrics(@Qualifier("applicationTaskExecutor") ThreadPoolTaskExecutor applicationTaskExecutor) {
    return new ExecutorServiceMetrics(applicationTaskExecutor.getThreadPoolExecutor(), "applicationTaskExecutor",
            Collections.emptyList());
}

Upvotes: 4

Derlin
Derlin

Reputation: 9881

Here is how I solved it (in kotlin):

@EnableAsync
@Configuration
class AsyncConfig(
        private val taskExecutorBuilder: TaskExecutorBuilder,
        private val meterRegistry: MeterRegistry) : AsyncConfigurer {

    /**
     * Add monitoring of executor using micrometer.
     */
    override fun getAsyncExecutor(): Executor {
        // create executor based on default spring-boot properties
        val executor = taskExecutorBuilder.build()
        // we need to initialize it before calling monitor
        executor.initialize()
        // monitor the executor (so it is available in metrics) (must be wrapped)
        return ExecutorServiceMetrics.monitor(meterRegistry, executor.threadPoolExecutor, "AsyncExecutor", "async")
    }

}

So basically:

  • make use of the autowired TaskExecutorBuilder so the executor is built depending on the spring.task.execution.* properties
  • wrap the thread pool executor in ExecutorServiceMetrics (from io.micrometer.core) to get the metrics

Note that for this to work, you must return the decorated executor !

In this example and since I gave a prefix (async), the metrics available are:

  • async.executor
  • async.executor.active
  • async.executor.completed
  • async.executor.idle
  • async.executor.pool.core
  • async.executor.pool.max
  • async.executor.pool.size
  • async.executor.queue.remaining
  • async.executor.queued

Upvotes: 0

jolo
jolo

Reputation: 771

I was able to get ExecutorServiceMetrics reporting metrics in a Spring Boot 2.1.2.RELEASE app and didn't have to do any more than create a monitored ExecutorService bean. I didn't have to add anything to my application.yml or application.properties to make this work.

Example:

@Configuration
public class ExecutorConfig {

    @Bean
    public ExecutorService executorService(final MeterRegistry registry) {
        return ExecutorServiceMetrics.monitor(registry, Executors.newFixedThreadPool(20), "my executor", Tags.of("key", "value"));
    }
}

Then, just wire your executorService bean into your components and submit tasks to that executorService bean.

Upvotes: 8

Related Questions