From 39a18948bd5ece81bb2e6b18b2b321ad56689589 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Tue, 18 Mar 2025 10:30:32 +0100 Subject: [PATCH] Remove TraceId HTTP response header support Closes gh-44752 --- .../build.gradle | 1 - .../observation/ObservationProperties.java | 15 +--- .../ObservationFilterConfigurations.java | 89 ------------------- .../servlet/TraceHeaderObservationFilter.java | 77 ---------------- .../WebMvcObservationAutoConfiguration.java | 28 +++++- .../TraceHeaderObservationFilterTests.java | 65 -------------- ...bMvcObservationAutoConfigurationTests.java | 70 +-------------- .../reference/pages/actuator/metrics.adoc | 3 - 8 files changed, 26 insertions(+), 322 deletions(-) delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/ObservationFilterConfigurations.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/TraceHeaderObservationFilter.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/TraceHeaderObservationFilterTests.java diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle b/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle index 7f50e88071..9366699365 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle @@ -136,7 +136,6 @@ dependencies { testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) testImplementation(testFixtures(project(":spring-boot-project:spring-boot"))) testImplementation("io.micrometer:micrometer-observation-test") - testImplementation("io.micrometer:micrometer-tracing-test") testImplementation("io.projectreactor:reactor-test") testImplementation("io.prometheus:prometheus-metrics-exposition-formats") testImplementation("io.r2dbc:r2dbc-h2") 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 e004eb04cc..93d0e71524 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2025 the original author or authors. + * Copyright 2012-2024 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. @@ -127,11 +127,6 @@ public class ObservationProperties { */ private String name = "http.server.requests"; - /** - * Whether to write the "X-Trace-Id" HTTP response header. - */ - private boolean writeTraceHeader = false; - public String getName() { return this.name; } @@ -140,14 +135,6 @@ public class ObservationProperties { this.name = name; } - public boolean isWriteTraceHeader() { - return this.writeTraceHeader; - } - - public void setWriteTraceHeader(boolean writeTraceHeader) { - this.writeTraceHeader = writeTraceHeader; - } - } } 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 deleted file mode 100644 index e9f5a980be..0000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/ObservationFilterConfigurations.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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. - * 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.servlet; - -import io.micrometer.observation.ObservationRegistry; -import io.micrometer.tracing.Tracer; -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.web.servlet.ConditionalOnMissingFilterBean; -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.Ordered; -import org.springframework.http.server.observation.DefaultServerRequestObservationConvention; -import org.springframework.http.server.observation.ServerRequestObservationConvention; -import org.springframework.web.filter.ServerHttpObservationFilter; - -/** - * Observation filter configurations imported by - * {@link WebMvcObservationAutoConfiguration}. - * - * @author Brian Clozel - */ -abstract class ObservationFilterConfigurations { - - static FilterRegistrationBean filterRegistration(T filter) { - FilterRegistrationBean registration = new FilterRegistrationBean<>(filter); - registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 1); - registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC); - return registration; - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(Tracer.class) - static class TracingHeaderObservation { - - @Bean - @ConditionalOnBooleanProperty("management.observations.http.server.requests.write-trace-header") - @ConditionalOnBean(Tracer.class) - @ConditionalOnMissingFilterBean({ ServerHttpObservationFilter.class, TraceHeaderObservationFilter.class }) - FilterRegistrationBean webMvcObservationFilter(ObservationRegistry registry, - Tracer tracer, ObjectProvider customConvention, - ObservationProperties observationProperties) { - String name = observationProperties.getHttp().getServer().getRequests().getName(); - ServerRequestObservationConvention convention = customConvention - .getIfAvailable(() -> new DefaultServerRequestObservationConvention(name)); - TraceHeaderObservationFilter filter = new TraceHeaderObservationFilter(tracer, registry, convention); - return filterRegistration(filter); - } - - } - - @Configuration(proxyBeanMethods = false) - static class DefaultObservation { - - @Bean - @ConditionalOnMissingFilterBean({ ServerHttpObservationFilter.class, TraceHeaderObservationFilter.class }) - FilterRegistrationBean webMvcObservationFilter(ObservationRegistry registry, - ObjectProvider customConvention, - ObservationProperties observationProperties) { - String name = observationProperties.getHttp().getServer().getRequests().getName(); - ServerRequestObservationConvention convention = customConvention - .getIfAvailable(() -> new DefaultServerRequestObservationConvention(name)); - ServerHttpObservationFilter filter = new ServerHttpObservationFilter(registry, convention); - return filterRegistration(filter); - } - - } - -} 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 deleted file mode 100644 index 47ea0783e9..0000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/TraceHeaderObservationFilter.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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. - * 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.servlet; - -import io.micrometer.observation.Observation.Scope; -import io.micrometer.observation.ObservationRegistry; -import io.micrometer.tracing.Span; -import io.micrometer.tracing.Tracer; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - -import org.springframework.http.server.observation.ServerRequestObservationConvention; -import org.springframework.util.Assert; -import org.springframework.web.filter.ServerHttpObservationFilter; - -/** - * {@link ServerHttpObservationFilter} that writes the current {@link Span} in an HTTP - * response header. By default, the {@code "X-Trace-Id"} header is used. - * - * @author Brian Clozel - * @since 3.5.0 - */ -public class TraceHeaderObservationFilter extends ServerHttpObservationFilter { - - private static final String TRACE_ID_HEADER_NAME = "X-Trace-Id"; - - private final Tracer tracer; - - /** - * Create a {@link TraceHeaderObservationFilter} that will write the - * {@code "X-Trace-Id"} HTTP response header. - * @param tracer the current tracer - * @param observationRegistry the current observation registry - */ - public TraceHeaderObservationFilter(Tracer tracer, ObservationRegistry observationRegistry) { - super(observationRegistry); - Assert.notNull(tracer, "'tracer' must not be null"); - this.tracer = tracer; - } - - /** - * Create a {@link TraceHeaderObservationFilter} that will write the - * {@code "X-Trace-Id"} HTTP response header. - * @param tracer the current tracer - * @param observationRegistry the current observation registry - * @param observationConvention the custom observation convention to use. - */ - public TraceHeaderObservationFilter(Tracer tracer, ObservationRegistry observationRegistry, - ServerRequestObservationConvention observationConvention) { - super(observationRegistry, observationConvention); - Assert.notNull(tracer, "'tracer' must not be null"); - this.tracer = tracer; - } - - @Override - protected void onScopeOpened(Scope scope, HttpServletRequest request, HttpServletResponse response) { - Span currentSpan = this.tracer.currentSpan(); - if (currentSpan != null && !currentSpan.isNoop()) { - response.setHeader(TRACE_ID_HEADER_NAME, currentSpan.context().traceId()); - } - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfiguration.java index 844dcb6ac3..2b4aa96c39 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2025 the original author or authors. + * 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. @@ -20,7 +20,9 @@ import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.config.MeterFilter; import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationRegistry; +import jakarta.servlet.DispatcherType; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties; @@ -33,11 +35,16 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.web.servlet.ConditionalOnMissingFilterBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; +import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; +import org.springframework.http.server.observation.DefaultServerRequestObservationConvention; +import org.springframework.http.server.observation.ServerRequestObservationConvention; +import org.springframework.web.filter.ServerHttpObservationFilter; import org.springframework.web.servlet.DispatcherServlet; /** @@ -55,10 +62,23 @@ import org.springframework.web.servlet.DispatcherServlet; @ConditionalOnClass({ DispatcherServlet.class, Observation.class }) @ConditionalOnBean(ObservationRegistry.class) @EnableConfigurationProperties({ MetricsProperties.class, ObservationProperties.class }) -@Import({ ObservationFilterConfigurations.TracingHeaderObservation.class, - ObservationFilterConfigurations.DefaultObservation.class }) public class WebMvcObservationAutoConfiguration { + @Bean + @ConditionalOnMissingFilterBean + public FilterRegistrationBean webMvcObservationFilter(ObservationRegistry registry, + ObjectProvider customConvention, + ObservationProperties observationProperties) { + String name = observationProperties.getHttp().getServer().getRequests().getName(); + ServerRequestObservationConvention convention = customConvention + .getIfAvailable(() -> new DefaultServerRequestObservationConvention(name)); + ServerHttpObservationFilter filter = new ServerHttpObservationFilter(registry, convention); + FilterRegistrationBean registration = new FilterRegistrationBean<>(filter); + registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 1); + registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC); + return registration; + } + @Configuration(proxyBeanMethods = false) @ConditionalOnClass(MeterRegistry.class) @ConditionalOnBean(MeterRegistry.class) 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 deleted file mode 100644 index 75d7a7a13f..0000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/TraceHeaderObservationFilterTests.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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. - * 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.servlet; - -import io.micrometer.observation.tck.TestObservationRegistry; -import io.micrometer.tracing.Tracer; -import io.micrometer.tracing.handler.DefaultTracingObservationHandler; -import io.micrometer.tracing.test.simple.SimpleTracer; -import jakarta.servlet.FilterChain; -import org.junit.jupiter.api.Test; - -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link TraceHeaderObservationFilter}. - * - * @author Brian Clozel - */ -class TraceHeaderObservationFilterTests { - - TestObservationRegistry observationRegistry = TestObservationRegistry.create(); - - @Test - void shouldWriteTraceHeaderWhenCurrentTrace() throws Exception { - TraceHeaderObservationFilter filter = createFilter(new SimpleTracer()); - MockHttpServletResponse response = new MockHttpServletResponse(); - filter.doFilter(new MockHttpServletRequest(), response, getFilterChain()); - assertThat(response.getHeader("X-Trace-Id")).isNotEmpty(); - } - - @Test - void shouldNotWriteTraceHeaderWhenNoCurrentTrace() throws Exception { - TraceHeaderObservationFilter filter = createFilter(Tracer.NOOP); - MockHttpServletResponse response = new MockHttpServletResponse(); - filter.doFilter(new MockHttpServletRequest(), response, getFilterChain()); - assertThat(response.getHeaderNames()).doesNotContain("X-Trace-Id"); - } - - private TraceHeaderObservationFilter createFilter(Tracer tracer) { - this.observationRegistry.observationConfig().observationHandler(new DefaultTracingObservationHandler(tracer)); - return new TraceHeaderObservationFilter(tracer, this.observationRegistry); - } - - private static FilterChain getFilterChain() { - return (servletRequest, servletResponse) -> servletResponse.getWriter().print("Hello"); - } - -} 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 d044fdec7f..93ef6d9046 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 @@ -20,7 +20,6 @@ import java.util.EnumSet; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.observation.tck.TestObservationRegistry; -import io.micrometer.tracing.Tracer; import jakarta.servlet.DispatcherType; import jakarta.servlet.Filter; import org.junit.jupiter.api.Test; @@ -30,7 +29,6 @@ import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfigu import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; import org.springframework.boot.actuate.autoconfigure.metrics.web.TestController; import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.NoopTracerAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; @@ -77,8 +75,7 @@ class WebMvcObservationAutoConfigurationTests { this.contextRunner.run((context) -> { assertThat(context).hasSingleBean(FilterRegistrationBean.class); assertThat(context.getBean(FilterRegistrationBean.class).getFilter()) - .isInstanceOf(ServerHttpObservationFilter.class) - .isNotInstanceOf(TraceHeaderObservationFilter.class); + .isInstanceOf(ServerHttpObservationFilter.class); }); } @@ -129,50 +126,6 @@ class WebMvcObservationAutoConfigurationTests { .run((context) -> assertThat(context).hasBean("testFilter").hasBean("webMvcObservationFilter")); } - @Test - void usesTracingFilterWhenTracingIsPresentAndEnabled() { - this.contextRunner.withConfiguration(AutoConfigurations.of(NoopTracerAutoConfiguration.class)) - .withPropertyValues("management.observations.http.server.requests.write-trace-header=true") - .run((context) -> { - assertThat(context).hasSingleBean(FilterRegistrationBean.class); - assertThat(context.getBean(FilterRegistrationBean.class).getFilter()) - .isInstanceOf(TraceHeaderObservationFilter.class); - }); - } - - @Test - void tracingFilterRegistrationHasExpectedDispatcherTypesAndOrder() { - this.contextRunner.withConfiguration(AutoConfigurations.of(NoopTracerAutoConfiguration.class)) - .withPropertyValues("management.observations.http.server.requests.write-trace-header=true") - .run((context) -> { - FilterRegistrationBean registration = context.getBean(FilterRegistrationBean.class); - assertThat(registration).hasFieldOrPropertyWithValue("dispatcherTypes", - EnumSet.of(DispatcherType.REQUEST, DispatcherType.ASYNC)); - assertThat(registration.getOrder()).isEqualTo(Ordered.HIGHEST_PRECEDENCE + 1); - }); - } - - @Test - void filterRegistrationBacksOffWithAnotherTraceHeaderObservationFilterRegistration() { - this.contextRunner.withConfiguration(AutoConfigurations.of(NoopTracerAutoConfiguration.class)) - .withPropertyValues("management.observations.http.server.requests.write-trace-header=true") - .withUserConfiguration(TestTraceHeaderObservationFilterRegistrationConfiguration.class) - .run((context) -> { - assertThat(context).hasSingleBean(FilterRegistrationBean.class); - assertThat(context.getBean(FilterRegistrationBean.class)) - .isSameAs(context.getBean("testTraceHeaderObservationFilter")); - }); - } - - @Test - void filterRegistrationBacksOffWithAnotherTraceHeaderObservationFilter() { - this.contextRunner.withConfiguration(AutoConfigurations.of(NoopTracerAutoConfiguration.class)) - .withPropertyValues("management.observations.http.server.requests.write-trace-header=true") - .withUserConfiguration(TestTraceHeaderObservationFilterConfiguration.class) - .run((context) -> assertThat(context).doesNotHaveBean(FilterRegistrationBean.class) - .hasSingleBean(TraceHeaderObservationFilter.class)); - } - @Test void afterMaxUrisReachedFurtherUrisAreDenied(CapturedOutput output) { this.contextRunner.withUserConfiguration(TestController.class) @@ -249,27 +202,6 @@ class WebMvcObservationAutoConfigurationTests { } - @Configuration(proxyBeanMethods = false) - static class TestTraceHeaderObservationFilterRegistrationConfiguration { - - @Bean - @SuppressWarnings("unchecked") - FilterRegistrationBean testTraceHeaderObservationFilter() { - return mock(FilterRegistrationBean.class); - } - - } - - @Configuration(proxyBeanMethods = false) - static class TestTraceHeaderObservationFilterConfiguration { - - @Bean - TraceHeaderObservationFilter testTraceHeaderObservationFilter() { - return new TraceHeaderObservationFilter(Tracer.NOOP, TestObservationRegistry.create()); - } - - } - @Configuration(proxyBeanMethods = false) static class TestFilterRegistrationConfiguration { 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 7a43a7bf3a..fb32b1ad1f 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,9 +775,6 @@ 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 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].