Browse Source
Create beans for the conventions that will be picked up by other auto-configuration. Adds a property to control which set of conventions are auto-configured, which makes this easier to configure consistently across applications.pull/49241/head
5 changed files with 325 additions and 6 deletions
@ -0,0 +1,115 @@
@@ -0,0 +1,115 @@
|
||||
/* |
||||
* Copyright 2012-present the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.micrometer.metrics.autoconfigure; |
||||
|
||||
import io.micrometer.core.instrument.Tags; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.JvmClassLoadingMeterConventions; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.JvmCpuMeterConventions; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.JvmMemoryMeterConventions; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.JvmThreadMeterConventions; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.micrometer.MicrometerJvmClassLoadingMeterConventions; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.micrometer.MicrometerJvmCpuMeterConventions; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.micrometer.MicrometerJvmMemoryMeterConventions; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.micrometer.MicrometerJvmThreadMeterConventions; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.otel.OpenTelemetryJvmClassLoadingMeterConventions; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.otel.OpenTelemetryJvmCpuMeterConventions; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.otel.OpenTelemetryJvmMemoryMeterConventions; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.otel.OpenTelemetryJvmThreadMeterConventions; |
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration; |
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; |
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; |
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties; |
||||
import org.springframework.boot.micrometer.metrics.autoconfigure.jvm.JvmMetricsAutoConfiguration; |
||||
import org.springframework.boot.micrometer.metrics.autoconfigure.system.SystemMetricsAutoConfiguration; |
||||
import org.springframework.boot.micrometer.observation.autoconfigure.ObservationProperties; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
|
||||
/** |
||||
* {@link EnableAutoConfiguration Auto-configuration} for semantic conventions for metrics |
||||
* and observations. |
||||
* |
||||
* @since 4.1.0 |
||||
*/ |
||||
@AutoConfiguration(before = { JvmMetricsAutoConfiguration.class, SystemMetricsAutoConfiguration.class }) |
||||
@EnableConfigurationProperties(ObservationProperties.class) |
||||
public final class SemanticConventionAutoConfiguration { |
||||
|
||||
@Configuration(proxyBeanMethods = false) |
||||
@ConditionalOnProperty(prefix = "management.observations", name = "conventions", havingValue = "micrometer", |
||||
matchIfMissing = true) |
||||
static class MicrometerSemanticConventionConfiguration { |
||||
|
||||
@Bean |
||||
@ConditionalOnMissingBean(JvmMemoryMeterConventions.class) |
||||
MicrometerJvmMemoryMeterConventions micrometerJvmMemoryMeterConventions() { |
||||
return new MicrometerJvmMemoryMeterConventions(); |
||||
} |
||||
|
||||
@Bean |
||||
@ConditionalOnMissingBean(JvmClassLoadingMeterConventions.class) |
||||
MicrometerJvmClassLoadingMeterConventions micrometerJvmClassLoadingMeterConventions() { |
||||
return new MicrometerJvmClassLoadingMeterConventions(); |
||||
} |
||||
|
||||
@Bean |
||||
@ConditionalOnMissingBean(JvmCpuMeterConventions.class) |
||||
MicrometerJvmCpuMeterConventions micrometerJvmCpuMeterConventions() { |
||||
return new MicrometerJvmCpuMeterConventions(Tags.empty()); |
||||
} |
||||
|
||||
@Bean |
||||
@ConditionalOnMissingBean(JvmThreadMeterConventions.class) |
||||
MicrometerJvmThreadMeterConventions micrometerJvmThreadMeterConventions() { |
||||
return new MicrometerJvmThreadMeterConventions(Tags.empty()); |
||||
} |
||||
|
||||
} |
||||
|
||||
@Configuration(proxyBeanMethods = false) |
||||
@ConditionalOnProperty(prefix = "management.observations", name = "conventions", havingValue = "opentelemetry") |
||||
static class OpenTelemetrySemanticConventionConfiguration { |
||||
|
||||
@Bean |
||||
@ConditionalOnMissingBean(JvmMemoryMeterConventions.class) |
||||
OpenTelemetryJvmMemoryMeterConventions openTelemetryJvmMemoryMeterConventions() { |
||||
return new OpenTelemetryJvmMemoryMeterConventions(Tags.empty()); |
||||
} |
||||
|
||||
@Bean |
||||
@ConditionalOnMissingBean(JvmClassLoadingMeterConventions.class) |
||||
OpenTelemetryJvmClassLoadingMeterConventions openTelemetryJvmClassLoadingMeterConventions() { |
||||
return new OpenTelemetryJvmClassLoadingMeterConventions(); |
||||
} |
||||
|
||||
@Bean |
||||
@ConditionalOnMissingBean(JvmCpuMeterConventions.class) |
||||
OpenTelemetryJvmCpuMeterConventions openTelemetryJvmCpuMeterConventions() { |
||||
return new OpenTelemetryJvmCpuMeterConventions(Tags.empty()); |
||||
} |
||||
|
||||
@Bean |
||||
@ConditionalOnMissingBean(JvmThreadMeterConventions.class) |
||||
OpenTelemetryJvmThreadMeterConventions openTelemetryJvmThreadMeterConventions() { |
||||
return new OpenTelemetryJvmThreadMeterConventions(Tags.empty()); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,158 @@
@@ -0,0 +1,158 @@
|
||||
/* |
||||
* Copyright 2012-present the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.micrometer.metrics.autoconfigure; |
||||
|
||||
import java.lang.management.MemoryPoolMXBean; |
||||
|
||||
import io.micrometer.core.instrument.binder.MeterConvention; |
||||
import io.micrometer.core.instrument.binder.SimpleMeterConvention; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.JvmClassLoadingMeterConventions; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.JvmCpuMeterConventions; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.JvmMemoryMeterConventions; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.JvmThreadMeterConventions; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.micrometer.MicrometerJvmClassLoadingMeterConventions; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.micrometer.MicrometerJvmCpuMeterConventions; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.micrometer.MicrometerJvmMemoryMeterConventions; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.micrometer.MicrometerJvmThreadMeterConventions; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.otel.OpenTelemetryJvmClassLoadingMeterConventions; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.otel.OpenTelemetryJvmCpuMeterConventions; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.otel.OpenTelemetryJvmMemoryMeterConventions; |
||||
import io.micrometer.core.instrument.binder.jvm.convention.otel.OpenTelemetryJvmThreadMeterConventions; |
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations; |
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* Tests for {@link SemanticConventionAutoConfiguration}. |
||||
*/ |
||||
class SemanticConventionAutoConfigurationTests { |
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() |
||||
.withConfiguration(AutoConfigurations.of(SemanticConventionAutoConfiguration.class)); |
||||
|
||||
@Test |
||||
void registersMicrometerConventionsByDefault() { |
||||
this.contextRunner.run((context) -> { |
||||
assertThat(context).hasSingleBean(MicrometerJvmMemoryMeterConventions.class); |
||||
assertThat(context).hasSingleBean(MicrometerJvmClassLoadingMeterConventions.class); |
||||
assertThat(context).hasSingleBean(MicrometerJvmCpuMeterConventions.class); |
||||
assertThat(context).hasSingleBean(MicrometerJvmThreadMeterConventions.class); |
||||
assertThat(context).doesNotHaveBean(OpenTelemetryJvmMemoryMeterConventions.class); |
||||
assertThat(context).doesNotHaveBean(OpenTelemetryJvmClassLoadingMeterConventions.class); |
||||
assertThat(context).doesNotHaveBean(OpenTelemetryJvmCpuMeterConventions.class); |
||||
assertThat(context).doesNotHaveBean(OpenTelemetryJvmThreadMeterConventions.class); |
||||
}); |
||||
} |
||||
|
||||
@Test |
||||
void registersOpenTelemetryConventionsWhenConventionsSetToOpenTelemetry() { |
||||
this.contextRunner.withPropertyValues("management.observations.conventions=opentelemetry").run((context) -> { |
||||
assertThat(context).hasSingleBean(JvmMemoryMeterConventions.class) |
||||
.hasSingleBean(OpenTelemetryJvmMemoryMeterConventions.class); |
||||
assertThat(context).hasSingleBean(JvmClassLoadingMeterConventions.class) |
||||
.hasSingleBean(OpenTelemetryJvmClassLoadingMeterConventions.class); |
||||
assertThat(context).hasSingleBean(JvmCpuMeterConventions.class) |
||||
.hasSingleBean(OpenTelemetryJvmCpuMeterConventions.class); |
||||
assertThat(context).hasSingleBean(JvmThreadMeterConventions.class) |
||||
.hasSingleBean(OpenTelemetryJvmThreadMeterConventions.class); |
||||
}); |
||||
} |
||||
|
||||
@Test |
||||
void allowsCustomMicrometerConventionsToBeUsed() { |
||||
this.contextRunner.withPropertyValues("management.observations.conventions=micrometer") |
||||
.withUserConfiguration(CustomJvmMemoryMeterConventionsConfiguration.class) |
||||
.run((context) -> { |
||||
assertThat(context).hasSingleBean(JvmMemoryMeterConventions.class) |
||||
.hasBean("customJvmMemoryMeterConventions"); |
||||
assertThat(context).doesNotHaveBean(MicrometerJvmMemoryMeterConventions.class); |
||||
assertThat(context).hasSingleBean(MicrometerJvmClassLoadingMeterConventions.class); |
||||
assertThat(context).hasSingleBean(MicrometerJvmCpuMeterConventions.class); |
||||
assertThat(context).hasSingleBean(MicrometerJvmThreadMeterConventions.class); |
||||
}); |
||||
} |
||||
|
||||
@Test |
||||
void allowsCustomOpenTelemetryConventionsToBeUsed() { |
||||
this.contextRunner.withPropertyValues("management.observations.conventions=opentelemetry") |
||||
.withUserConfiguration(CustomJvmClassLoadingMeterConventionsConfiguration.class) |
||||
.run((context) -> { |
||||
assertThat(context).hasSingleBean(JvmClassLoadingMeterConventions.class) |
||||
.hasBean("customJvmClassLoadingMeterConventions"); |
||||
assertThat(context).doesNotHaveBean(MicrometerJvmClassLoadingMeterConventions.class); |
||||
assertThat(context).hasSingleBean(OpenTelemetryJvmMemoryMeterConventions.class); |
||||
assertThat(context).hasSingleBean(OpenTelemetryJvmCpuMeterConventions.class); |
||||
assertThat(context).hasSingleBean(OpenTelemetryJvmThreadMeterConventions.class); |
||||
}); |
||||
} |
||||
|
||||
@Configuration(proxyBeanMethods = false) |
||||
static class CustomJvmMemoryMeterConventionsConfiguration { |
||||
|
||||
@Bean |
||||
JvmMemoryMeterConventions customJvmMemoryMeterConventions() { |
||||
return new JvmMemoryMeterConventions() { |
||||
@Override |
||||
public MeterConvention<MemoryPoolMXBean> getMemoryUsedConvention() { |
||||
return new SimpleMeterConvention<>("my.memory.used"); |
||||
} |
||||
|
||||
@Override |
||||
public MeterConvention<MemoryPoolMXBean> getMemoryCommittedConvention() { |
||||
return new SimpleMeterConvention<>("my.memory.committed"); |
||||
} |
||||
|
||||
@Override |
||||
public MeterConvention<MemoryPoolMXBean> getMemoryMaxConvention() { |
||||
return new SimpleMeterConvention<>("my.memory.max"); |
||||
} |
||||
}; |
||||
} |
||||
|
||||
} |
||||
|
||||
@Configuration(proxyBeanMethods = false) |
||||
static class CustomJvmClassLoadingMeterConventionsConfiguration { |
||||
|
||||
@Bean |
||||
JvmClassLoadingMeterConventions customJvmClassLoadingMeterConventions() { |
||||
return new JvmClassLoadingMeterConventions() { |
||||
@Override |
||||
public MeterConvention<Object> loadedConvention() { |
||||
return new SimpleMeterConvention<>("my.classes.loaded"); |
||||
} |
||||
|
||||
@Override |
||||
public MeterConvention<Object> unloadedConvention() { |
||||
return new SimpleMeterConvention<>("my.classes.unloaded"); |
||||
} |
||||
|
||||
@Override |
||||
public MeterConvention<Object> currentClassCountConvention() { |
||||
return new SimpleMeterConvention<>("my.classes.current"); |
||||
} |
||||
}; |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue