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
This commit is contained in:
		
							parent
							
								
									fc9cd86718
								
							
						
					
					
						commit
						de128fed20
					
				|  | @ -18,10 +18,10 @@ package org.springframework.boot.actuate.autoconfigure.trace.http; | |||
| 
 | ||||
| import org.springframework.boot.actuate.trace.http.HttpExchangeTracer; | ||||
| import org.springframework.boot.actuate.trace.http.HttpTraceRepository; | ||||
| import org.springframework.boot.actuate.trace.http.InMemoryHttpTraceRepository; | ||||
| import org.springframework.boot.actuate.web.trace.reactive.HttpTraceWebFilter; | ||||
| import org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter; | ||||
| import org.springframework.boot.autoconfigure.EnableAutoConfiguration; | ||||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; | ||||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | ||||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; | ||||
|  | @ -40,15 +40,10 @@ import org.springframework.context.annotation.Configuration; | |||
| @ConditionalOnWebApplication | ||||
| @ConditionalOnProperty(prefix = "management.trace.http", name = "enabled", | ||||
| 		matchIfMissing = true) | ||||
| @ConditionalOnBean(HttpTraceRepository.class) | ||||
| @EnableConfigurationProperties(HttpTraceProperties.class) | ||||
| public class HttpTraceAutoConfiguration { | ||||
| 
 | ||||
| 	@Bean | ||||
| 	@ConditionalOnMissingBean(HttpTraceRepository.class) | ||||
| 	public InMemoryHttpTraceRepository traceRepository() { | ||||
| 		return new InMemoryHttpTraceRepository(); | ||||
| 	} | ||||
| 
 | ||||
| 	@Bean | ||||
| 	@ConditionalOnMissingBean | ||||
| 	public HttpExchangeTracer httpExchangeTracer(HttpTraceProperties traceProperties) { | ||||
|  |  | |||
|  | @ -42,45 +42,34 @@ import static org.assertj.core.api.Assertions.assertThat; | |||
|  * Tests for {@link HttpTraceAutoConfiguration}. | ||||
|  * | ||||
|  * @author Andy Wilkinson | ||||
|  * @author Madhura Bhave | ||||
|  */ | ||||
| public class HttpTraceAutoConfigurationTests { | ||||
| 
 | ||||
| 	private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() | ||||
| 			.withConfiguration(AutoConfigurations.of(HttpTraceAutoConfiguration.class)); | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void configuresRepository() { | ||||
| 		new WebApplicationContextRunner() | ||||
| 				.withConfiguration( | ||||
| 						AutoConfigurations.of(HttpTraceAutoConfiguration.class)) | ||||
| 				.run((context) -> assertThat(context) | ||||
| 						.hasSingleBean(InMemoryHttpTraceRepository.class)); | ||||
| 	public void autoConfigurationIsDisabledByDefault() { | ||||
| 		this.contextRunner.run((context) -> assertThat(context) | ||||
| 				.doesNotHaveBean(HttpTraceAutoConfiguration.class)); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void usesUserProvidedRepository() { | ||||
| 		new WebApplicationContextRunner() | ||||
| 				.withConfiguration( | ||||
| 						AutoConfigurations.of(HttpTraceAutoConfiguration.class)) | ||||
| 				.withUserConfiguration(CustomRepositoryConfiguration.class) | ||||
| 	public void autoConfigurationIsEnabledWhenHttpTraceRepositoryBeanPresent() { | ||||
| 		this.contextRunner.withUserConfiguration(HttpTraceRepositoryConfiguration.class) | ||||
| 				.run((context) -> { | ||||
| 					assertThat(context).hasSingleBean(HttpExchangeTracer.class); | ||||
| 					assertThat(context).hasSingleBean(HttpTraceFilter.class); | ||||
| 					assertThat(context).hasSingleBean(HttpTraceRepository.class); | ||||
| 					assertThat(context.getBean(HttpTraceRepository.class)) | ||||
| 							.isInstanceOf(CustomHttpTraceRepository.class); | ||||
| 				}); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void configuresTracer() { | ||||
| 		new WebApplicationContextRunner() | ||||
| 				.withConfiguration( | ||||
| 						AutoConfigurations.of(HttpTraceAutoConfiguration.class)) | ||||
| 				.run((context) -> assertThat(context) | ||||
| 						.hasSingleBean(HttpExchangeTracer.class)); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void usesUserProvidedTracer() { | ||||
| 		new WebApplicationContextRunner() | ||||
| 				.withConfiguration( | ||||
| 						AutoConfigurations.of(HttpTraceAutoConfiguration.class)) | ||||
| 		this.contextRunner.withUserConfiguration(HttpTraceRepositoryConfiguration.class) | ||||
| 				.withUserConfiguration(CustomTracerConfiguration.class).run((context) -> { | ||||
| 					assertThat(context).hasSingleBean(HttpExchangeTracer.class); | ||||
| 					assertThat(context.getBean(HttpExchangeTracer.class)) | ||||
|  | @ -89,19 +78,11 @@ public class HttpTraceAutoConfigurationTests { | |||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void configuresWebFilter() { | ||||
| 		new ReactiveWebApplicationContextRunner() | ||||
| 				.withConfiguration( | ||||
| 						AutoConfigurations.of(HttpTraceAutoConfiguration.class)) | ||||
| 				.run((context) -> assertThat(context) | ||||
| 						.hasSingleBean(HttpTraceWebFilter.class)); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void usesUserProvidedWebFilter() { | ||||
| 	public void usesUserProvidedWebFilterWhenReactiveContext() { | ||||
| 		new ReactiveWebApplicationContextRunner() | ||||
| 				.withConfiguration( | ||||
| 						AutoConfigurations.of(HttpTraceAutoConfiguration.class)) | ||||
| 				.withUserConfiguration(HttpTraceRepositoryConfiguration.class) | ||||
| 				.withUserConfiguration(CustomWebFilterConfiguration.class) | ||||
| 				.run((context) -> { | ||||
| 					assertThat(context).hasSingleBean(HttpTraceWebFilter.class); | ||||
|  | @ -110,20 +91,9 @@ public class HttpTraceAutoConfigurationTests { | |||
| 				}); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void configuresServletFilter() { | ||||
| 		new WebApplicationContextRunner() | ||||
| 				.withConfiguration( | ||||
| 						AutoConfigurations.of(HttpTraceAutoConfiguration.class)) | ||||
| 				.run((context) -> assertThat(context) | ||||
| 						.hasSingleBean(HttpTraceFilter.class)); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void usesUserProvidedServletFilter() { | ||||
| 		new WebApplicationContextRunner() | ||||
| 				.withConfiguration( | ||||
| 						AutoConfigurations.of(HttpTraceAutoConfiguration.class)) | ||||
| 		this.contextRunner.withUserConfiguration(HttpTraceRepositoryConfiguration.class) | ||||
| 				.withUserConfiguration(CustomFilterConfiguration.class).run((context) -> { | ||||
| 					assertThat(context).hasSingleBean(HttpTraceFilter.class); | ||||
| 					assertThat(context.getBean(HttpTraceFilter.class)) | ||||
|  | @ -133,9 +103,7 @@ public class HttpTraceAutoConfigurationTests { | |||
| 
 | ||||
| 	@Test | ||||
| 	public void backsOffWhenDisabled() { | ||||
| 		new WebApplicationContextRunner() | ||||
| 				.withConfiguration( | ||||
| 						AutoConfigurations.of(HttpTraceAutoConfiguration.class)) | ||||
| 		this.contextRunner.withUserConfiguration(HttpTraceRepositoryConfiguration.class) | ||||
| 				.withPropertyValues("management.trace.http.enabled=false") | ||||
| 				.run((context) -> assertThat(context) | ||||
| 						.doesNotHaveBean(InMemoryHttpTraceRepository.class) | ||||
|  | @ -158,7 +126,7 @@ public class HttpTraceAutoConfigurationTests { | |||
| 	} | ||||
| 
 | ||||
| 	@Configuration(proxyBeanMethods = false) | ||||
| 	static class CustomRepositoryConfiguration { | ||||
| 	static class HttpTraceRepositoryConfiguration { | ||||
| 
 | ||||
| 		@Bean | ||||
| 		public CustomHttpTraceRepository customRepository() { | ||||
|  |  | |||
|  | @ -21,8 +21,11 @@ import org.junit.Test; | |||
| import org.springframework.boot.actuate.autoconfigure.trace.http.HttpTraceAutoConfiguration; | ||||
| import org.springframework.boot.actuate.autoconfigure.trace.http.HttpTraceEndpointAutoConfiguration; | ||||
| import org.springframework.boot.actuate.trace.http.HttpTraceEndpoint; | ||||
| import org.springframework.boot.actuate.trace.http.InMemoryHttpTraceRepository; | ||||
| import org.springframework.boot.autoconfigure.AutoConfigurations; | ||||
| import org.springframework.boot.test.context.runner.WebApplicationContextRunner; | ||||
| import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
| 
 | ||||
| import static org.assertj.core.api.Assertions.assertThat; | ||||
| 
 | ||||
|  | @ -30,6 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat; | |||
|  * Tests for {@link HttpTraceEndpointAutoConfiguration}. | ||||
|  * | ||||
|  * @author Phillip Webb | ||||
|  * @author Madhura Bhave | ||||
|  */ | ||||
| public class HttpTraceEndpointAutoConfigurationTests { | ||||
| 
 | ||||
|  | @ -38,8 +42,8 @@ public class HttpTraceEndpointAutoConfigurationTests { | |||
| 					HttpTraceEndpointAutoConfiguration.class)); | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void runShouldHaveEndpointBean() { | ||||
| 		this.contextRunner | ||||
| 	public void runWhenRepositoryBeanAvailableShouldHaveEndpointBean() { | ||||
| 		this.contextRunner.withUserConfiguration(HttpTraceRepositoryConfiguration.class) | ||||
| 				.withPropertyValues("management.endpoints.web.exposure.include=httptrace") | ||||
| 				.run((context) -> assertThat(context) | ||||
| 						.hasSingleBean(HttpTraceEndpoint.class)); | ||||
|  | @ -47,13 +51,15 @@ public class HttpTraceEndpointAutoConfigurationTests { | |||
| 
 | ||||
| 	@Test | ||||
| 	public void runWhenNotExposedShouldNotHaveEndpointBean() { | ||||
| 		this.contextRunner.run((context) -> assertThat(context) | ||||
| 		this.contextRunner.withUserConfiguration(HttpTraceRepositoryConfiguration.class) | ||||
| 				.run((context) -> assertThat(context) | ||||
| 						.doesNotHaveBean(HttpTraceEndpoint.class)); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void runWhenEnabledPropertyIsFalseShouldNotHaveEndpointBean() { | ||||
| 		this.contextRunner | ||||
| 		this.contextRunner.withUserConfiguration(HttpTraceRepositoryConfiguration.class) | ||||
| 				.withPropertyValues("management.endpoints.web.exposure.include=httptrace") | ||||
| 				.withPropertyValues("management.endpoint.httptrace.enabled:false") | ||||
| 				.run((context) -> assertThat(context) | ||||
| 						.doesNotHaveBean(HttpTraceEndpoint.class)); | ||||
|  | @ -61,9 +67,20 @@ public class HttpTraceEndpointAutoConfigurationTests { | |||
| 
 | ||||
| 	@Test | ||||
| 	public void endpointBacksOffWhenRepositoryIsNotAvailable() { | ||||
| 		this.contextRunner.withPropertyValues("management.trace.http.enabled:false") | ||||
| 		this.contextRunner | ||||
| 				.withPropertyValues("management.endpoints.web.exposure.include=httptrace") | ||||
| 				.run((context) -> assertThat(context) | ||||
| 						.doesNotHaveBean(HttpTraceEndpoint.class)); | ||||
| 	} | ||||
| 
 | ||||
| 	@Configuration(proxyBeanMethods = false) | ||||
| 	static class HttpTraceRepositoryConfiguration { | ||||
| 
 | ||||
| 		@Bean | ||||
| 		public InMemoryHttpTraceRepository customRepository() { | ||||
| 			return new InMemoryHttpTraceRepository(); | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -2213,8 +2213,12 @@ implementing `ApplicationEventPublisherAware`). | |||
| 
 | ||||
| [[production-ready-http-tracing]] | ||||
| == HTTP Tracing | ||||
| Tracing is automatically enabled for all HTTP requests. You can view the `httptrace` | ||||
| endpoint and obtain basic information about the last 100 request-response exchanges. | ||||
| HTTP Tracing can be enabled by providing a bean of type `HttpTraceRepository` in your application's | ||||
| configuration. For convenience, Spring Boot offers an `InMemoryHttpTraceRepository` that stores traces | ||||
| for the last 100 request-response exchanges, by default. `InMemoryHttpTraceRepository` is limited | ||||
| compared to other tracing solutions and we recommend using it only for development environments. | ||||
| For production environments, consider creating your own alternative `HttpTraceRepository` implementation. | ||||
| You can view the `httptrace` endpoint and obtain information about the request-response exchanges. | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | @ -2224,11 +2228,6 @@ To customize the items that are included in each trace, use the | |||
| `management.trace.http.include` configuration property. For advanced customization, | ||||
| consider registering your own `HttpExchangeTracer` implementation. | ||||
| 
 | ||||
| By default, an `InMemoryHttpTraceRepository` that stores traces for the last 100 | ||||
| request-response exchanges is used. If you need to expand the capacity, you can define | ||||
| your own instance of the `InMemoryHttpTraceRepository` bean. You can also create your own | ||||
| alternative `HttpTraceRepository` implementation. | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| [[production-ready-process-monitoring]] | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue