4

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.

Suresh Naik
  • 275
  • 4
  • 11

4 Answers4

7

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.

jolo
  • 751
  • 4
  • 6
3

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());
}
user944849
  • 14,524
  • 2
  • 61
  • 83
Ian Rowlands
  • 153
  • 1
  • 11
0

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
Derlin
  • 9,572
  • 2
  • 32
  • 53
0

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

@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;
    }
}
袁文涛
  • 735
  • 1
  • 10
  • 23