Close meter registries early in the shutdown process
Closes gh-38240 Co-authored-by: Phillip Webb <pwebb@vmware.com>
This commit is contained in:
@@ -16,8 +16,11 @@
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.metrics;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.micrometer.core.annotation.Timed;
|
||||
import io.micrometer.core.instrument.Clock;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.binder.MeterBinder;
|
||||
import io.micrometer.core.instrument.config.MeterFilter;
|
||||
|
||||
@@ -28,6 +31,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.annotation.Order;
|
||||
|
||||
@@ -36,6 +40,8 @@ import org.springframework.core.annotation.Order;
|
||||
*
|
||||
* @author Jon Schneider
|
||||
* @author Stephane Nicoll
|
||||
* @author Phil Webb
|
||||
* @author Moritz Halbritter
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@AutoConfiguration(before = CompositeMeterRegistryAutoConfiguration.class)
|
||||
@@ -64,4 +70,45 @@ public class MetricsAutoConfiguration {
|
||||
return new PropertiesMeterFilter(properties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
MeterRegistryLifecycle meterRegistryLifecycle(ObjectProvider<MeterRegistry> meterRegistries) {
|
||||
return new MeterRegistryLifecycle(meterRegistries.orderedStream().toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that {@link MeterRegistry meter registries} are closed early in the
|
||||
* shutdown process.
|
||||
*/
|
||||
static class MeterRegistryLifecycle implements SmartLifecycle {
|
||||
|
||||
private volatile boolean running;
|
||||
|
||||
private final List<MeterRegistry> meterRegistries;
|
||||
|
||||
MeterRegistryLifecycle(List<MeterRegistry> meterRegistries) {
|
||||
this.meterRegistries = meterRegistries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
this.running = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
this.running = false;
|
||||
this.meterRegistries.forEach((registry) -> {
|
||||
if (!registry.isClosed()) {
|
||||
registry.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return this.running;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,15 +16,19 @@
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.metrics;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.micrometer.core.instrument.Clock;
|
||||
import io.micrometer.core.instrument.Meter;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.binder.MeterBinder;
|
||||
import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
|
||||
import io.micrometer.core.instrument.config.MeterFilter;
|
||||
import io.micrometer.core.instrument.config.MeterFilterReply;
|
||||
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration.MeterRegistryLifecycle;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -40,6 +44,7 @@ import static org.mockito.Mockito.mock;
|
||||
* Tests for {@link MetricsAutoConfiguration}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class MetricsAutoConfigurationTests {
|
||||
|
||||
@@ -72,6 +77,21 @@ class MetricsAutoConfigurationTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldSupplyMeterRegistryLifecycle() {
|
||||
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(MeterRegistryLifecycle.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void meterRegistryLifecycleShouldCloseRegistryOnShutdown() {
|
||||
MeterRegistry meterRegistry = new CompositeMeterRegistry();
|
||||
assertThat(meterRegistry.isClosed()).isFalse();
|
||||
MeterRegistryLifecycle lifecycle = new MeterRegistryLifecycle(List.of(meterRegistry));
|
||||
lifecycle.start();
|
||||
lifecycle.stop();
|
||||
assertThat(meterRegistry.isClosed()).isTrue();
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CustomClockConfiguration {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user