mirror of
https://github.com/spring-projects/spring-boot.git
synced 2026-09-17 12:09:16 +00:00
Configure OpenTelemetry semantic conventions
Adds a management.observations.conventions property to control which set of conventions are auto-configured across the application. Configures WebMvc and WebFlux ServerRequestObservationConvention beans to switch to OpenTelemetry conventions when configured. Configures JVM and system meter binders using their builder APIs to apply OpenTelemetry conventions while still allowing individual meter conventions to be overridden via beans. Signed-off-by: Tommy Ludwig <8924140+shakuzen@users.noreply.github.com> See gh-49241
This commit is contained in:
committed by
Andy Wilkinson
parent
254a2e37ba
commit
7d43f31732
+36
-14
@@ -34,6 +34,7 @@ import io.micrometer.core.instrument.binder.jvm.convention.JvmClassUnloadedMeter
|
|||||||
import io.micrometer.core.instrument.binder.jvm.convention.JvmMemoryCommittedMeterConvention;
|
import io.micrometer.core.instrument.binder.jvm.convention.JvmMemoryCommittedMeterConvention;
|
||||||
import io.micrometer.core.instrument.binder.jvm.convention.JvmMemoryMaxMeterConvention;
|
import io.micrometer.core.instrument.binder.jvm.convention.JvmMemoryMaxMeterConvention;
|
||||||
import io.micrometer.core.instrument.binder.jvm.convention.JvmMemoryMeterConventions;
|
import io.micrometer.core.instrument.binder.jvm.convention.JvmMemoryMeterConventions;
|
||||||
|
import io.micrometer.core.instrument.binder.jvm.convention.JvmMemoryUsedAfterLastGcMeterConvention;
|
||||||
import io.micrometer.core.instrument.binder.jvm.convention.JvmMemoryUsedMeterConvention;
|
import io.micrometer.core.instrument.binder.jvm.convention.JvmMemoryUsedMeterConvention;
|
||||||
import io.micrometer.core.instrument.binder.jvm.convention.JvmThreadCountMeterConvention;
|
import io.micrometer.core.instrument.binder.jvm.convention.JvmThreadCountMeterConvention;
|
||||||
import io.micrometer.core.instrument.binder.jvm.convention.JvmThreadMeterConventions;
|
import io.micrometer.core.instrument.binder.jvm.convention.JvmThreadMeterConventions;
|
||||||
@@ -49,9 +50,12 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
|||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.boot.context.properties.PropertyMapper;
|
import org.springframework.boot.context.properties.PropertyMapper;
|
||||||
import org.springframework.boot.micrometer.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration;
|
import org.springframework.boot.micrometer.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration;
|
||||||
import org.springframework.boot.micrometer.metrics.autoconfigure.MetricsAutoConfiguration;
|
import org.springframework.boot.micrometer.metrics.autoconfigure.MetricsAutoConfiguration;
|
||||||
|
import org.springframework.boot.micrometer.observation.autoconfigure.ObservationProperties;
|
||||||
|
import org.springframework.boot.micrometer.observation.autoconfigure.ObservationProperties.ConventionsVariant;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.ImportRuntimeHints;
|
import org.springframework.context.annotation.ImportRuntimeHints;
|
||||||
@@ -67,6 +71,7 @@ import org.springframework.util.ClassUtils;
|
|||||||
@AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class })
|
@AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class })
|
||||||
@ConditionalOnClass(MeterRegistry.class)
|
@ConditionalOnClass(MeterRegistry.class)
|
||||||
@ConditionalOnBean(MeterRegistry.class)
|
@ConditionalOnBean(MeterRegistry.class)
|
||||||
|
@EnableConfigurationProperties(ObservationProperties.class)
|
||||||
public final class JvmMetricsAutoConfiguration {
|
public final class JvmMetricsAutoConfiguration {
|
||||||
|
|
||||||
private static final String VIRTUAL_THREAD_METRICS_CLASS = "io.micrometer.java21.instrument.binder.jdk.VirtualThreadMetrics";
|
private static final String VIRTUAL_THREAD_METRICS_CLASS = "io.micrometer.java21.instrument.binder.jdk.VirtualThreadMetrics";
|
||||||
@@ -86,26 +91,29 @@ public final class JvmMetricsAutoConfiguration {
|
|||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
JvmMemoryMetrics jvmMemoryMetrics(ObjectProvider<JvmMemoryMeterConventions> jvmMemoryMeterConventions,
|
JvmMemoryMetrics jvmMemoryMetrics(ObservationProperties observationProperties,
|
||||||
|
ObjectProvider<JvmMemoryMeterConventions> jvmMemoryMeterConventions,
|
||||||
ObjectProvider<JvmMemoryUsedMeterConvention> jvmMemoryUsedMeterConvention,
|
ObjectProvider<JvmMemoryUsedMeterConvention> jvmMemoryUsedMeterConvention,
|
||||||
ObjectProvider<JvmMemoryCommittedMeterConvention> jvmMemoryCommittedMeterConvention,
|
ObjectProvider<JvmMemoryCommittedMeterConvention> jvmMemoryCommittedMeterConvention,
|
||||||
ObjectProvider<JvmMemoryMaxMeterConvention> jvmMemoryMaxMeterConvention) {
|
ObjectProvider<JvmMemoryMaxMeterConvention> jvmMemoryMaxMeterConvention,
|
||||||
|
ObjectProvider<JvmMemoryUsedAfterLastGcMeterConvention> jvmMemoryUsedAfterLastGcMeterConvention) {
|
||||||
JvmMemoryMetricsFactory factory = new JvmMemoryMetricsFactory(jvmMemoryUsedMeterConvention.getIfAvailable(),
|
JvmMemoryMetricsFactory factory = new JvmMemoryMetricsFactory(jvmMemoryUsedMeterConvention.getIfAvailable(),
|
||||||
jvmMemoryCommittedMeterConvention.getIfAvailable(), jvmMemoryMaxMeterConvention.getIfAvailable());
|
jvmMemoryCommittedMeterConvention.getIfAvailable(), jvmMemoryMaxMeterConvention.getIfAvailable(),
|
||||||
|
jvmMemoryUsedAfterLastGcMeterConvention.getIfAvailable());
|
||||||
JvmMemoryMeterConventions deprecatedConventions = jvmMemoryMeterConventions.getIfAvailable();
|
JvmMemoryMeterConventions deprecatedConventions = jvmMemoryMeterConventions.getIfAvailable();
|
||||||
if (deprecatedConventions != null && factory.hasConvention()) {
|
if (deprecatedConventions != null && factory.hasConvention()) {
|
||||||
throw new IllegalStateException("Either %s or the interfaces that supersede it should be set"
|
throw new IllegalStateException("Either %s or the interfaces that supersede it should be set"
|
||||||
.formatted(JvmMemoryMeterConventions.class.getSimpleName()));
|
.formatted(JvmMemoryMeterConventions.class.getSimpleName()));
|
||||||
}
|
}
|
||||||
return (deprecatedConventions != null) ? new JvmMemoryMetrics(Collections.emptyList(), deprecatedConventions)
|
return (deprecatedConventions != null) ? new JvmMemoryMetrics(Collections.emptyList(), deprecatedConventions)
|
||||||
: factory.create();
|
: factory.create(observationProperties);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
JvmThreadMetrics jvmThreadMetrics(ObjectProvider<JvmThreadMeterConventions> jvmThreadMeterConventions,
|
JvmThreadMetrics jvmThreadMetrics(ObservationProperties observationProperties,
|
||||||
|
ObjectProvider<JvmThreadMeterConventions> jvmThreadMeterConventions,
|
||||||
ObjectProvider<JvmThreadCountMeterConvention> jvmThreadCountMeterConvention) {
|
ObjectProvider<JvmThreadCountMeterConvention> jvmThreadCountMeterConvention) {
|
||||||
JvmThreadMeterConventions deprecatedConventions = jvmThreadMeterConventions.getIfAvailable();
|
JvmThreadMeterConventions deprecatedConventions = jvmThreadMeterConventions.getIfAvailable();
|
||||||
JvmThreadCountMeterConvention convention = jvmThreadCountMeterConvention.getIfAvailable();
|
JvmThreadCountMeterConvention convention = jvmThreadCountMeterConvention.getIfAvailable();
|
||||||
@@ -117,14 +125,19 @@ public final class JvmMetricsAutoConfiguration {
|
|||||||
if (deprecatedConventions != null) {
|
if (deprecatedConventions != null) {
|
||||||
return new JvmThreadMetrics(Collections.emptyList(), deprecatedConventions);
|
return new JvmThreadMetrics(Collections.emptyList(), deprecatedConventions);
|
||||||
}
|
}
|
||||||
return (convention != null) ? JvmThreadMetrics.builder().threadCountConvention(convention).build()
|
JvmThreadMetrics.Builder builder = JvmThreadMetrics.builder();
|
||||||
: new JvmThreadMetrics();
|
if (observationProperties.getConventions() == ConventionsVariant.OPENTELEMETRY) {
|
||||||
|
builder.openTelemetryConventions();
|
||||||
|
}
|
||||||
|
PropertyMapper map = PropertyMapper.get();
|
||||||
|
map.from(convention).to(builder::threadCountConvention);
|
||||||
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
ClassLoaderMetrics classLoaderMetrics(
|
ClassLoaderMetrics classLoaderMetrics(ObservationProperties observationProperties,
|
||||||
ObjectProvider<JvmClassLoadingMeterConventions> jvmClassLoadingMeterConventions,
|
ObjectProvider<JvmClassLoadingMeterConventions> jvmClassLoadingMeterConventions,
|
||||||
ObjectProvider<JvmClassCountMeterConvention> jvmClassCountMeterConvention,
|
ObjectProvider<JvmClassCountMeterConvention> jvmClassCountMeterConvention,
|
||||||
ObjectProvider<JvmClassLoadedMeterConvention> jvmClassLoadedMeterConvention,
|
ObjectProvider<JvmClassLoadedMeterConvention> jvmClassLoadedMeterConvention,
|
||||||
@@ -136,7 +149,8 @@ public final class JvmMetricsAutoConfiguration {
|
|||||||
throw new IllegalStateException("Either %s or the interfaces that supersede it should be set"
|
throw new IllegalStateException("Either %s or the interfaces that supersede it should be set"
|
||||||
.formatted(JvmClassLoadingMeterConventions.class.getSimpleName()));
|
.formatted(JvmClassLoadingMeterConventions.class.getSimpleName()));
|
||||||
}
|
}
|
||||||
return (deprecatedConventions != null) ? new ClassLoaderMetrics(deprecatedConventions) : factory.create();
|
return (deprecatedConventions != null) ? new ClassLoaderMetrics(deprecatedConventions)
|
||||||
|
: factory.create(observationProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@@ -168,19 +182,24 @@ public final class JvmMetricsAutoConfiguration {
|
|||||||
|
|
||||||
private record JvmMemoryMetricsFactory(@Nullable JvmMemoryUsedMeterConvention memoryUsedConvention,
|
private record JvmMemoryMetricsFactory(@Nullable JvmMemoryUsedMeterConvention memoryUsedConvention,
|
||||||
@Nullable JvmMemoryCommittedMeterConvention memoryCommittedConvention,
|
@Nullable JvmMemoryCommittedMeterConvention memoryCommittedConvention,
|
||||||
@Nullable JvmMemoryMaxMeterConvention memoryMaxConvention) {
|
@Nullable JvmMemoryMaxMeterConvention memoryMaxConvention,
|
||||||
|
@Nullable JvmMemoryUsedAfterLastGcMeterConvention memoryUsedAfterLastGcConvention) {
|
||||||
|
|
||||||
boolean hasConvention() {
|
boolean hasConvention() {
|
||||||
return this.memoryUsedConvention != null || this.memoryCommittedConvention != null
|
return this.memoryUsedConvention != null || this.memoryCommittedConvention != null
|
||||||
|| this.memoryMaxConvention != null;
|
|| this.memoryMaxConvention != null || this.memoryUsedAfterLastGcConvention != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
JvmMemoryMetrics create() {
|
JvmMemoryMetrics create(ObservationProperties observationProperties) {
|
||||||
JvmMemoryMetrics.Builder builder = JvmMemoryMetrics.builder();
|
JvmMemoryMetrics.Builder builder = JvmMemoryMetrics.builder();
|
||||||
|
if (observationProperties.getConventions() == ConventionsVariant.OPENTELEMETRY) {
|
||||||
|
builder.openTelemetryConventions();
|
||||||
|
}
|
||||||
PropertyMapper map = PropertyMapper.get();
|
PropertyMapper map = PropertyMapper.get();
|
||||||
map.from(this.memoryUsedConvention).to(builder::memoryUsedConvention);
|
map.from(this.memoryUsedConvention).to(builder::memoryUsedConvention);
|
||||||
map.from(this.memoryCommittedConvention).to(builder::memoryCommittedConvention);
|
map.from(this.memoryCommittedConvention).to(builder::memoryCommittedConvention);
|
||||||
map.from(this.memoryMaxConvention).to(builder::memoryMaxConvention);
|
map.from(this.memoryMaxConvention).to(builder::memoryMaxConvention);
|
||||||
|
map.from(this.memoryUsedAfterLastGcConvention).to(builder::memoryUsedAfterLastGcConvention);
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,8 +214,11 @@ public final class JvmMetricsAutoConfiguration {
|
|||||||
|| this.classUnloadedConvention != null;
|
|| this.classUnloadedConvention != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassLoaderMetrics create() {
|
ClassLoaderMetrics create(ObservationProperties observationProperties) {
|
||||||
ClassLoaderMetrics.Builder builder = ClassLoaderMetrics.builder();
|
ClassLoaderMetrics.Builder builder = ClassLoaderMetrics.builder();
|
||||||
|
if (observationProperties.getConventions() == ConventionsVariant.OPENTELEMETRY) {
|
||||||
|
builder.openTelemetryConventions();
|
||||||
|
}
|
||||||
PropertyMapper map = PropertyMapper.get();
|
PropertyMapper map = PropertyMapper.get();
|
||||||
map.from(this.classCountConvention).to(builder::classCountConvention);
|
map.from(this.classCountConvention).to(builder::classCountConvention);
|
||||||
map.from(this.classLoadedConvention).to(builder::classLoadedConvention);
|
map.from(this.classLoadedConvention).to(builder::classLoadedConvention);
|
||||||
|
|||||||
+11
-5
@@ -43,6 +43,8 @@ import org.springframework.boot.micrometer.metrics.autoconfigure.CompositeMeterR
|
|||||||
import org.springframework.boot.micrometer.metrics.autoconfigure.MetricsAutoConfiguration;
|
import org.springframework.boot.micrometer.metrics.autoconfigure.MetricsAutoConfiguration;
|
||||||
import org.springframework.boot.micrometer.metrics.autoconfigure.MetricsProperties;
|
import org.springframework.boot.micrometer.metrics.autoconfigure.MetricsProperties;
|
||||||
import org.springframework.boot.micrometer.metrics.system.DiskSpaceMetricsBinder;
|
import org.springframework.boot.micrometer.metrics.system.DiskSpaceMetricsBinder;
|
||||||
|
import org.springframework.boot.micrometer.observation.autoconfigure.ObservationProperties;
|
||||||
|
import org.springframework.boot.micrometer.observation.autoconfigure.ObservationProperties.ConventionsVariant;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,7 +57,7 @@ import org.springframework.context.annotation.Bean;
|
|||||||
@AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class })
|
@AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class })
|
||||||
@ConditionalOnClass(MeterRegistry.class)
|
@ConditionalOnClass(MeterRegistry.class)
|
||||||
@ConditionalOnBean(MeterRegistry.class)
|
@ConditionalOnBean(MeterRegistry.class)
|
||||||
@EnableConfigurationProperties(MetricsProperties.class)
|
@EnableConfigurationProperties({ MetricsProperties.class, ObservationProperties.class })
|
||||||
public final class SystemMetricsAutoConfiguration {
|
public final class SystemMetricsAutoConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@@ -67,7 +69,8 @@ public final class SystemMetricsAutoConfiguration {
|
|||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
ProcessorMetrics processorMetrics(ObjectProvider<JvmCpuMeterConventions> jvmCpuMeterConventions,
|
ProcessorMetrics processorMetrics(ObservationProperties observationProperties,
|
||||||
|
ObjectProvider<JvmCpuMeterConventions> jvmCpuMeterConventions,
|
||||||
ObjectProvider<JvmCpuTimeMeterConvention> jvmCpuTimeMeterConvention,
|
ObjectProvider<JvmCpuTimeMeterConvention> jvmCpuTimeMeterConvention,
|
||||||
ObjectProvider<JvmCpuCountMeterConvention> jvmCpuCountMeterConvention,
|
ObjectProvider<JvmCpuCountMeterConvention> jvmCpuCountMeterConvention,
|
||||||
ObjectProvider<JvmCpuLoadMeterConvention> jvmCpuLoadMeterConvention) {
|
ObjectProvider<JvmCpuLoadMeterConvention> jvmCpuLoadMeterConvention) {
|
||||||
@@ -79,7 +82,7 @@ public final class SystemMetricsAutoConfiguration {
|
|||||||
.formatted(JvmCpuMeterConventions.class.getSimpleName()));
|
.formatted(JvmCpuMeterConventions.class.getSimpleName()));
|
||||||
}
|
}
|
||||||
return (deprecatedConventions != null) ? new ProcessorMetrics(Collections.emptyList(), deprecatedConventions)
|
return (deprecatedConventions != null) ? new ProcessorMetrics(Collections.emptyList(), deprecatedConventions)
|
||||||
: factory.create();
|
: factory.create(observationProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@@ -103,9 +106,12 @@ public final class SystemMetricsAutoConfiguration {
|
|||||||
return this.cpuTimeConvention != null || this.cpuCountConvention != null || this.cpuLoadConvention != null;
|
return this.cpuTimeConvention != null || this.cpuCountConvention != null || this.cpuLoadConvention != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessorMetrics create() {
|
ProcessorMetrics create(ObservationProperties observationProperties) {
|
||||||
PropertyMapper map = PropertyMapper.get();
|
|
||||||
ProcessorMetrics.Builder builder = ProcessorMetrics.builder();
|
ProcessorMetrics.Builder builder = ProcessorMetrics.builder();
|
||||||
|
if (observationProperties.getConventions() == ConventionsVariant.OPENTELEMETRY) {
|
||||||
|
builder.openTelemetryConventions();
|
||||||
|
}
|
||||||
|
PropertyMapper map = PropertyMapper.get();
|
||||||
map.from(this.cpuTimeConvention).to(builder::cpuTimeConvention);
|
map.from(this.cpuTimeConvention).to(builder::cpuTimeConvention);
|
||||||
map.from(this.cpuCountConvention).to(builder::cpuCountConvention);
|
map.from(this.cpuCountConvention).to(builder::cpuCountConvention);
|
||||||
map.from(this.cpuLoadConvention).to(builder::cpuLoadConvention);
|
map.from(this.cpuLoadConvention).to(builder::cpuLoadConvention);
|
||||||
|
|||||||
+77
@@ -33,12 +33,22 @@ import io.micrometer.core.instrument.binder.jvm.convention.JvmClassUnloadedMeter
|
|||||||
import io.micrometer.core.instrument.binder.jvm.convention.JvmMemoryCommittedMeterConvention;
|
import io.micrometer.core.instrument.binder.jvm.convention.JvmMemoryCommittedMeterConvention;
|
||||||
import io.micrometer.core.instrument.binder.jvm.convention.JvmMemoryMaxMeterConvention;
|
import io.micrometer.core.instrument.binder.jvm.convention.JvmMemoryMaxMeterConvention;
|
||||||
import io.micrometer.core.instrument.binder.jvm.convention.JvmMemoryMeterConventions;
|
import io.micrometer.core.instrument.binder.jvm.convention.JvmMemoryMeterConventions;
|
||||||
|
import io.micrometer.core.instrument.binder.jvm.convention.JvmMemoryUsedAfterLastGcMeterConvention;
|
||||||
import io.micrometer.core.instrument.binder.jvm.convention.JvmMemoryUsedMeterConvention;
|
import io.micrometer.core.instrument.binder.jvm.convention.JvmMemoryUsedMeterConvention;
|
||||||
import io.micrometer.core.instrument.binder.jvm.convention.JvmThreadCountMeterConvention;
|
import io.micrometer.core.instrument.binder.jvm.convention.JvmThreadCountMeterConvention;
|
||||||
import io.micrometer.core.instrument.binder.jvm.convention.JvmThreadMeterConventions;
|
import io.micrometer.core.instrument.binder.jvm.convention.JvmThreadMeterConventions;
|
||||||
|
import io.micrometer.core.instrument.binder.jvm.convention.micrometer.MicrometerJvmClassCountMeterConvention;
|
||||||
import io.micrometer.core.instrument.binder.jvm.convention.micrometer.MicrometerJvmClassLoadingMeterConventions;
|
import io.micrometer.core.instrument.binder.jvm.convention.micrometer.MicrometerJvmClassLoadingMeterConventions;
|
||||||
import io.micrometer.core.instrument.binder.jvm.convention.micrometer.MicrometerJvmMemoryMeterConventions;
|
import io.micrometer.core.instrument.binder.jvm.convention.micrometer.MicrometerJvmMemoryMeterConventions;
|
||||||
|
import io.micrometer.core.instrument.binder.jvm.convention.micrometer.MicrometerJvmMemoryUsedAfterLastGcMeterConvention;
|
||||||
|
import io.micrometer.core.instrument.binder.jvm.convention.micrometer.MicrometerJvmMemoryUsedMeterConvention;
|
||||||
|
import io.micrometer.core.instrument.binder.jvm.convention.micrometer.MicrometerJvmThreadCountMeterConvention;
|
||||||
import io.micrometer.core.instrument.binder.jvm.convention.micrometer.MicrometerJvmThreadMeterConventions;
|
import io.micrometer.core.instrument.binder.jvm.convention.micrometer.MicrometerJvmThreadMeterConventions;
|
||||||
|
import io.micrometer.core.instrument.binder.jvm.convention.otel.OpenTelemetryJvmClassCountMeterConvention;
|
||||||
|
import io.micrometer.core.instrument.binder.jvm.convention.otel.OpenTelemetryJvmMemoryCommittedMeterConvention;
|
||||||
|
import io.micrometer.core.instrument.binder.jvm.convention.otel.OpenTelemetryJvmMemoryUsedAfterLastGcMeterConvention;
|
||||||
|
import io.micrometer.core.instrument.binder.jvm.convention.otel.OpenTelemetryJvmMemoryUsedMeterConvention;
|
||||||
|
import io.micrometer.core.instrument.binder.jvm.convention.otel.OpenTelemetryJvmThreadCountMeterConvention;
|
||||||
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
|
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.condition.EnabledForJreRange;
|
import org.junit.jupiter.api.condition.EnabledForJreRange;
|
||||||
@@ -80,6 +90,62 @@ class JvmMetricsAutoConfigurationTests {
|
|||||||
this.contextRunner.run(assertMetricsBeans());
|
this.contextRunner.run(assertMetricsBeans());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void autoConfiguresJvmMetricsWithDefaultConventions() {
|
||||||
|
this.contextRunner.run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(JvmMemoryMetrics.class)
|
||||||
|
.getBean(JvmMemoryMetrics.class)
|
||||||
|
.extracting("memoryUsedConvention")
|
||||||
|
.isInstanceOf(MicrometerJvmMemoryUsedMeterConvention.class);
|
||||||
|
assertThat(context.getBean(JvmMemoryMetrics.class)).extracting("memoryUsedAfterLastGcConvention")
|
||||||
|
.isInstanceOf(MicrometerJvmMemoryUsedAfterLastGcMeterConvention.class);
|
||||||
|
assertThat(context).hasSingleBean(JvmThreadMetrics.class)
|
||||||
|
.getBean(JvmThreadMetrics.class)
|
||||||
|
.extracting("threadCountConvention")
|
||||||
|
.isInstanceOf(MicrometerJvmThreadCountMeterConvention.class);
|
||||||
|
assertThat(context).hasSingleBean(ClassLoaderMetrics.class)
|
||||||
|
.getBean(ClassLoaderMetrics.class)
|
||||||
|
.extracting("classCountConvention")
|
||||||
|
.isInstanceOf(MicrometerJvmClassCountMeterConvention.class);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void autoConfiguresJvmMetricsWithOpenTelemetryConventions() {
|
||||||
|
this.contextRunner.withPropertyValues("management.observations.conventions=opentelemetry").run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(JvmMemoryMetrics.class)
|
||||||
|
.getBean(JvmMemoryMetrics.class)
|
||||||
|
.extracting("memoryUsedConvention")
|
||||||
|
.isInstanceOf(OpenTelemetryJvmMemoryUsedMeterConvention.class);
|
||||||
|
assertThat(context.getBean(JvmMemoryMetrics.class)).extracting("memoryUsedAfterLastGcConvention")
|
||||||
|
.isInstanceOf(OpenTelemetryJvmMemoryUsedAfterLastGcMeterConvention.class);
|
||||||
|
assertThat(context).hasSingleBean(JvmThreadMetrics.class)
|
||||||
|
.getBean(JvmThreadMetrics.class)
|
||||||
|
.extracting("threadCountConvention")
|
||||||
|
.isInstanceOf(OpenTelemetryJvmThreadCountMeterConvention.class);
|
||||||
|
assertThat(context).hasSingleBean(ClassLoaderMetrics.class)
|
||||||
|
.getBean(ClassLoaderMetrics.class)
|
||||||
|
.extracting("classCountConvention")
|
||||||
|
.isInstanceOf(OpenTelemetryJvmClassCountMeterConvention.class);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void allowsIndividualConventionToBeOverriddenWithOpenTelemetryConventions() {
|
||||||
|
JvmMemoryUsedMeterConvention customUsed = mock(JvmMemoryUsedMeterConvention.class);
|
||||||
|
this.contextRunner.withPropertyValues("management.observations.conventions=opentelemetry")
|
||||||
|
.withBean(JvmMemoryUsedMeterConvention.class, () -> customUsed)
|
||||||
|
.run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(JvmMemoryMetrics.class)
|
||||||
|
.getBean(JvmMemoryMetrics.class)
|
||||||
|
.hasFieldOrPropertyWithValue("memoryUsedConvention", customUsed);
|
||||||
|
assertThat(context.getBean(JvmMemoryMetrics.class)).extracting("memoryCommittedConvention")
|
||||||
|
.isInstanceOf(OpenTelemetryJvmMemoryCommittedMeterConvention.class);
|
||||||
|
assertThat(context.getBean(JvmMemoryMetrics.class)).extracting("memoryUsedAfterLastGcConvention")
|
||||||
|
.isInstanceOf(OpenTelemetryJvmMemoryUsedAfterLastGcMeterConvention.class);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void allowsCustomJvmGcMetricsToBeUsed() {
|
void allowsCustomJvmGcMetricsToBeUsed() {
|
||||||
this.contextRunner.withUserConfiguration(CustomJvmGcMetricsConfiguration.class)
|
this.contextRunner.withUserConfiguration(CustomJvmGcMetricsConfiguration.class)
|
||||||
@@ -171,6 +237,17 @@ class JvmMetricsAutoConfigurationTests {
|
|||||||
.hasFieldOrPropertyWithValue("memoryMaxConvention", memoryMaxConvention));
|
.hasFieldOrPropertyWithValue("memoryMaxConvention", memoryMaxConvention));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void allowCustomJvmMemoryUsedAfterLastGcMeterConventionToBeUsed() {
|
||||||
|
JvmMemoryUsedAfterLastGcMeterConvention memoryUsedAfterLastGcConvention = mock(
|
||||||
|
JvmMemoryUsedAfterLastGcMeterConvention.class);
|
||||||
|
this.contextRunner
|
||||||
|
.withBean(JvmMemoryUsedAfterLastGcMeterConvention.class, () -> memoryUsedAfterLastGcConvention)
|
||||||
|
.run((context) -> assertThat(context).hasSingleBean(JvmMemoryMetrics.class)
|
||||||
|
.getBean(JvmMemoryMetrics.class)
|
||||||
|
.hasFieldOrPropertyWithValue("memoryUsedAfterLastGcConvention", memoryUsedAfterLastGcConvention));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void allowsCustomJvmThreadMetricsToBeUsed() {
|
void allowsCustomJvmThreadMetricsToBeUsed() {
|
||||||
this.contextRunner.withUserConfiguration(CustomJvmThreadMetricsConfiguration.class)
|
this.contextRunner.withUserConfiguration(CustomJvmThreadMetricsConfiguration.class)
|
||||||
|
|||||||
+32
@@ -25,7 +25,10 @@ import io.micrometer.core.instrument.binder.jvm.convention.JvmCpuCountMeterConve
|
|||||||
import io.micrometer.core.instrument.binder.jvm.convention.JvmCpuLoadMeterConvention;
|
import io.micrometer.core.instrument.binder.jvm.convention.JvmCpuLoadMeterConvention;
|
||||||
import io.micrometer.core.instrument.binder.jvm.convention.JvmCpuMeterConventions;
|
import io.micrometer.core.instrument.binder.jvm.convention.JvmCpuMeterConventions;
|
||||||
import io.micrometer.core.instrument.binder.jvm.convention.JvmCpuTimeMeterConvention;
|
import io.micrometer.core.instrument.binder.jvm.convention.JvmCpuTimeMeterConvention;
|
||||||
|
import io.micrometer.core.instrument.binder.jvm.convention.micrometer.MicrometerJvmCpuCountMeterConvention;
|
||||||
import io.micrometer.core.instrument.binder.jvm.convention.micrometer.MicrometerJvmCpuMeterConventions;
|
import io.micrometer.core.instrument.binder.jvm.convention.micrometer.MicrometerJvmCpuMeterConventions;
|
||||||
|
import io.micrometer.core.instrument.binder.jvm.convention.otel.OpenTelemetryJvmCpuCountMeterConvention;
|
||||||
|
import io.micrometer.core.instrument.binder.jvm.convention.otel.OpenTelemetryJvmCpuLoadMeterConvention;
|
||||||
import io.micrometer.core.instrument.binder.system.FileDescriptorMetrics;
|
import io.micrometer.core.instrument.binder.system.FileDescriptorMetrics;
|
||||||
import io.micrometer.core.instrument.binder.system.ProcessorMetrics;
|
import io.micrometer.core.instrument.binder.system.ProcessorMetrics;
|
||||||
import io.micrometer.core.instrument.binder.system.UptimeMetrics;
|
import io.micrometer.core.instrument.binder.system.UptimeMetrics;
|
||||||
@@ -73,6 +76,35 @@ class SystemMetricsAutoConfigurationTests {
|
|||||||
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ProcessorMetrics.class));
|
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ProcessorMetrics.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void autoConfiguresProcessorMetricsWithDefaultConventions() {
|
||||||
|
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ProcessorMetrics.class)
|
||||||
|
.getBean(ProcessorMetrics.class)
|
||||||
|
.extracting("cpuCountConvention")
|
||||||
|
.isInstanceOf(MicrometerJvmCpuCountMeterConvention.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void autoConfiguresProcessorMetricsWithOpenTelemetryConventions() {
|
||||||
|
this.contextRunner.withPropertyValues("management.observations.conventions=opentelemetry")
|
||||||
|
.run((context) -> assertThat(context).hasSingleBean(ProcessorMetrics.class)
|
||||||
|
.getBean(ProcessorMetrics.class)
|
||||||
|
.extracting("cpuCountConvention")
|
||||||
|
.isInstanceOf(OpenTelemetryJvmCpuCountMeterConvention.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void allowsIndividualConventionToBeOverriddenWithOpenTelemetryConventions() {
|
||||||
|
JvmCpuCountMeterConvention customCount = mock(JvmCpuCountMeterConvention.class);
|
||||||
|
this.contextRunner.withPropertyValues("management.observations.conventions=opentelemetry")
|
||||||
|
.withBean(JvmCpuCountMeterConvention.class, () -> customCount)
|
||||||
|
.run((context) -> assertThat(context).hasSingleBean(ProcessorMetrics.class)
|
||||||
|
.getBean(ProcessorMetrics.class)
|
||||||
|
.hasFieldOrPropertyWithValue("cpuCountConvention", customCount)
|
||||||
|
.extracting("cpuLoadConvention")
|
||||||
|
.isInstanceOf(OpenTelemetryJvmCpuLoadMeterConvention.class));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void allowsCustomProcessorMetricsToBeUsed() {
|
void allowsCustomProcessorMetricsToBeUsed() {
|
||||||
this.contextRunner.withUserConfiguration(CustomProcessorMetricsConfiguration.class)
|
this.contextRunner.withUserConfiguration(CustomProcessorMetricsConfiguration.class)
|
||||||
|
|||||||
+19
@@ -45,6 +45,11 @@ public class ObservationProperties {
|
|||||||
*/
|
*/
|
||||||
private Map<String, Boolean> enable = new LinkedHashMap<>();
|
private Map<String, Boolean> enable = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Conventions variant to use when configuring observations and metrics.
|
||||||
|
*/
|
||||||
|
private ConventionsVariant conventions = ConventionsVariant.MICROMETER;
|
||||||
|
|
||||||
public Map<String, Boolean> getEnable() {
|
public Map<String, Boolean> getEnable() {
|
||||||
return this.enable;
|
return this.enable;
|
||||||
}
|
}
|
||||||
@@ -65,6 +70,20 @@ public class ObservationProperties {
|
|||||||
this.keyValues = keyValues;
|
this.keyValues = keyValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ConventionsVariant getConventions() {
|
||||||
|
return this.conventions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConventions(ConventionsVariant conventions) {
|
||||||
|
this.conventions = conventions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ConventionsVariant {
|
||||||
|
|
||||||
|
OPENTELEMETRY, MICROMETER,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public static class Http {
|
public static class Http {
|
||||||
|
|
||||||
private final Client client = new Client();
|
private final Client client = new Client();
|
||||||
|
|||||||
+12
-1
@@ -25,6 +25,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
|||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
@@ -34,6 +35,7 @@ import org.springframework.boot.micrometer.observation.autoconfigure.Observation
|
|||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.http.server.reactive.observation.DefaultServerRequestObservationConvention;
|
import org.springframework.http.server.reactive.observation.DefaultServerRequestObservationConvention;
|
||||||
|
import org.springframework.http.server.reactive.observation.OpenTelemetryServerRequestObservationConvention;
|
||||||
import org.springframework.http.server.reactive.observation.ServerRequestObservationConvention;
|
import org.springframework.http.server.reactive.observation.ServerRequestObservationConvention;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -71,9 +73,18 @@ public final class WebFluxObservationAutoConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean(ServerRequestObservationConvention.class)
|
@ConditionalOnMissingBean(ServerRequestObservationConvention.class)
|
||||||
DefaultServerRequestObservationConvention defaultServerRequestObservationConvention() {
|
@ConditionalOnProperty(name = "management.observations.conventions", havingValue = "micrometer",
|
||||||
|
matchIfMissing = true)
|
||||||
|
DefaultServerRequestObservationConvention micrometerServerRequestObservationConvention() {
|
||||||
return new DefaultServerRequestObservationConvention(
|
return new DefaultServerRequestObservationConvention(
|
||||||
this.observationProperties.getHttp().getServer().getRequests().getName());
|
this.observationProperties.getHttp().getServer().getRequests().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(ServerRequestObservationConvention.class)
|
||||||
|
@ConditionalOnProperty(name = "management.observations.conventions", havingValue = "opentelemetry")
|
||||||
|
OpenTelemetryServerRequestObservationConvention openTelemetryServerRequestObservationConvention() {
|
||||||
|
return new OpenTelemetryServerRequestObservationConvention();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+7
@@ -32,6 +32,7 @@ import org.springframework.boot.test.context.runner.ReactiveWebApplicationContex
|
|||||||
import org.springframework.boot.test.system.CapturedOutput;
|
import org.springframework.boot.test.system.CapturedOutput;
|
||||||
import org.springframework.boot.test.system.OutputCaptureExtension;
|
import org.springframework.boot.test.system.OutputCaptureExtension;
|
||||||
import org.springframework.http.server.reactive.observation.DefaultServerRequestObservationConvention;
|
import org.springframework.http.server.reactive.observation.DefaultServerRequestObservationConvention;
|
||||||
|
import org.springframework.http.server.reactive.observation.OpenTelemetryServerRequestObservationConvention;
|
||||||
import org.springframework.http.server.reactive.observation.ServerRequestObservationConvention;
|
import org.springframework.http.server.reactive.observation.ServerRequestObservationConvention;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
@@ -107,6 +108,12 @@ class WebFluxObservationAutoConfigurationTests {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void openTelemetryConventionConfiguredViaProperties() {
|
||||||
|
this.contextRunner.withPropertyValues("management.observations.conventions=opentelemetry")
|
||||||
|
.run((context) -> assertThat(context).hasSingleBean(OpenTelemetryServerRequestObservationConvention.class));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldBackOffOnCustomServerRequestObservationConvention() {
|
void shouldBackOffOnCustomServerRequestObservationConvention() {
|
||||||
this.contextRunner
|
this.contextRunner
|
||||||
|
|||||||
+21
-6
@@ -21,12 +21,13 @@ import io.micrometer.observation.Observation;
|
|||||||
import io.micrometer.observation.ObservationRegistry;
|
import io.micrometer.observation.ObservationRegistry;
|
||||||
import jakarta.servlet.DispatcherType;
|
import jakarta.servlet.DispatcherType;
|
||||||
|
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingFilterBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingFilterBean;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
@@ -39,6 +40,7 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.http.server.observation.DefaultServerRequestObservationConvention;
|
import org.springframework.http.server.observation.DefaultServerRequestObservationConvention;
|
||||||
|
import org.springframework.http.server.observation.OpenTelemetryServerRequestObservationConvention;
|
||||||
import org.springframework.http.server.observation.ServerRequestObservationConvention;
|
import org.springframework.http.server.observation.ServerRequestObservationConvention;
|
||||||
import org.springframework.web.filter.ServerHttpObservationFilter;
|
import org.springframework.web.filter.ServerHttpObservationFilter;
|
||||||
import org.springframework.web.servlet.DispatcherServlet;
|
import org.springframework.web.servlet.DispatcherServlet;
|
||||||
@@ -64,13 +66,26 @@ import org.springframework.web.servlet.DispatcherServlet;
|
|||||||
public final class WebMvcObservationAutoConfiguration {
|
public final class WebMvcObservationAutoConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingFilterBean
|
@ConditionalOnMissingBean(ServerRequestObservationConvention.class)
|
||||||
FilterRegistrationBean<ServerHttpObservationFilter> webMvcObservationFilter(ObservationRegistry registry,
|
@ConditionalOnProperty(name = "management.observations.conventions", havingValue = "micrometer",
|
||||||
ObjectProvider<ServerRequestObservationConvention> customConvention,
|
matchIfMissing = true)
|
||||||
|
DefaultServerRequestObservationConvention micrometerServerRequestObservationConvention(
|
||||||
ObservationProperties observationProperties) {
|
ObservationProperties observationProperties) {
|
||||||
String name = observationProperties.getHttp().getServer().getRequests().getName();
|
String name = observationProperties.getHttp().getServer().getRequests().getName();
|
||||||
ServerRequestObservationConvention convention = customConvention
|
return new DefaultServerRequestObservationConvention(name);
|
||||||
.getIfAvailable(() -> new DefaultServerRequestObservationConvention(name));
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(ServerRequestObservationConvention.class)
|
||||||
|
@ConditionalOnProperty(name = "management.observations.conventions", havingValue = "opentelemetry")
|
||||||
|
OpenTelemetryServerRequestObservationConvention openTelemetryServerRequestObservationConvention() {
|
||||||
|
return new OpenTelemetryServerRequestObservationConvention();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingFilterBean
|
||||||
|
FilterRegistrationBean<ServerHttpObservationFilter> webMvcObservationFilter(ObservationRegistry registry,
|
||||||
|
ServerRequestObservationConvention convention) {
|
||||||
ServerHttpObservationFilter filter = new ServerHttpObservationFilter(registry, convention);
|
ServerHttpObservationFilter filter = new ServerHttpObservationFilter(registry, convention);
|
||||||
FilterRegistrationBean<ServerHttpObservationFilter> registration = new FilterRegistrationBean<>(filter);
|
FilterRegistrationBean<ServerHttpObservationFilter> registration = new FilterRegistrationBean<>(filter);
|
||||||
registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
|
registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
|
||||||
|
|||||||
+13
@@ -45,6 +45,7 @@ import org.springframework.context.annotation.Bean;
|
|||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.http.server.observation.DefaultServerRequestObservationConvention;
|
import org.springframework.http.server.observation.DefaultServerRequestObservationConvention;
|
||||||
|
import org.springframework.http.server.observation.OpenTelemetryServerRequestObservationConvention;
|
||||||
import org.springframework.test.web.servlet.assertj.MockMvcTester;
|
import org.springframework.test.web.servlet.assertj.MockMvcTester;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
@@ -92,6 +93,18 @@ class WebMvcObservationAutoConfigurationTests {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void defaultMicrometerConvention() {
|
||||||
|
this.contextRunner
|
||||||
|
.run((context) -> assertThat(context).hasSingleBean(DefaultServerRequestObservationConvention.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void openTelemetryConventionConfiguredViaProperties() {
|
||||||
|
this.contextRunner.withPropertyValues("management.observations.conventions=opentelemetry")
|
||||||
|
.run((context) -> assertThat(context).hasSingleBean(OpenTelemetryServerRequestObservationConvention.class));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void customConventionWhenPresent() {
|
void customConventionWhenPresent() {
|
||||||
this.contextRunner.withUserConfiguration(CustomConventionConfiguration.class)
|
this.contextRunner.withUserConfiguration(CustomConventionConfiguration.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user