Skip to content

Commit

Permalink
Make TaskExecution and TaskScheduling metrics unique
Browse files Browse the repository at this point in the history
Fixes gh-28536
  • Loading branch information
scottfrederick committed Nov 15, 2021
1 parent a1e7375 commit d7f8931
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 55 deletions.
Expand Up @@ -19,7 +19,6 @@
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.function.Supplier;

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.binder.jvm.ExecutorServiceMetrics;
Expand All @@ -36,14 +35,14 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.util.StringUtils;

/**
* {@link EnableAutoConfiguration Auto-configuration} for metrics on all available
* {@link ThreadPoolTaskExecutor task executors} and {@link ThreadPoolTaskScheduler task
* schedulers}.
*
* @author Stephane Nicoll
* @author Scott Frederick
* @since 2.6.0
*/
@Configuration(proxyBeanMethods = false)
Expand All @@ -53,27 +52,21 @@
@ConditionalOnBean({ Executor.class, MeterRegistry.class })
public class TaskExecutorMetricsAutoConfiguration {

private static final String TASK_EXECUTOR_SUFFIX = "taskExecutor";

private static final String TASK_SCHEDULER_SUFFIX = "taskScheduler";

@Autowired
public void bindTaskExecutorsToRegistry(Map<String, Executor> executors, MeterRegistry registry) {
executors.forEach((beanName, executor) -> {
if (executor instanceof ThreadPoolTaskExecutor) {
monitor(registry, safeGetThreadPoolExecutor((ThreadPoolTaskExecutor) executor),
() -> getTaskExecutorName(beanName));
monitor(registry, safeGetThreadPoolExecutor((ThreadPoolTaskExecutor) executor), beanName);
}
else if (executor instanceof ThreadPoolTaskScheduler) {
monitor(registry, safeGetThreadPoolExecutor((ThreadPoolTaskScheduler) executor),
() -> getTaskSchedulerName(beanName));
monitor(registry, safeGetThreadPoolExecutor((ThreadPoolTaskScheduler) executor), beanName);
}
});
}

private void monitor(MeterRegistry registry, ThreadPoolExecutor threadPoolExecutor, Supplier<String> beanName) {
private void monitor(MeterRegistry registry, ThreadPoolExecutor threadPoolExecutor, String name) {
if (threadPoolExecutor != null) {
ExecutorServiceMetrics.monitor(registry, threadPoolExecutor, beanName.get());
ExecutorServiceMetrics.monitor(registry, threadPoolExecutor, name);
}
}

Expand All @@ -95,33 +88,4 @@ private ThreadPoolExecutor safeGetThreadPoolExecutor(ThreadPoolTaskScheduler tas
}
}

/**
* Get the name of a {@link ThreadPoolTaskExecutor} based on its {@code beanName}.
* @param beanName the name of the {@link ThreadPoolTaskExecutor} bean
* @return a name for the given task executor
*/
private String getTaskExecutorName(String beanName) {
if (beanName.length() > TASK_EXECUTOR_SUFFIX.length()
&& StringUtils.endsWithIgnoreCase(beanName, TASK_EXECUTOR_SUFFIX)) {
return beanName.substring(0, beanName.length() - TASK_EXECUTOR_SUFFIX.length());
}
return beanName;
}

/**
* Get the name of a {@link ThreadPoolTaskScheduler} based on its {@code beanName}.
* @param beanName the name of the {@link ThreadPoolTaskScheduler} bean
* @return a name for the given task scheduler
*/
private String getTaskSchedulerName(String beanName) {
if (beanName.equals(TASK_SCHEDULER_SUFFIX)) {
return "application";
}
if (beanName.length() > TASK_SCHEDULER_SUFFIX.length()
&& StringUtils.endsWithIgnoreCase(beanName, TASK_SCHEDULER_SUFFIX)) {
return beanName.substring(0, beanName.length() - TASK_SCHEDULER_SUFFIX.length());
}
return beanName;
}

}
Expand Up @@ -41,6 +41,7 @@
* Tests for {@link TaskExecutorMetricsAutoConfiguration}.
*
* @author Stephane Nicoll
* @author Scott Frederick
*/
class TaskExecutorMetricsAutoConfigurationTests {

Expand All @@ -53,8 +54,8 @@ void taskExecutorUsingAutoConfigurationIsInstrumented() {
.run((context) -> {
MeterRegistry registry = context.getBean(MeterRegistry.class);
Collection<FunctionCounter> meters = registry.get("executor.completed").functionCounters();
assertThat(meters).singleElement()
.satisfies((meter) -> assertThat(meter.getId().getTag("name")).isEqualTo("application"));
assertThat(meters).singleElement().satisfies(
(meter) -> assertThat(meter.getId().getTag("name")).isEqualTo("applicationTaskExecutor"));
});
}

Expand All @@ -64,8 +65,8 @@ void taskExecutorsWithCustomNamesAreInstrumented() {
.withBean("customName", ThreadPoolTaskExecutor.class, ThreadPoolTaskExecutor::new).run((context) -> {
MeterRegistry registry = context.getBean(MeterRegistry.class);
Collection<FunctionCounter> meters = registry.get("executor.completed").functionCounters();
assertThat(meters).map((meter) -> meter.getId().getTag("name")).containsExactlyInAnyOrder("first",
"customName");
assertThat(meters).map((meter) -> meter.getId().getTag("name"))
.containsExactlyInAnyOrder("firstTaskExecutor", "customName");
});
}

Expand All @@ -77,8 +78,8 @@ void threadPoolTaskExecutorWithNoTaskExecutorIsIgnored() {
.withBean("customName", ThreadPoolTaskExecutor.class, () -> unavailableTaskExecutor).run((context) -> {
MeterRegistry registry = context.getBean(MeterRegistry.class);
Collection<FunctionCounter> meters = registry.get("executor.completed").functionCounters();
assertThat(meters).singleElement()
.satisfies((meter) -> assertThat(meter.getId().getTag("name")).isEqualTo("first"));
assertThat(meters).singleElement().satisfies(
(meter) -> assertThat(meter.getId().getTag("name")).isEqualTo("firstTaskExecutor"));
});
}

Expand All @@ -87,8 +88,8 @@ void taskExecutorInstrumentationCanBeDisabled() {
this.contextRunner.withPropertyValues("management.metrics.enable.executor=false")
.withConfiguration(AutoConfigurations.of(TaskExecutionAutoConfiguration.class)).run((context) -> {
MeterRegistry registry = context.getBean(MeterRegistry.class);
assertThat(registry.find("executor.completed").tags("name", "application").functionCounter())
.isNull();
assertThat(registry.find("executor.completed").tags("name", "applicationTaskExecutor")
.functionCounter()).isNull();
});
}

Expand All @@ -99,7 +100,7 @@ void taskSchedulerUsingAutoConfigurationIsInstrumented() {
MeterRegistry registry = context.getBean(MeterRegistry.class);
Collection<FunctionCounter> meters = registry.get("executor.completed").functionCounters();
assertThat(meters).singleElement()
.satisfies((meter) -> assertThat(meter.getId().getTag("name")).isEqualTo("application"));
.satisfies((meter) -> assertThat(meter.getId().getTag("name")).isEqualTo("taskScheduler"));
});
}

