From 7b90fbb0b2ef73871ca776d9f999e9cdc1cb7e6d Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Tue, 13 Jun 2023 12:01:39 +0200 Subject: [PATCH] Add property to specify the order of ServerHttpObservationFilter The property is named 'management.observations.http.server.filter.order' Closes gh-35067 --- .../observation/ObservationProperties.java | 24 ++++++++++ .../OrderedServerHttpObservationFilter.java | 46 +++++++++++++++++++ .../WebFluxObservationAutoConfiguration.java | 10 ++-- ...FluxObservationAutoConfigurationTests.java | 10 ++++ 4 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/OrderedServerHttpObservationFilter.java diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationProperties.java index 92f8e8b0fe2..27c2473cc63 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationProperties.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationProperties.java @@ -20,6 +20,7 @@ import java.util.LinkedHashMap; import java.util.Map; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.core.Ordered; /** * {@link ConfigurationProperties @ConfigurationProperties} for configuring Micrometer @@ -96,10 +97,16 @@ public class ObservationProperties { private final ServerRequests requests = new ServerRequests(); + private final Filter filter = new Filter(); + public ServerRequests getRequests() { return this.requests; } + public Filter getFilter() { + return this.filter; + } + public static class ServerRequests { /** @@ -118,6 +125,23 @@ public class ObservationProperties { } + public static class Filter { + + /** + * Order of the filter that creates the observations. + */ + private int order = Ordered.HIGHEST_PRECEDENCE + 1; + + public int getOrder() { + return this.order; + } + + public void setOrder(int order) { + this.order = order; + } + + } + } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/OrderedServerHttpObservationFilter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/OrderedServerHttpObservationFilter.java new file mode 100644 index 00000000000..9d3146f1dbe --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/OrderedServerHttpObservationFilter.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2023 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.actuate.autoconfigure.observation.web.reactive; + +import io.micrometer.observation.ObservationRegistry; + +import org.springframework.boot.web.reactive.filter.OrderedWebFilter; +import org.springframework.core.Ordered; +import org.springframework.http.server.reactive.observation.ServerRequestObservationConvention; +import org.springframework.web.filter.reactive.ServerHttpObservationFilter; + +/** + * {@link ServerHttpObservationFilter} that also implements {@link Ordered}. + * + * @author Moritz Halbritter + */ +class OrderedServerHttpObservationFilter extends ServerHttpObservationFilter implements OrderedWebFilter { + + private final int order; + + OrderedServerHttpObservationFilter(ObservationRegistry observationRegistry, + ServerRequestObservationConvention observationConvention, int order) { + super(observationRegistry, observationConvention); + this.order = order; + } + + @Override + public int getOrder() { + return this.order; + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfiguration.java index a998e6b5d24..83c67a60736 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfiguration.java @@ -42,7 +42,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplicat import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.http.server.reactive.observation.DefaultServerRequestObservationConvention; import org.springframework.http.server.reactive.observation.ServerRequestObservationConvention; @@ -55,6 +54,7 @@ import org.springframework.web.filter.reactive.ServerHttpObservationFilter; * @author Brian Clozel * @author Jon Schneider * @author Dmytro Nosan + * @author Moritz Halbritter * @since 3.0.0 */ @AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class, @@ -77,9 +77,8 @@ public class WebFluxObservationAutoConfiguration { } @Bean - @ConditionalOnMissingBean - @Order(Ordered.HIGHEST_PRECEDENCE + 1) - public ServerHttpObservationFilter webfluxObservationFilter(ObservationRegistry registry, + @ConditionalOnMissingBean(ServerHttpObservationFilter.class) + public OrderedServerHttpObservationFilter webfluxObservationFilter(ObservationRegistry registry, ObjectProvider customConvention, ObjectProvider tagConfigurer, ObjectProvider contributorsProvider) { @@ -90,7 +89,8 @@ public class WebFluxObservationAutoConfiguration { List tagsContributors = contributorsProvider.orderedStream().toList(); ServerRequestObservationConvention convention = createConvention(customConvention.getIfAvailable(), name, tagsProvider, tagsContributors); - return new ServerHttpObservationFilter(registry, convention); + int order = this.observationProperties.getHttp().getServer().getFilter().getOrder(); + return new OrderedServerHttpObservationFilter(registry, convention, order); } private static ServerRequestObservationConvention createConvention( diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfigurationTests.java index 88609e23f68..d8197198eb4 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfigurationTests.java @@ -57,6 +57,7 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Brian Clozel * @author Dmytro Nosan * @author Madhura Bhave + * @author Moritz Halbritter */ @ExtendWith(OutputCaptureExtension.class) @SuppressWarnings("removal") @@ -169,6 +170,15 @@ class WebFluxObservationAutoConfigurationTests { }); } + @Test + void shouldUsePropertyForServerHttpObservationFilterOrder() { + this.contextRunner.withPropertyValues("management.observations.http.server.filter.order=1000") + .run((context) -> { + OrderedServerHttpObservationFilter bean = context.getBean(OrderedServerHttpObservationFilter.class); + assertThat(bean.getOrder()).isEqualTo(1000); + }); + } + private MeterRegistry getInitializedMeterRegistry(AssertableReactiveWebApplicationContext context) throws Exception { return getInitializedMeterRegistry(context, "/test0", "/test1", "/test2");