Skip to content

Commit de128fe

Browse files
committed
Disable HttpTrace infrastructure by default
Prior to this commit, the http trace auto-configuration provided an `InMemoryHttpTraceRepository` bean. This commit changes the auto-config so that an `HttpTraceRepository` is not provided and instead the auto-config is conditional on the presence of a `HttpTraceRepository` bean. This is done to encourage the use of a custom implementation of `HttpTraceRepository` since the in-memory one is quite limited and not suitable for production. A flag is available if the auto-configuration needs to be turned off even in the presence of a bean. Closes gh-15039
1 parent fc9cd86 commit de128fe

File tree

4 files changed

+48
-69
lines changed

4 files changed

+48
-69
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/trace/http/HttpTraceAutoConfiguration.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@
1818

1919
import org.springframework.boot.actuate.trace.http.HttpExchangeTracer;
2020
import org.springframework.boot.actuate.trace.http.HttpTraceRepository;
21-
import org.springframework.boot.actuate.trace.http.InMemoryHttpTraceRepository;
2221
import org.springframework.boot.actuate.web.trace.reactive.HttpTraceWebFilter;
2322
import org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter;
2423
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
24+
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
2525
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
2626
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
2727
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
@@ -40,15 +40,10 @@
4040
@ConditionalOnWebApplication
4141
@ConditionalOnProperty(prefix = "management.trace.http", name = "enabled",
4242
matchIfMissing = true)
43+
@ConditionalOnBean(HttpTraceRepository.class)
4344
@EnableConfigurationProperties(HttpTraceProperties.class)
4445
public class HttpTraceAutoConfiguration {
4546

46-
@Bean
47-
@ConditionalOnMissingBean(HttpTraceRepository.class)
48-
public InMemoryHttpTraceRepository traceRepository() {
49-
return new InMemoryHttpTraceRepository();
50-
}
51-
5247
@Bean
5348
@ConditionalOnMissingBean
5449
public HttpExchangeTracer httpExchangeTracer(HttpTraceProperties traceProperties) {

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/trace/HttpTraceAutoConfigurationTests.java

Lines changed: 17 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -42,45 +42,34 @@
4242
* Tests for {@link HttpTraceAutoConfiguration}.
4343
*
4444
* @author Andy Wilkinson
45+
* @author Madhura Bhave
4546
*/
4647
public class HttpTraceAutoConfigurationTests {
4748

49+
private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
50+
.withConfiguration(AutoConfigurations.of(HttpTraceAutoConfiguration.class));
51+
4852
@Test
49-
public void configuresRepository() {
50-
new WebApplicationContextRunner()
51-
.withConfiguration(
52-
AutoConfigurations.of(HttpTraceAutoConfiguration.class))
53-
.run((context) -> assertThat(context)
54-
.hasSingleBean(InMemoryHttpTraceRepository.class));
53+
public void autoConfigurationIsDisabledByDefault() {
54+
this.contextRunner.run((context) -> assertThat(context)
55+
.doesNotHaveBean(HttpTraceAutoConfiguration.class));
5556
}
5657

5758
@Test
58-
public void usesUserProvidedRepository() {
59-
new WebApplicationContextRunner()
60-
.withConfiguration(
61-
AutoConfigurations.of(HttpTraceAutoConfiguration.class))
62-
.withUserConfiguration(CustomRepositoryConfiguration.class)
59+
public void autoConfigurationIsEnabledWhenHttpTraceRepositoryBeanPresent() {
60+
this.contextRunner.withUserConfiguration(HttpTraceRepositoryConfiguration.class)
6361
.run((context) -> {
62+
assertThat(context).hasSingleBean(HttpExchangeTracer.class);
63+
assertThat(context).hasSingleBean(HttpTraceFilter.class);
6464
assertThat(context).hasSingleBean(HttpTraceRepository.class);
6565
assertThat(context.getBean(HttpTraceRepository.class))
6666
.isInstanceOf(CustomHttpTraceRepository.class);
6767
});
6868
}
6969

70-
@Test
71-
public void configuresTracer() {
72-
new WebApplicationContextRunner()
73-
.withConfiguration(
74-
AutoConfigurations.of(HttpTraceAutoConfiguration.class))
75-
.run((context) -> assertThat(context)
76-
.hasSingleBean(HttpExchangeTracer.class));
77-
}
78-
7970
@Test
8071
public void usesUserProvidedTracer() {
81-
new WebApplicationContextRunner()
82-
.withConfiguration(
83-
AutoConfigurations.of(HttpTraceAutoConfiguration.class))
72+
this.contextRunner.withUserConfiguration(HttpTraceRepositoryConfiguration.class)
8473
.withUserConfiguration(CustomTracerConfiguration.class).run((context) -> {
8574
assertThat(context).hasSingleBean(HttpExchangeTracer.class);
8675
assertThat(context.getBean(HttpExchangeTracer.class))
@@ -89,19 +78,11 @@ public void usesUserProvidedTracer() {
8978
}
9079

9180
@Test
92-
public void configuresWebFilter() {
93-
new ReactiveWebApplicationContextRunner()
94-
.withConfiguration(
95-
AutoConfigurations.of(HttpTraceAutoConfiguration.class))
96-
.run((context) -> assertThat(context)
97-
.hasSingleBean(HttpTraceWebFilter.class));
98-
}
99-
100-
@Test
101-
public void usesUserProvidedWebFilter() {
81+
public void usesUserProvidedWebFilterWhenReactiveContext() {
10282
new ReactiveWebApplicationContextRunner()
10383
.withConfiguration(
10484
AutoConfigurations.of(HttpTraceAutoConfiguration.class))
85+
.withUserConfiguration(HttpTraceRepositoryConfiguration.class)
10586
.withUserConfiguration(CustomWebFilterConfiguration.class)
10687
.run((context) -> {
10788
assertThat(context).hasSingleBean(HttpTraceWebFilter.class);
@@ -110,20 +91,9 @@ public void usesUserProvidedWebFilter() {
11091
});
11192
}
11293

113-
@Test
114-
public void configuresServletFilter() {
115-
new WebApplicationContextRunner()
116-
.withConfiguration(
117-
AutoConfigurations.of(HttpTraceAutoConfiguration.class))
118-
.run((context) -> assertThat(context)
119-
.hasSingleBean(HttpTraceFilter.class));
120-
}
121-
12294
@Test
12395
public void usesUserProvidedServletFilter() {
124-
new WebApplicationContextRunner()
125-
.withConfiguration(
126-
AutoConfigurations.of(HttpTraceAutoConfiguration.class))
96+
this.contextRunner.withUserConfiguration(HttpTraceRepositoryConfiguration.class)
12797
.withUserConfiguration(CustomFilterConfiguration.class).run((context) -> {
12898
assertThat(context).hasSingleBean(HttpTraceFilter.class);
12999
assertThat(context.getBean(HttpTraceFilter.class))
@@ -133,9 +103,7 @@ public void usesUserProvidedServletFilter() {
133103

134104
@Test
135105
public void backsOffWhenDisabled() {
136-
new WebApplicationContextRunner()
137-
.withConfiguration(
138-
AutoConfigurations.of(HttpTraceAutoConfiguration.class))
106+
this.contextRunner.withUserConfiguration(HttpTraceRepositoryConfiguration.class)
139107
.withPropertyValues("management.trace.http.enabled=false")
140108
.run((context) -> assertThat(context)
141109
.doesNotHaveBean(InMemoryHttpTraceRepository.class)
@@ -158,7 +126,7 @@ public void add(HttpTrace trace) {
158126
}
159127

160128
@Configuration(proxyBeanMethods = false)
161-
static class CustomRepositoryConfiguration {
129+
static class HttpTraceRepositoryConfiguration {
162130

163131
@Bean
164132
public CustomHttpTraceRepository customRepository() {

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/trace/HttpTraceEndpointAutoConfigurationTests.java

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,19 @@
2121
import org.springframework.boot.actuate.autoconfigure.trace.http.HttpTraceAutoConfiguration;
2222
import org.springframework.boot.actuate.autoconfigure.trace.http.HttpTraceEndpointAutoConfiguration;
2323
import org.springframework.boot.actuate.trace.http.HttpTraceEndpoint;
24+
import org.springframework.boot.actuate.trace.http.InMemoryHttpTraceRepository;
2425
import org.springframework.boot.autoconfigure.AutoConfigurations;
2526
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
27+
import org.springframework.context.annotation.Bean;
28+
import org.springframework.context.annotation.Configuration;
2629

2730
import static org.assertj.core.api.Assertions.assertThat;
2831

2932
/**
3033
* Tests for {@link HttpTraceEndpointAutoConfiguration}.
3134
*
3235
* @author Phillip Webb
36+
* @author Madhura Bhave
3337
*/
3438
public class HttpTraceEndpointAutoConfigurationTests {
3539

@@ -38,32 +42,45 @@ public class HttpTraceEndpointAutoConfigurationTests {
3842
HttpTraceEndpointAutoConfiguration.class));
3943

4044
@Test
41-
public void runShouldHaveEndpointBean() {
42-
this.contextRunner
45+
public void runWhenRepositoryBeanAvailableShouldHaveEndpointBean() {
46+
this.contextRunner.withUserConfiguration(HttpTraceRepositoryConfiguration.class)
4347
.withPropertyValues("management.endpoints.web.exposure.include=httptrace")
4448
.run((context) -> assertThat(context)
4549
.hasSingleBean(HttpTraceEndpoint.class));
4650
}
4751

4852
@Test
4953
public void runWhenNotExposedShouldNotHaveEndpointBean() {
50-
this.contextRunner.run((context) -> assertThat(context)
51-
.doesNotHaveBean(HttpTraceEndpoint.class));
54+
this.contextRunner.withUserConfiguration(HttpTraceRepositoryConfiguration.class)
55+
.run((context) -> assertThat(context)
56+
.doesNotHaveBean(HttpTraceEndpoint.class));
5257
}
5358

5459
@Test
5560
public void runWhenEnabledPropertyIsFalseShouldNotHaveEndpointBean() {
56-
this.contextRunner
61+
this.contextRunner.withUserConfiguration(HttpTraceRepositoryConfiguration.class)
62+
.withPropertyValues("management.endpoints.web.exposure.include=httptrace")
5763
.withPropertyValues("management.endpoint.httptrace.enabled:false")
5864
.run((context) -> assertThat(context)
5965
.doesNotHaveBean(HttpTraceEndpoint.class));
6066
}
6167

6268
@Test
6369
public void endpointBacksOffWhenRepositoryIsNotAvailable() {
64-
this.contextRunner.withPropertyValues("management.trace.http.enabled:false")
70+
this.contextRunner
71+
.withPropertyValues("management.endpoints.web.exposure.include=httptrace")
6572
.run((context) -> assertThat(context)
6673
.doesNotHaveBean(HttpTraceEndpoint.class));
6774
}
6875

76+
@Configuration(proxyBeanMethods = false)
77+
static class HttpTraceRepositoryConfiguration {
78+
79+
@Bean
80+
public InMemoryHttpTraceRepository customRepository() {
81+
return new InMemoryHttpTraceRepository();
82+
}
83+
84+
}
85+
6986
}

spring-boot-project/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2213,8 +2213,12 @@ implementing `ApplicationEventPublisherAware`).
22132213

22142214
[[production-ready-http-tracing]]
22152215
== HTTP Tracing
2216-
Tracing is automatically enabled for all HTTP requests. You can view the `httptrace`
2217-
endpoint and obtain basic information about the last 100 request-response exchanges.
2216+
HTTP Tracing can be enabled by providing a bean of type `HttpTraceRepository` in your application's
2217+
configuration. For convenience, Spring Boot offers an `InMemoryHttpTraceRepository` that stores traces
2218+
for the last 100 request-response exchanges, by default. `InMemoryHttpTraceRepository` is limited
2219+
compared to other tracing solutions and we recommend using it only for development environments.
2220+
For production environments, consider creating your own alternative `HttpTraceRepository` implementation.
2221+
You can view the `httptrace` endpoint and obtain information about the request-response exchanges.
22182222

22192223

22202224

@@ -2224,11 +2228,6 @@ To customize the items that are included in each trace, use the
22242228
`management.trace.http.include` configuration property. For advanced customization,
22252229
consider registering your own `HttpExchangeTracer` implementation.
22262230

2227-
By default, an `InMemoryHttpTraceRepository` that stores traces for the last 100
2228-
request-response exchanges is used. If you need to expand the capacity, you can define
2229-
your own instance of the `InMemoryHttpTraceRepository` bean. You can also create your own
2230-
alternative `HttpTraceRepository` implementation.
2231-
22322231

22332232

22342233
[[production-ready-process-monitoring]]

0 commit comments

Comments
 (0)