Expand All @@ -109,8 +110,8 @@ void taskSchedulersWithCustomNamesAreInstrumented() {
.withBean("customName", ThreadPoolTaskScheduler.class, ThreadPoolTaskScheduler::new).run((context) -> {
MeterRegistry registry = context.getBean(MeterRegistry.class);
Collection<FunctionCounter> meters = registry.get("executor.completed").functionCounters();
assertThat(meters).map((meter) -> meter.getId().getTag("name")).containsExactlyInAnyOrder("first",
"customName");
assertThat(meters).map((meter) -> meter.getId().getTag("name"))
.containsExactlyInAnyOrder("firstTaskScheduler", "customName");
});
}

Expand All @@ -122,8 +123,8 @@ void threadPoolTaskSchedulerWithNoTaskExecutorIsIgnored() {
.withBean("customName", ThreadPoolTaskScheduler.class, () -> unavailableTaskExecutor).run((context) -> {
MeterRegistry registry = context.getBean(MeterRegistry.class);
Collection<FunctionCounter> meters = registry.get("executor.completed").functionCounters();
assertThat(meters).singleElement()
.satisfies((meter) -> assertThat(meter.getId().getTag("name")).isEqualTo("first"));
assertThat(meters).singleElement().satisfies(
(meter) -> assertThat(meter.getId().getTag("name")).isEqualTo("firstTaskScheduler"));
});
}

Expand All @@ -133,7 +134,7 @@ void taskSchedulerInstrumentationCanBeDisabled() {
.withConfiguration(AutoConfigurations.of(TaskSchedulingAutoConfiguration.class))
.withUserConfiguration(SchedulingTestConfiguration.class).run((context) -> {
MeterRegistry registry = context.getBean(MeterRegistry.class);
assertThat(registry.find("executor.completed").tags("name", "application").functionCounter())
assertThat(registry.find("executor.completed").tags("name", "taskScheduler").functionCounter())
.isNull();
});
}
Expand Down

0 comments on commit d7f8931

Please sign in to comment.