diff --git a/buildSrc/src/main/resources/org/springframework/boot/build/antora/antora-asciidoc-attributes.properties b/buildSrc/src/main/resources/org/springframework/boot/build/antora/antora-asciidoc-attributes.properties index 82eba8024b6..0183ad7e7c1 100644 --- a/buildSrc/src/main/resources/org/springframework/boot/build/antora/antora-asciidoc-attributes.properties +++ b/buildSrc/src/main/resources/org/springframework/boot/build/antora/antora-asciidoc-attributes.properties @@ -27,8 +27,8 @@ url-gradle-dsl=https://docs.gradle.org/current/dsl url-gradle-javadoc=https://docs.gradle.org/current/javadoc url-kotlin-docs-kotlin-plugin={url-kotlin-docs}/using-gradle.html url-micrometer-docs-concepts={url-micrometer-docs}/concepts -url-micrometer-docs-observation={url-micrometer-docs}/observation url-micrometer-docs-implementations={url-micrometer-docs}/implementations +url-micrometer-docs-observation={url-micrometer-docs}/observation url-native-build-tools-docs=https://graalvm.github.io/native-build-tools/{version-native-build-tools} url-native-build-tools-docs-gradle-plugin={url-native-build-tools-docs}/gradle-plugin.html url-native-build-tools-docs-maven-plugin={url-native-build-tools-docs}/maven-plugin.html diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/ObservationFilterConfigurations.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/ObservationFilterConfigurations.java index 2bff98ee499..e9f5a980be4 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/ObservationFilterConfigurations.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/ObservationFilterConfigurations.java @@ -23,8 +23,8 @@ import jakarta.servlet.DispatcherType; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.actuate.autoconfigure.observation.ObservationProperties; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.web.servlet.ConditionalOnMissingFilterBean; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; @@ -54,7 +54,7 @@ abstract class ObservationFilterConfigurations { static class TracingHeaderObservation { @Bean - @ConditionalOnProperty(prefix = "management.observations.http.server.requests", name = "write-trace-header") + @ConditionalOnBooleanProperty("management.observations.http.server.requests.write-trace-header") @ConditionalOnBean(Tracer.class) @ConditionalOnMissingFilterBean({ ServerHttpObservationFilter.class, TraceHeaderObservationFilter.class }) FilterRegistrationBean webMvcObservationFilter(ObservationRegistry registry, diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/TraceHeaderObservationFilter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/TraceHeaderObservationFilter.java index 98f0c3b7dc2..47ea0783e9e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/TraceHeaderObservationFilter.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/TraceHeaderObservationFilter.java @@ -48,7 +48,7 @@ public class TraceHeaderObservationFilter extends ServerHttpObservationFilter { */ public TraceHeaderObservationFilter(Tracer tracer, ObservationRegistry observationRegistry) { super(observationRegistry); - Assert.notNull(tracer, "Tracer must not be null"); + Assert.notNull(tracer, "'tracer' must not be null"); this.tracer = tracer; } @@ -62,7 +62,7 @@ public class TraceHeaderObservationFilter extends ServerHttpObservationFilter { public TraceHeaderObservationFilter(Tracer tracer, ObservationRegistry observationRegistry, ServerRequestObservationConvention observationConvention) { super(observationRegistry, observationConvention); - Assert.notNull(tracer, "Tracer must not be null"); + Assert.notNull(tracer, "'tracer' must not be null"); this.tracer = tracer; } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/TraceHeaderObservationFilterTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/TraceHeaderObservationFilterTests.java index 8e519aac8d7..75d7a7a13ff 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/TraceHeaderObservationFilterTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/TraceHeaderObservationFilterTests.java @@ -30,6 +30,8 @@ import static org.assertj.core.api.Assertions.assertThat; /** * Tests for {@link TraceHeaderObservationFilter}. + * + * @author Brian Clozel */ class TraceHeaderObservationFilterTests { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfigurationTests.java index 2506ee28916..d044fdec7f6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfigurationTests.java @@ -165,7 +165,7 @@ class WebMvcObservationAutoConfigurationTests { } @Test - void filterRegistrationBacksOffWithAnothertestTraceHeaderObservationFilter() { + void filterRegistrationBacksOffWithAnotherTraceHeaderObservationFilter() { this.contextRunner.withConfiguration(AutoConfigurations.of(NoopTracerAutoConfiguration.class)) .withPropertyValues("management.observations.http.server.requests.write-trace-header=true") .withUserConfiguration(TestTraceHeaderObservationFilterConfiguration.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerServletWebConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerServletWebConfiguration.java index d653a248d55..123bb1db6ae 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerServletWebConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerServletWebConfiguration.java @@ -77,7 +77,7 @@ class FreeMarkerServletWebConfiguration extends AbstractFreeMarkerConfiguration @Bean @ConditionalOnEnabledResourceChain - @ConditionalOnMissingFilterBean(ResourceUrlEncodingFilter.class) + @ConditionalOnMissingFilterBean FilterRegistrationBean resourceUrlEncodingFilter() { FilterRegistrationBean registration = new FilterRegistrationBean<>( new ResourceUrlEncodingFilter()); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfiguration.java index 0a29829090d..a3d86633e08 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfiguration.java @@ -98,7 +98,7 @@ public class JerseyAutoConfiguration implements ServletContextAware { } @Bean - @ConditionalOnMissingFilterBean(RequestContextFilter.class) + @ConditionalOnMissingFilterBean public FilterRegistrationBean requestContextFilter() { FilterRegistrationBean registration = new FilterRegistrationBean<>(); registration.setFilter(new RequestContextFilter()); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfiguration.java index c9714fbf413..25c20208ca5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfiguration.java @@ -134,7 +134,7 @@ public class ThymeleafAutoConfiguration { @Bean @ConditionalOnEnabledResourceChain - @ConditionalOnMissingFilterBean(ResourceUrlEncodingFilter.class) + @ConditionalOnMissingFilterBean FilterRegistrationBean resourceUrlEncodingFilter() { FilterRegistrationBean registration = new FilterRegistrationBean<>( new ResourceUrlEncodingFilter()); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.java index 11d4b7ccb88..89291825ed8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.java @@ -371,7 +371,7 @@ public class WebMvcAutoConfiguration { @Bean @ConditionalOnMissingBean({ RequestContextListener.class, RequestContextFilter.class }) - @ConditionalOnMissingFilterBean(RequestContextFilter.class) + @ConditionalOnMissingFilterBean public static RequestContextFilter requestContextFilter() { return new OrderedRequestContextFilter(); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ConditionalOnMissingFilterBeanTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ConditionalOnMissingFilterBeanTests.java index 3c3e1c3a6b2..9be535ab820 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ConditionalOnMissingFilterBeanTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ConditionalOnMissingFilterBeanTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2025 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. @@ -46,7 +46,6 @@ class ConditionalOnMissingFilterBeanTests { @Test void outcomeWhenValueIsOfMissingBeanReturnsMatch() { - this.contextRunner.withUserConfiguration(WithoutTestFilterConfig.class, OnMissingWithValueConfig.class) .run((context) -> assertThat(context).satisfies(filterBeanRequirement("myOtherFilter", "testFilter"))); } diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/ROOT/pages/redirect.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/ROOT/pages/redirect.adoc index e13279f64fe..55c60bdaf9d 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/ROOT/pages/redirect.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/ROOT/pages/redirect.adoc @@ -1190,8 +1190,6 @@ * xref:reference:actuator/metrics.adoc#actuator.metrics.supported.system[#actuator.metrics.supported.system] * xref:reference:actuator/metrics.adoc#actuator.metrics.supported.system[#production-ready-metrics-system] * xref:reference:actuator/metrics.adoc#actuator.metrics.supported.tasks[#actuator.metrics.supported.tasks] -* xref:reference:actuator/observability.adoc#actuator.observability.annotations[#actuator.metrics.supported.timed-annotation] -* xref:reference:actuator/observability.adoc#actuator.observability.annotations[#production-ready-metrics-timed-annotation] * xref:reference:actuator/metrics.adoc#actuator.metrics.supported.tomcat[#actuator.metrics.supported.tomcat] * xref:reference:actuator/metrics.adoc#actuator.metrics.supported.tomcat[#production-ready-metrics-tomcat] * xref:reference:actuator/metrics.adoc#actuator.metrics.supported[#actuator.metrics.supported] @@ -1210,7 +1208,9 @@ * xref:reference:actuator/monitoring.adoc#actuator.monitoring.management-specific-ssl[#production-ready-management-specific-ssl] * xref:reference:actuator/monitoring.adoc#actuator.monitoring[#actuator.monitoring] * xref:reference:actuator/monitoring.adoc#actuator.monitoring[#production-ready-monitoring] +* xref:reference:actuator/observability.adoc#actuator.observability.annotations[#actuator.metrics.supported.timed-annotation] * xref:reference:actuator/observability.adoc#actuator.observability.annotations[#actuator.observability.annotations] +* xref:reference:actuator/observability.adoc#actuator.observability.annotations[#production-ready-metrics-timed-annotation] * xref:reference:actuator/observability.adoc#actuator.observability.common-tags[#actuator.observability.common-tags] * xref:reference:actuator/observability.adoc#actuator.observability.opentelemetry[#actuator.observability.opentelemetry] * xref:reference:actuator/observability.adoc#actuator.observability.preventing-observations[#actuator.observability.preventing-observations] diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/metrics.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/metrics.adoc index c1b6c412f8b..7a43a7bf3ae 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/metrics.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/metrics.adoc @@ -775,8 +775,8 @@ See the {url-spring-framework-docs}/integration/observability.html#observability To add to the default tags, provide a javadoc:org.springframework.context.annotation.Bean[format=annotation] that extends javadoc:org.springframework.http.server.observation.DefaultServerRequestObservationConvention[] from the `org.springframework.http.server.observation` package. To replace the default tags, provide a javadoc:org.springframework.context.annotation.Bean[format=annotation] that implements javadoc:org.springframework.http.server.observation.ServerRequestObservationConvention[]. -If the application is using xref:actuator/tracing.adoc#actuator.micrometer-tracing[Tracing], you can configure the HTTP server observations to print an `X-Trace-Id` -HTTP response header containing the current trace Id. For that, you will need to enable the following configuration property: configprop:management.observations.http.server.requests.write-trace-header[]. +If the application is using xref:actuator/tracing.adoc#actuator.micrometer-tracing[tracing], you can configure the HTTP server observations to include an `X-Trace-Id` +HTTP response header containing the current trace ID. For that, you will need to enable the following configuration property: configprop:management.observations.http.server.requests.write-trace-header[]. TIP: In some cases, exceptions handled in web controllers are not recorded as request metrics tags. Applications can opt in and record exceptions by xref:web/servlet.adoc#web.servlet.spring-mvc.error-handling[setting handled exceptions as request attributes]. diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/observability.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/observability.adoc index ec359162185..349ae05782e 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/observability.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/observability.adoc @@ -108,9 +108,9 @@ The next sections will provide more details about logging, metrics and traces. [[actuator.observability.annotations]] == Micrometer Observation Annotations support -To enable scanning of observability annotations like javadoc:io.micrometer.observation.annotation.Observed[format=annotation], javadoc:io.micrometer.core.annotation.Timed[format=annotation], javadoc:io.micrometer.core.annotation.Counted[format=annotation], javadoc:io.micrometer.core.aop.MeterTag[format=annotation] and javadoc:io.micrometer.tracing.annotation.NewSpan[format=annotation] annotations, you need to set the configprop:management.observations.annotations.enabled[] property to `true`. +To enable scanning of observability annotations like javadoc:io.micrometer.observation.annotation.Observed[format=annotation], javadoc:io.micrometer.core.annotation.Timed[format=annotation], javadoc:io.micrometer.core.annotation.Counted[format=annotation], javadoc:io.micrometer.core.aop.MeterTag[format=annotation] and javadoc:io.micrometer.tracing.annotation.NewSpan[format=annotation], you need to set the configprop:management.observations.annotations.enabled[] property to `true`. This feature is supported by Micrometer directly. Please refer to the {url-micrometer-docs-concepts}/timers.html#_the_timed_annotation[Micrometer], {url-micrometer-docs-observation}/components.html#micrometer-observation-annotations[Micrometer Observation] and {url-micrometer-tracing-docs}/api.html#_aspect_oriented_programming[Micrometer Tracing] reference docs. -NOTE: When you annotate methods or classes which are already instrumented (for example xref:reference:actuator/metrics.adoc#actuator.metrics.supported.spring-data-repository[Spring Data repositories] or xref:reference:actuator/metrics.adoc#actuator.metrics.supported.spring-mvc[Spring MVC controllers]), you will get duplicate observations. -In that case you can either disable the automatic instrumentation using xref:reference:actuator/observability.adoc#actuator.observability.preventing-observations[properties] or an javadoc:io.micrometer.observation.ObservationPredicate[] and rely on your annotations, or you can remove your annotation. +NOTE: When you annotate methods or classes which are already instrumented (for example, xref:reference:actuator/metrics.adoc#actuator.metrics.supported.spring-data-repository[Spring Data repositories] or xref:reference:actuator/metrics.adoc#actuator.metrics.supported.spring-mvc[Spring MVC controllers]), you will get duplicate observations. +In that case you can either disable the automatic instrumentation using xref:reference:actuator/observability.adoc#actuator.observability.preventing-observations[properties] or an javadoc:io.micrometer.observation.ObservationPredicate[] and rely on your annotations, or you can remove your annotations.