Skip to content

Commit 764428c

Browse files
committed
Auto-configure OtlpMetricsSender if available
A new interface OtlpMetricsSender was introduced to allow users to customize the sending of OTLP metrics using the OtlpMeterRegistry. This configures it, if available as a bean, on the auto-configured OtlpMeterRegistry.
1 parent 752842a commit 764428c

File tree

3 files changed

+57
-4
lines changed

3 files changed

+57
-4
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsExportAutoConfiguration.java

+15-4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@
1919
import io.micrometer.core.instrument.Clock;
2020
import io.micrometer.registry.otlp.OtlpConfig;
2121
import io.micrometer.registry.otlp.OtlpMeterRegistry;
22+
import io.micrometer.registry.otlp.OtlpMeterRegistry.Builder;
23+
import io.micrometer.registry.otlp.OtlpMetricsSender;
2224

25+
import org.springframework.beans.factory.ObjectProvider;
2326
import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration;
2427
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
2528
import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport;
@@ -76,16 +79,24 @@ OtlpConfig otlpConfig(OpenTelemetryProperties openTelemetryProperties,
7679
@Bean
7780
@ConditionalOnMissingBean
7881
@ConditionalOnThreading(Threading.PLATFORM)
79-
public OtlpMeterRegistry otlpMeterRegistry(OtlpConfig otlpConfig, Clock clock) {
80-
return new OtlpMeterRegistry(otlpConfig, clock);
82+
public OtlpMeterRegistry otlpMeterRegistry(OtlpConfig otlpConfig, Clock clock,
83+
ObjectProvider<OtlpMetricsSender> metricsSender) {
84+
Builder builder = OtlpMeterRegistry.builder(otlpConfig).clock(clock);
85+
metricsSender.ifAvailable(builder::metricsSender);
86+
return builder.build();
8187
}
8288

8389
@Bean
8490
@ConditionalOnMissingBean
8591
@ConditionalOnThreading(Threading.VIRTUAL)
86-
public OtlpMeterRegistry otlpMeterRegistryVirtualThreads(OtlpConfig otlpConfig, Clock clock) {
92+
public OtlpMeterRegistry otlpMeterRegistryVirtualThreads(OtlpConfig otlpConfig, Clock clock,
93+
ObjectProvider<OtlpMetricsSender> metricsSender) {
8794
VirtualThreadTaskExecutor taskExecutor = new VirtualThreadTaskExecutor("otlp-meter-registry-");
88-
return new OtlpMeterRegistry(otlpConfig, clock, taskExecutor.getVirtualThreadFactory());
95+
Builder builder = OtlpMeterRegistry.builder(otlpConfig)
96+
.clock(clock)
97+
.threadFactory(taskExecutor.getVirtualThreadFactory());
98+
metricsSender.ifAvailable(builder::metricsSender);
99+
return builder.build();
89100
}
90101

91102
/**

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsExportAutoConfigurationTests.java

+40
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import io.micrometer.core.instrument.Clock;
2222
import io.micrometer.registry.otlp.OtlpConfig;
2323
import io.micrometer.registry.otlp.OtlpMeterRegistry;
24+
import io.micrometer.registry.otlp.OtlpMetricsSender;
2425
import org.junit.jupiter.api.Test;
2526
import org.junit.jupiter.api.condition.EnabledForJreRange;
2627
import org.junit.jupiter.api.condition.JRE;
@@ -132,6 +133,32 @@ void testConnectionFactoryWithOverridesWhenUsingCustomConnectionDetails() {
132133
});
133134
}
134135

136+
@Test
137+
void allowsCustomMetricsSenderToBeUsed() {
138+
this.contextRunner.withUserConfiguration(BaseConfiguration.class, CustomMetricsSenderConfiguration.class)
139+
.run((context) -> {
140+
assertThat(context).hasSingleBean(OtlpMeterRegistry.class);
141+
OtlpMeterRegistry registry = context.getBean(OtlpMeterRegistry.class);
142+
assertThat(registry).extracting("metricsSender")
143+
.satisfies((sender) -> assertThat(sender)
144+
.isSameAs(CustomMetricsSenderConfiguration.customMetricsSender));
145+
});
146+
}
147+
148+
@Test
149+
@EnabledForJreRange(min = JRE.JAVA_21)
150+
void allowsCustomMetricsSenderToBeUsedWithVirtualThreads() {
151+
this.contextRunner.withUserConfiguration(BaseConfiguration.class, CustomMetricsSenderConfiguration.class)
152+
.withPropertyValues("spring.threads.virtual.enabled=true")
153+
.run((context) -> {
154+
assertThat(context).hasSingleBean(OtlpMeterRegistry.class);
155+
OtlpMeterRegistry registry = context.getBean(OtlpMeterRegistry.class);
156+
assertThat(registry).extracting("metricsSender")
157+
.satisfies((sender) -> assertThat(sender)
158+
.isSameAs(CustomMetricsSenderConfiguration.customMetricsSender));
159+
});
160+
}
161+
135162
@Configuration(proxyBeanMethods = false)
136163
static class BaseConfiguration {
137164

@@ -174,4 +201,17 @@ OtlpMetricsConnectionDetails otlpConnectionDetails() {
174201

175202
}
176203

204+
@Configuration(proxyBeanMethods = false)
205+
static class CustomMetricsSenderConfiguration {
206+
207+
static OtlpMetricsSender customMetricsSender = request -> {
208+
};
209+
210+
@Bean
211+
OtlpMetricsSender customMetricsSender() {
212+
return customMetricsSender;
213+
}
214+
215+
}
216+
177217
}

spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/metrics.adoc

+2
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,8 @@ management:
522522

523523
Custom headers, for example for authentication, can also be provided using configprop:management.otlp.metrics.export.headers.*[] properties.
524524

525+
If an `OtlpMetricsSender` bean is available, it will be configured on the `OtlpMeterRegistry` that Spring Boot auto-configures.
526+
525527

526528

527529
[[actuator.metrics.export.prometheus]]

0 commit comments

Comments
 (0)