Skip to content

Commit d7f8931

Browse files
Make TaskExecution and TaskScheduling metrics unique
Fixes gh-28536
1 parent a1e7375 commit d7f8931

File tree

2 files changed

+20
-55
lines changed

2 files changed

+20
-55
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/task/TaskExecutorMetricsAutoConfiguration.java

Lines changed: 5 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import java.util.Map;
2020
import java.util.concurrent.Executor;
2121
import java.util.concurrent.ThreadPoolExecutor;
22-
import java.util.function.Supplier;
2322

2423
import io.micrometer.core.instrument.MeterRegistry;
2524
import io.micrometer.core.instrument.binder.jvm.ExecutorServiceMetrics;
@@ -36,14 +35,14 @@
3635
import org.springframework.context.annotation.Configuration;
3736
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
3837
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
39-
import org.springframework.util.StringUtils;
4038

4139
/**
4240
* {@link EnableAutoConfiguration Auto-configuration} for metrics on all available
4341
* {@link ThreadPoolTaskExecutor task executors} and {@link ThreadPoolTaskScheduler task
4442
* schedulers}.
4543
*
4644
* @author Stephane Nicoll
45+
* @author Scott Frederick
4746
* @since 2.6.0
4847
*/
4948
@Configuration(proxyBeanMethods = false)
@@ -53,27 +52,21 @@
5352
@ConditionalOnBean({ Executor.class, MeterRegistry.class })
5453
public class TaskExecutorMetricsAutoConfiguration {
5554

56-
private static final String TASK_EXECUTOR_SUFFIX = "taskExecutor";
57-
58-
private static final String TASK_SCHEDULER_SUFFIX = "taskScheduler";
59-
6055
@Autowired
6156
public void bindTaskExecutorsToRegistry(Map<String, Executor> executors, MeterRegistry registry) {
6257
executors.forEach((beanName, executor) -> {
6358
if (executor instanceof ThreadPoolTaskExecutor) {
64-
monitor(registry, safeGetThreadPoolExecutor((ThreadPoolTaskExecutor) executor),
65-
() -> getTaskExecutorName(beanName));
59+
monitor(registry, safeGetThreadPoolExecutor((ThreadPoolTaskExecutor) executor), beanName);
6660
}
6761
else if (executor instanceof ThreadPoolTaskScheduler) {
68-
monitor(registry, safeGetThreadPoolExecutor((ThreadPoolTaskScheduler) executor),
69-
() -> getTaskSchedulerName(beanName));
62+
monitor(registry, safeGetThreadPoolExecutor((ThreadPoolTaskScheduler) executor), beanName);
7063
}
7164
});
7265
}
7366

74-
private void monitor(MeterRegistry registry, ThreadPoolExecutor threadPoolExecutor, Supplier<String> beanName) {
67+
private void monitor(MeterRegistry registry, ThreadPoolExecutor threadPoolExecutor, String name) {
7568
if (threadPoolExecutor != null) {
76-
ExecutorServiceMetrics.monitor(registry, threadPoolExecutor, beanName.get());
69+
ExecutorServiceMetrics.monitor(registry, threadPoolExecutor, name);
7770
}
7871
}
7972

@@ -95,33 +88,4 @@ private ThreadPoolExecutor safeGetThreadPoolExecutor(ThreadPoolTaskScheduler tas
9588
}
9689
}
9790

98-
/**
99-
* Get the name of a {@link ThreadPoolTaskExecutor} based on its {@code beanName}.
100-
* @param beanName the name of the {@link ThreadPoolTaskExecutor} bean
101-
* @return a name for the given task executor
102-
*/
103-
private String getTaskExecutorName(String beanName) {
104-
if (beanName.length() > TASK_EXECUTOR_SUFFIX.length()
105-
&& StringUtils.endsWithIgnoreCase(beanName, TASK_EXECUTOR_SUFFIX)) {
106-
return beanName.substring(0, beanName.length() - TASK_EXECUTOR_SUFFIX.length());
107-
}
108-
return beanName;
109-
}
110-
111-
/**
112-
* Get the name of a {@link ThreadPoolTaskScheduler} based on its {@code beanName}.
113-
* @param beanName the name of the {@link ThreadPoolTaskScheduler} bean
114-
* @return a name for the given task scheduler
115-
*/
116-
private String getTaskSchedulerName(String beanName) {
117-
if (beanName.equals(TASK_SCHEDULER_SUFFIX)) {
118-
return "application";
119-
}
120-
if (beanName.length() > TASK_SCHEDULER_SUFFIX.length()
121-
&& StringUtils.endsWithIgnoreCase(beanName, TASK_SCHEDULER_SUFFIX)) {
122-
return beanName.substring(0, beanName.length() - TASK_SCHEDULER_SUFFIX.length());
123-
}
124-
return beanName;
125-
}
126-
12791
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/task/TaskExecutorMetricsAutoConfigurationTests.java

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
* Tests for {@link TaskExecutorMetricsAutoConfiguration}.
4242
*
4343
* @author Stephane Nicoll
44+
* @author Scott Frederick
4445
*/
4546
class TaskExecutorMetricsAutoConfigurationTests {
4647

@@ -53,8 +54,8 @@ void taskExecutorUsingAutoConfigurationIsInstrumented() {
5354
.run((context) -> {
5455
MeterRegistry registry = context.getBean(MeterRegistry.class);
5556
Collection<FunctionCounter> meters = registry.get("executor.completed").functionCounters();
56-
assertThat(meters).singleElement()
57-
.satisfies((meter) -> assertThat(meter.getId().getTag("name")).isEqualTo("application"));
57+
assertThat(meters).singleElement().satisfies(
58+
(meter) -> assertThat(meter.getId().getTag("name")).isEqualTo("applicationTaskExecutor"));
5859
});
5960
}
6061

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

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

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

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

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

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

@@ -133,7 +134,7 @@ void taskSchedulerInstrumentationCanBeDisabled() {
133134
.withConfiguration(AutoConfigurations.of(TaskSchedulingAutoConfiguration.class))
134135
.withUserConfiguration(SchedulingTestConfiguration.class).run((context) -> {
135136
MeterRegistry registry = context.getBean(MeterRegistry.class);
136-
assertThat(registry.find("executor.completed").tags("name", "application").functionCounter())
137+
assertThat(registry.find("executor.completed").tags("name", "taskScheduler").functionCounter())
137138
.isNull();
138139
});
139140
}

0 commit comments

Comments
 (0)