diff --git a/module/spring-boot-micrometer-metrics/src/main/java/org/springframework/boot/micrometer/metrics/autoconfigure/jvm/JvmMetricsAutoConfiguration.java b/module/spring-boot-micrometer-metrics/src/main/java/org/springframework/boot/micrometer/metrics/autoconfigure/jvm/JvmMetricsAutoConfiguration.java index 2b3f5c3224be..0375523e15b3 100644 --- a/module/spring-boot-micrometer-metrics/src/main/java/org/springframework/boot/micrometer/metrics/autoconfigure/jvm/JvmMetricsAutoConfiguration.java +++ b/module/spring-boot-micrometer-metrics/src/main/java/org/springframework/boot/micrometer/metrics/autoconfigure/jvm/JvmMetricsAutoConfiguration.java @@ -17,6 +17,7 @@ package org.springframework.boot.micrometer.metrics.autoconfigure.jvm; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Tags; import io.micrometer.core.instrument.binder.MeterBinder; import io.micrometer.core.instrument.binder.jvm.ClassLoaderMetrics; import io.micrometer.core.instrument.binder.jvm.JvmCompilationMetrics; @@ -25,12 +26,16 @@ import io.micrometer.core.instrument.binder.jvm.JvmInfoMetrics; import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics; +import io.micrometer.core.instrument.binder.jvm.convention.JvmClassLoadingMeterConventions; +import io.micrometer.core.instrument.binder.jvm.convention.JvmMemoryMeterConventions; +import io.micrometer.core.instrument.binder.jvm.convention.JvmThreadMeterConventions; import org.jspecify.annotations.Nullable; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -71,20 +76,23 @@ JvmHeapPressureMetrics jvmHeapPressureMetrics() { @Bean @ConditionalOnMissingBean - JvmMemoryMetrics jvmMemoryMetrics() { - return new JvmMemoryMetrics(); + JvmMemoryMetrics jvmMemoryMetrics(ObjectProvider jvmMemoryMeterConventions) { + JvmMemoryMeterConventions conventions = jvmMemoryMeterConventions.getIfAvailable(); + return (conventions != null) ? new JvmMemoryMetrics(Tags.empty(), conventions) : new JvmMemoryMetrics(); } @Bean @ConditionalOnMissingBean - JvmThreadMetrics jvmThreadMetrics() { - return new JvmThreadMetrics(); + JvmThreadMetrics jvmThreadMetrics(ObjectProvider jvmThreadMeterConventions) { + JvmThreadMeterConventions conventions = jvmThreadMeterConventions.getIfAvailable(); + return (conventions != null) ? new JvmThreadMetrics(Tags.empty(), conventions) : new JvmThreadMetrics(); } @Bean @ConditionalOnMissingBean - ClassLoaderMetrics classLoaderMetrics() { - return new ClassLoaderMetrics(); + ClassLoaderMetrics classLoaderMetrics(ObjectProvider jvmClassLoadingMeterConventions) { + JvmClassLoadingMeterConventions conventions = jvmClassLoadingMeterConventions.getIfAvailable(); + return (conventions != null) ? new ClassLoaderMetrics(conventions) : new ClassLoaderMetrics(); } @Bean diff --git a/module/spring-boot-micrometer-metrics/src/main/java/org/springframework/boot/micrometer/metrics/autoconfigure/system/SystemMetricsAutoConfiguration.java b/module/spring-boot-micrometer-metrics/src/main/java/org/springframework/boot/micrometer/metrics/autoconfigure/system/SystemMetricsAutoConfiguration.java index faf02f23c145..207842b4dcad 100644 --- a/module/spring-boot-micrometer-metrics/src/main/java/org/springframework/boot/micrometer/metrics/autoconfigure/system/SystemMetricsAutoConfiguration.java +++ b/module/spring-boot-micrometer-metrics/src/main/java/org/springframework/boot/micrometer/metrics/autoconfigure/system/SystemMetricsAutoConfiguration.java @@ -21,10 +21,12 @@ import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tags; +import io.micrometer.core.instrument.binder.jvm.convention.JvmCpuMeterConventions; import io.micrometer.core.instrument.binder.system.FileDescriptorMetrics; import io.micrometer.core.instrument.binder.system.ProcessorMetrics; import io.micrometer.core.instrument.binder.system.UptimeMetrics; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -58,8 +60,9 @@ UptimeMetrics uptimeMetrics() { @Bean @ConditionalOnMissingBean - ProcessorMetrics processorMetrics() { - return new ProcessorMetrics(); + ProcessorMetrics processorMetrics(ObjectProvider jvmCpuMeterConventions) { + JvmCpuMeterConventions conventions = jvmCpuMeterConventions.getIfAvailable(); + return (conventions != null) ? new ProcessorMetrics(Tags.empty(), conventions) : new ProcessorMetrics(); } @Bean diff --git a/module/spring-boot-micrometer-metrics/src/test/java/org/springframework/boot/micrometer/metrics/autoconfigure/jvm/JvmMetricsAutoConfigurationTests.java b/module/spring-boot-micrometer-metrics/src/test/java/org/springframework/boot/micrometer/metrics/autoconfigure/jvm/JvmMetricsAutoConfigurationTests.java index a40865473902..594d05a1d83a 100644 --- a/module/spring-boot-micrometer-metrics/src/test/java/org/springframework/boot/micrometer/metrics/autoconfigure/jvm/JvmMetricsAutoConfigurationTests.java +++ b/module/spring-boot-micrometer-metrics/src/test/java/org/springframework/boot/micrometer/metrics/autoconfigure/jvm/JvmMetricsAutoConfigurationTests.java @@ -25,6 +25,9 @@ import io.micrometer.core.instrument.binder.jvm.JvmInfoMetrics; import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics; +import io.micrometer.core.instrument.binder.jvm.convention.JvmClassLoadingMeterConventions; +import io.micrometer.core.instrument.binder.jvm.convention.JvmMemoryMeterConventions; +import io.micrometer.core.instrument.binder.jvm.convention.JvmThreadMeterConventions; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledForJreRange; @@ -44,6 +47,7 @@ import org.springframework.util.ClassUtils; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; /** * Tests for {@link JvmMetricsAutoConfiguration}. @@ -82,18 +86,64 @@ void allowsCustomJvmMemoryMetricsToBeUsed() { .run(assertMetricsBeans().andThen((context) -> assertThat(context).hasBean("customJvmMemoryMetrics"))); } + @Test + void autoConfiguresJvmMemoryMetrics() { + this.contextRunner.run((context) -> assertThat(context).hasSingleBean(JvmMemoryMetrics.class)); + } + + @Test + void autoConfiguresJvmMemoryMetricsWithCustomJvmMemoryMeterConventions() { + this.contextRunner.withUserConfiguration(CustomJvmMemoryMeterConventionsConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(JvmMemoryMetrics.class); + JvmMemoryMetrics jvmMemoryMetrics = context.getBean(JvmMemoryMetrics.class); + assertThat(jvmMemoryMetrics).extracting("conventions") + .isSameAs(context.getBean(JvmMemoryMeterConventions.class)); + }); + } + @Test void allowsCustomJvmThreadMetricsToBeUsed() { this.contextRunner.withUserConfiguration(CustomJvmThreadMetricsConfiguration.class) .run(assertMetricsBeans().andThen((context) -> assertThat(context).hasBean("customJvmThreadMetrics"))); } + @Test + void autoConfiguresJvmThreadMetrics() { + this.contextRunner.run((context) -> assertThat(context).hasSingleBean(JvmThreadMetrics.class)); + } + + @Test + void autoConfiguresJvmThreadMetricsWithCustomCustomJvmThreadMeterConventions() { + this.contextRunner.withUserConfiguration(CustomJvmThreadMeterConventionsConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(JvmThreadMetrics.class); + JvmThreadMetrics jvmThreadMetrics = context.getBean(JvmThreadMetrics.class); + assertThat(jvmThreadMetrics).extracting("conventions") + .isSameAs(context.getBean(JvmThreadMeterConventions.class)); + }); + } + @Test void allowsCustomClassLoaderMetricsToBeUsed() { this.contextRunner.withUserConfiguration(CustomClassLoaderMetricsConfiguration.class) .run(assertMetricsBeans().andThen((context) -> assertThat(context).hasBean("customClassLoaderMetrics"))); } + @Test + void autoConfiguresClassLoaderMetrics() { + this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ClassLoaderMetrics.class)); + } + + @Test + void autoConfiguresClassLoaderMetricsWithCustomJvmClassLoadingMeterConventions() { + this.contextRunner.withUserConfiguration(CustomJvmClassLoadingMeterConventionsConfiguration.class) + .run((context) -> { + assertThat(context).hasSingleBean(ClassLoaderMetrics.class); + ClassLoaderMetrics classLoaderMetrics = context.getBean(ClassLoaderMetrics.class); + assertThat(classLoaderMetrics).extracting("conventions") + .isSameAs(context.getBean(JvmClassLoadingMeterConventions.class)); + }); + } + @Test void allowsCustomJvmInfoMetricsToBeUsed() { this.contextRunner.withUserConfiguration(CustomJvmInfoMetricsConfiguration.class) @@ -222,4 +272,34 @@ JvmCompilationMetrics customJvmCompilationMetrics() { } + @Configuration(proxyBeanMethods = false) + static class CustomJvmThreadMeterConventionsConfiguration { + + @Bean + JvmThreadMeterConventions customJvmThreadMeterConventions() { + return mock(JvmThreadMeterConventions.class); + } + + } + + @Configuration(proxyBeanMethods = false) + static class CustomJvmMemoryMeterConventionsConfiguration { + + @Bean + JvmMemoryMeterConventions customJvmMemoryMeterConventions() { + return mock(JvmMemoryMeterConventions.class); + } + + } + + @Configuration(proxyBeanMethods = false) + static class CustomJvmClassLoadingMeterConventionsConfiguration { + + @Bean + JvmClassLoadingMeterConventions customJvmClassLoadingMeterConventions() { + return mock(JvmClassLoadingMeterConventions.class); + } + + } + } diff --git a/module/spring-boot-micrometer-metrics/src/test/java/org/springframework/boot/micrometer/metrics/autoconfigure/system/SystemMetricsAutoConfigurationTests.java b/module/spring-boot-micrometer-metrics/src/test/java/org/springframework/boot/micrometer/metrics/autoconfigure/system/SystemMetricsAutoConfigurationTests.java index eb077080f82d..0470e857cf0d 100644 --- a/module/spring-boot-micrometer-metrics/src/test/java/org/springframework/boot/micrometer/metrics/autoconfigure/system/SystemMetricsAutoConfigurationTests.java +++ b/module/spring-boot-micrometer-metrics/src/test/java/org/springframework/boot/micrometer/metrics/autoconfigure/system/SystemMetricsAutoConfigurationTests.java @@ -21,6 +21,7 @@ import java.util.Collections; import io.micrometer.core.instrument.Tags; +import io.micrometer.core.instrument.binder.jvm.convention.JvmCpuMeterConventions; import io.micrometer.core.instrument.binder.system.FileDescriptorMetrics; import io.micrometer.core.instrument.binder.system.ProcessorMetrics; import io.micrometer.core.instrument.binder.system.UptimeMetrics; @@ -34,6 +35,7 @@ import org.springframework.context.annotation.Configuration; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; /** * Tests for {@link SystemMetricsAutoConfiguration}. @@ -64,6 +66,16 @@ void autoConfiguresProcessorMetrics() { this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ProcessorMetrics.class)); } + @Test + void autoConfiguresProcessorMetricsWithCustomJvmCpuMeterConventions() { + this.contextRunner.withUserConfiguration(JvmCpuMeterConventionsConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(ProcessorMetrics.class); + ProcessorMetrics processorMetrics = context.getBean(ProcessorMetrics.class); + assertThat(processorMetrics).extracting("conventions") + .isSameAs(context.getBean(JvmCpuMeterConventions.class)); + }); + } + @Test void allowsCustomProcessorMetricsToBeUsed() { this.contextRunner.withUserConfiguration(CustomProcessorMetricsConfiguration.class) @@ -138,6 +150,16 @@ ProcessorMetrics customProcessorMetrics() { } + @Configuration(proxyBeanMethods = false) + static class JvmCpuMeterConventionsConfiguration { + + @Bean + JvmCpuMeterConventions customJvmCpuMeterConventions() { + return mock(JvmCpuMeterConventions.class); + } + + } + @Configuration(proxyBeanMethods = false) static class CustomFileDescriptorMetricsConfiguration {