Commit 356efaa7 authored by Andy Wilkinson's avatar Andy Wilkinson

Rename trace to httptrace

Closes gh-11806
parent 87c82310
[[trace]] [[http-trace]]
= Trace (`trace`) = HTTP Trace (`httptrace`)
The `trace` endpoint provides information about HTTP request-response exchanges. The `httptrace` endpoint provides information about HTTP request-response exchanges.
[[trace-retrieving]] [[http-trace-retrieving]]
== Retrieving the Traces == Retrieving the Traces
To retrieve the traces, make a `GET` request to `/actuator/trace`, as shown in the To retrieve the traces, make a `GET` request to `/actuator/httptrace`, as shown in the
following curl-based example: following curl-based example:
include::{snippets}trace/curl-request.adoc[] include::{snippets}httptrace/curl-request.adoc[]
The resulting response is similar to the following: The resulting response is similar to the following:
include::{snippets}trace/http-response.adoc[] include::{snippets}httptrace/http-response.adoc[]
[[trace-retrieving-response-structure]] [[http-trace-retrieving-response-structure]]
=== Response Structure === Response Structure
The response contains details of the traced HTTP request-response exchanges. The The response contains details of the traced HTTP request-response exchanges. The
following table describes the structure of the response: following table describes the structure of the response:
[cols="2,1,3"] [cols="2,1,3"]
include::{snippets}trace/response-fields.adoc[] include::{snippets}httptrace/response-fields.adoc[]
...@@ -57,6 +57,7 @@ include::endpoints/env.adoc[leveloffset=+1] ...@@ -57,6 +57,7 @@ include::endpoints/env.adoc[leveloffset=+1]
include::endpoints/flyway.adoc[leveloffset=+1] include::endpoints/flyway.adoc[leveloffset=+1]
include::endpoints/health.adoc[leveloffset=+1] include::endpoints/health.adoc[leveloffset=+1]
include::endpoints/heapdump.adoc[leveloffset=+1] include::endpoints/heapdump.adoc[leveloffset=+1]
include::endpoints/httptrace.adoc[leveloffset=+1]
include::endpoints/info.adoc[leveloffset=+1] include::endpoints/info.adoc[leveloffset=+1]
include::endpoints/liquibase.adoc[leveloffset=+1] include::endpoints/liquibase.adoc[leveloffset=+1]
include::endpoints/logfile.adoc[leveloffset=+1] include::endpoints/logfile.adoc[leveloffset=+1]
...@@ -68,4 +69,3 @@ include::endpoints/scheduledtasks.adoc[leveloffset=+1] ...@@ -68,4 +69,3 @@ include::endpoints/scheduledtasks.adoc[leveloffset=+1]
include::endpoints/sessions.adoc[leveloffset=+1] include::endpoints/sessions.adoc[leveloffset=+1]
include::endpoints/shutdown.adoc[leveloffset=+1] include::endpoints/shutdown.adoc[leveloffset=+1]
include::endpoints/threaddump.adoc[leveloffset=+1] include::endpoints/threaddump.adoc[leveloffset=+1]
include::endpoints/trace.adoc[leveloffset=+1]
...@@ -38,9 +38,9 @@ import org.springframework.context.annotation.Configuration; ...@@ -38,9 +38,9 @@ import org.springframework.context.annotation.Configuration;
*/ */
@Configuration @Configuration
@ConditionalOnWebApplication @ConditionalOnWebApplication
@ConditionalOnProperty(prefix = "management.trace", name = "enabled", matchIfMissing = true) @ConditionalOnProperty(prefix = "management.httptrace", name = "enabled", matchIfMissing = true)
@EnableConfigurationProperties(TraceProperties.class) @EnableConfigurationProperties(HttpTraceProperties.class)
public class TraceAutoConfiguration { public class HttpTraceAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean(HttpTraceRepository.class) @ConditionalOnMissingBean(HttpTraceRepository.class)
...@@ -50,7 +50,7 @@ public class TraceAutoConfiguration { ...@@ -50,7 +50,7 @@ public class TraceAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public HttpExchangeTracer httpExchangeTracer(TraceProperties traceProperties) { public HttpExchangeTracer httpExchangeTracer(HttpTraceProperties traceProperties) {
return new HttpExchangeTracer(traceProperties.getInclude()); return new HttpExchangeTracer(traceProperties.getInclude());
} }
...@@ -72,7 +72,7 @@ public class TraceAutoConfiguration { ...@@ -72,7 +72,7 @@ public class TraceAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public HttpTraceWebFilter httpTraceWebFilter(HttpTraceRepository repository, public HttpTraceWebFilter httpTraceWebFilter(HttpTraceRepository repository,
HttpExchangeTracer tracer, TraceProperties traceProperties) { HttpExchangeTracer tracer, HttpTraceProperties traceProperties) {
return new HttpTraceWebFilter(repository, tracer, return new HttpTraceWebFilter(repository, tracer,
traceProperties.getInclude()); traceProperties.getInclude());
} }
......
...@@ -33,14 +33,14 @@ import org.springframework.context.annotation.Configuration; ...@@ -33,14 +33,14 @@ import org.springframework.context.annotation.Configuration;
* @since 2.0.0 * @since 2.0.0
*/ */
@Configuration @Configuration
@AutoConfigureAfter(TraceAutoConfiguration.class) @AutoConfigureAfter(HttpTraceAutoConfiguration.class)
public class TraceEndpointAutoConfiguration { public class HttpTraceEndpointAutoConfiguration {
@Bean @Bean
@ConditionalOnBean(HttpTraceRepository.class) @ConditionalOnBean(HttpTraceRepository.class)
@ConditionalOnMissingBean @ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint @ConditionalOnEnabledEndpoint
public HttpTraceEndpoint traceEndpoint(HttpTraceRepository traceRepository) { public HttpTraceEndpoint httpTraceEndpoint(HttpTraceRepository traceRepository) {
return new HttpTraceEndpoint(traceRepository); return new HttpTraceEndpoint(traceRepository);
} }
......
...@@ -23,7 +23,7 @@ import org.springframework.boot.actuate.web.trace.Include; ...@@ -23,7 +23,7 @@ import org.springframework.boot.actuate.web.trace.Include;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
/** /**
* Configuration properties for tracing. * Configuration properties for HTTP tracing.
* *
* @author Wallace Wadge * @author Wallace Wadge
* @author Phillip Webb * @author Phillip Webb
...@@ -32,8 +32,8 @@ import org.springframework.boot.context.properties.ConfigurationProperties; ...@@ -32,8 +32,8 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
* @author Stephane Nicoll * @author Stephane Nicoll
* @since 2.0.0 * @since 2.0.0
*/ */
@ConfigurationProperties(prefix = "management.trace") @ConfigurationProperties(prefix = "management.httptrace")
public class TraceProperties { public class HttpTraceProperties {
/** /**
* Items to be included in the trace. Defaults to request headers (excluding * Items to be included in the trace. Defaults to request headers (excluding
......
...@@ -222,7 +222,7 @@ ...@@ -222,7 +222,7 @@
"defaultValue": true "defaultValue": true
}, },
{ {
"name": "management.trace.enabled", "name": "management.httptrace.enabled",
"type": "java.lang.Boolean", "type": "java.lang.Boolean",
"description": "Whether to enable HTTP request-response tracing.", "description": "Whether to enable HTTP request-response tracing.",
"defaultValue": true "defaultValue": true
...@@ -232,7 +232,7 @@ ...@@ -232,7 +232,7 @@
"type": "java.lang.Boolean", "type": "java.lang.Boolean",
"description": "Whether to enable the trace servlet filter.", "description": "Whether to enable the trace servlet filter.",
"deprecation": { "deprecation": {
"replacement": "management.trace.enabled", "replacement": "management.httptrace.enabled",
"level": "error" "level": "error"
} }
}, },
......
...@@ -43,8 +43,8 @@ org.springframework.boot.actuate.autoconfigure.web.mappings.MappingsEndpointAuto ...@@ -43,8 +43,8 @@ org.springframework.boot.actuate.autoconfigure.web.mappings.MappingsEndpointAuto
org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementContextAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementContextAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.web.trace.TraceAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.web.trace.HttpTraceAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.web.trace.TraceEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.web.trace.HttpTraceEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration=\ org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration=\
org.springframework.boot.actuate.autoconfigure.endpoint.web.ServletEndpointManagementContextConfiguration,\ org.springframework.boot.actuate.autoconfigure.endpoint.web.ServletEndpointManagementContextConfiguration,\
......
...@@ -76,8 +76,8 @@ public class HttpTraceEndpointDocumentationTests ...@@ -76,8 +76,8 @@ public class HttpTraceEndpointDocumentationTests
tracer.sendingResponse(trace, response, () -> principal, tracer.sendingResponse(trace, response, () -> principal,
() -> UUID.randomUUID().toString()); () -> UUID.randomUUID().toString());
given(this.repository.findAll()).willReturn(Arrays.asList(trace)); given(this.repository.findAll()).willReturn(Arrays.asList(trace));
this.mockMvc.perform(get("/actuator/trace")).andExpect(status().isOk()) this.mockMvc.perform(get("/actuator/httptrace")).andExpect(status().isOk())
.andDo(document("trace", .andDo(document("httptrace",
responseFields( responseFields(
fieldWithPath("traces").description( fieldWithPath("traces").description(
"An array of traced HTTP request-response exchanges."), "An array of traced HTTP request-response exchanges."),
......
...@@ -29,7 +29,7 @@ import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoC ...@@ -29,7 +29,7 @@ import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoC
import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.management.ThreadDumpEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.management.ThreadDumpEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.mappings.MappingsEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.web.mappings.MappingsEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.trace.TraceEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.web.trace.HttpTraceEndpointAutoConfiguration;
/** /**
* A list of all endpoint auto-configuration classes for use in tests. * A list of all endpoint auto-configuration classes for use in tests.
...@@ -49,7 +49,7 @@ final class EndpointAutoConfigurationClasses { ...@@ -49,7 +49,7 @@ final class EndpointAutoConfigurationClasses {
all.add(HealthEndpointAutoConfiguration.class); all.add(HealthEndpointAutoConfiguration.class);
all.add(InfoEndpointAutoConfiguration.class); all.add(InfoEndpointAutoConfiguration.class);
all.add(ThreadDumpEndpointAutoConfiguration.class); all.add(ThreadDumpEndpointAutoConfiguration.class);
all.add(TraceEndpointAutoConfiguration.class); all.add(HttpTraceEndpointAutoConfiguration.class);
all.add(MappingsEndpointAutoConfiguration.class); all.add(MappingsEndpointAutoConfiguration.class);
ALL = all.toArray(new Class<?>[] {}); ALL = all.toArray(new Class<?>[] {});
} }
......
...@@ -28,7 +28,7 @@ import org.junit.Test; ...@@ -28,7 +28,7 @@ import org.junit.Test;
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.endpoint.jmx.JmxEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.jmx.JmxEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.trace.TraceAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.web.trace.HttpTraceAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration; import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
...@@ -47,7 +47,7 @@ public class JmxEndpointIntegrationTests { ...@@ -47,7 +47,7 @@ public class JmxEndpointIntegrationTests {
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(JmxAutoConfiguration.class, .withConfiguration(AutoConfigurations.of(JmxAutoConfiguration.class,
EndpointAutoConfiguration.class, JmxEndpointAutoConfiguration.class, EndpointAutoConfiguration.class, JmxEndpointAutoConfiguration.class,
TraceAutoConfiguration.class)) HttpTraceAutoConfiguration.class))
.withConfiguration( .withConfiguration(
AutoConfigurations.of(EndpointAutoConfigurationClasses.ALL)); AutoConfigurations.of(EndpointAutoConfigurationClasses.ALL));
...@@ -57,7 +57,7 @@ public class JmxEndpointIntegrationTests { ...@@ -57,7 +57,7 @@ public class JmxEndpointIntegrationTests {
MBeanServer mBeanServer = context.getBean(MBeanServer.class); MBeanServer mBeanServer = context.getBean(MBeanServer.class);
checkEndpointMBeans(mBeanServer, checkEndpointMBeans(mBeanServer,
new String[] { "beans", "conditions", "configprops", "env", "health", new String[] { "beans", "conditions", "configprops", "env", "health",
"info", "mappings", "threaddump", "trace" }, "info", "mappings", "threaddump", "httptrace" },
new String[] { "shutdown" }); new String[] { "shutdown" });
}); });
} }
...@@ -70,7 +70,7 @@ public class JmxEndpointIntegrationTests { ...@@ -70,7 +70,7 @@ public class JmxEndpointIntegrationTests {
checkEndpointMBeans(mBeanServer, new String[0], checkEndpointMBeans(mBeanServer, new String[0],
new String[] { "beans", "conditions", "configprops", "env", new String[] { "beans", "conditions", "configprops", "env",
"health", "mappings", "shutdown", "threaddump", "health", "mappings", "shutdown", "threaddump",
"trace" }); "httptrace" });
}); });
} }
...@@ -82,7 +82,7 @@ public class JmxEndpointIntegrationTests { ...@@ -82,7 +82,7 @@ public class JmxEndpointIntegrationTests {
MBeanServer mBeanServer = context.getBean(MBeanServer.class); MBeanServer mBeanServer = context.getBean(MBeanServer.class);
checkEndpointMBeans(mBeanServer, new String[] { "beans" }, checkEndpointMBeans(mBeanServer, new String[] { "beans" },
new String[] { "conditions", "configprops", "env", "health", new String[] { "conditions", "configprops", "env", "health",
"mappings", "shutdown", "threaddump", "trace" }); "mappings", "shutdown", "threaddump", "httptrace" });
}); });
} }
......
...@@ -22,7 +22,7 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfi ...@@ -22,7 +22,7 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfi
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.trace.TraceAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.web.trace.HttpTraceAutoConfiguration;
import org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint; import org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint;
import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
...@@ -61,7 +61,7 @@ public class WebMvcEndpointExposureIntegrationTests { ...@@ -61,7 +61,7 @@ public class WebMvcEndpointExposureIntegrationTests {
ServletManagementContextAutoConfiguration.class, ServletManagementContextAutoConfiguration.class,
ManagementContextAutoConfiguration.class, ManagementContextAutoConfiguration.class,
ServletManagementContextAutoConfiguration.class, ServletManagementContextAutoConfiguration.class,
TraceAutoConfiguration.class)) HttpTraceAutoConfiguration.class))
.withConfiguration( .withConfiguration(
AutoConfigurations.of(EndpointAutoConfigurationClasses.ALL)) AutoConfigurations.of(EndpointAutoConfigurationClasses.ALL))
.withUserConfiguration(CustomMvcEndpoint.class); .withUserConfiguration(CustomMvcEndpoint.class);
...@@ -80,7 +80,7 @@ public class WebMvcEndpointExposureIntegrationTests { ...@@ -80,7 +80,7 @@ public class WebMvcEndpointExposureIntegrationTests {
assertThat(isExposed(mvc, HttpMethod.GET, "mappings")).isFalse(); assertThat(isExposed(mvc, HttpMethod.GET, "mappings")).isFalse();
assertThat(isExposed(mvc, HttpMethod.POST, "shutdown")).isFalse(); assertThat(isExposed(mvc, HttpMethod.POST, "shutdown")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "threaddump")).isFalse(); assertThat(isExposed(mvc, HttpMethod.GET, "threaddump")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "trace")).isFalse(); assertThat(isExposed(mvc, HttpMethod.GET, "httptrace")).isFalse();
}); });
} }
...@@ -100,7 +100,7 @@ public class WebMvcEndpointExposureIntegrationTests { ...@@ -100,7 +100,7 @@ public class WebMvcEndpointExposureIntegrationTests {
assertThat(isExposed(mvc, HttpMethod.GET, "mappings")).isTrue(); assertThat(isExposed(mvc, HttpMethod.GET, "mappings")).isTrue();
assertThat(isExposed(mvc, HttpMethod.POST, "shutdown")).isFalse(); assertThat(isExposed(mvc, HttpMethod.POST, "shutdown")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "threaddump")).isTrue(); assertThat(isExposed(mvc, HttpMethod.GET, "threaddump")).isTrue();
assertThat(isExposed(mvc, HttpMethod.GET, "trace")).isTrue(); assertThat(isExposed(mvc, HttpMethod.GET, "httptrace")).isTrue();
}); });
} }
...@@ -120,7 +120,7 @@ public class WebMvcEndpointExposureIntegrationTests { ...@@ -120,7 +120,7 @@ public class WebMvcEndpointExposureIntegrationTests {
assertThat(isExposed(mvc, HttpMethod.GET, "mappings")).isFalse(); assertThat(isExposed(mvc, HttpMethod.GET, "mappings")).isFalse();
assertThat(isExposed(mvc, HttpMethod.POST, "shutdown")).isFalse(); assertThat(isExposed(mvc, HttpMethod.POST, "shutdown")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "threaddump")).isFalse(); assertThat(isExposed(mvc, HttpMethod.GET, "threaddump")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "trace")).isFalse(); assertThat(isExposed(mvc, HttpMethod.GET, "httptrace")).isFalse();
}); });
} }
...@@ -141,7 +141,7 @@ public class WebMvcEndpointExposureIntegrationTests { ...@@ -141,7 +141,7 @@ public class WebMvcEndpointExposureIntegrationTests {
assertThat(isExposed(mvc, HttpMethod.GET, "mappings")).isTrue(); assertThat(isExposed(mvc, HttpMethod.GET, "mappings")).isTrue();
assertThat(isExposed(mvc, HttpMethod.POST, "shutdown")).isFalse(); assertThat(isExposed(mvc, HttpMethod.POST, "shutdown")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "threaddump")).isTrue(); assertThat(isExposed(mvc, HttpMethod.GET, "threaddump")).isTrue();
assertThat(isExposed(mvc, HttpMethod.GET, "trace")).isTrue(); assertThat(isExposed(mvc, HttpMethod.GET, "httptrace")).isTrue();
}); });
} }
......
...@@ -37,16 +37,17 @@ import org.springframework.context.annotation.Configuration; ...@@ -37,16 +37,17 @@ import org.springframework.context.annotation.Configuration;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
/** /**
* Tests for {@link TraceAutoConfiguration}. * Tests for {@link HttpTraceAutoConfiguration}.
* *
* @author Andy Wilkinson * @author Andy Wilkinson
*/ */
public class TraceAutoConfigurationTests { public class HttpTraceAutoConfigurationTests {
@Test @Test
public void configuresRepository() { public void configuresRepository() {
new WebApplicationContextRunner() new WebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class)) .withConfiguration(
AutoConfigurations.of(HttpTraceAutoConfiguration.class))
.run((context) -> assertThat(context) .run((context) -> assertThat(context)
.hasSingleBean(InMemoryHttpTraceRepository.class)); .hasSingleBean(InMemoryHttpTraceRepository.class));
} }
...@@ -54,7 +55,8 @@ public class TraceAutoConfigurationTests { ...@@ -54,7 +55,8 @@ public class TraceAutoConfigurationTests {
@Test @Test
public void usesUserProvidedRepository() { public void usesUserProvidedRepository() {
new WebApplicationContextRunner() new WebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class)) .withConfiguration(
AutoConfigurations.of(HttpTraceAutoConfiguration.class))
.withUserConfiguration(CustomRepositoryConfiguration.class) .withUserConfiguration(CustomRepositoryConfiguration.class)
.run((context) -> { .run((context) -> {
assertThat(context).hasSingleBean(HttpTraceRepository.class); assertThat(context).hasSingleBean(HttpTraceRepository.class);
...@@ -66,7 +68,8 @@ public class TraceAutoConfigurationTests { ...@@ -66,7 +68,8 @@ public class TraceAutoConfigurationTests {
@Test @Test
public void configuresTracer() { public void configuresTracer() {
new WebApplicationContextRunner() new WebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class)) .withConfiguration(
AutoConfigurations.of(HttpTraceAutoConfiguration.class))
.run((context) -> assertThat(context) .run((context) -> assertThat(context)
.hasSingleBean(HttpExchangeTracer.class)); .hasSingleBean(HttpExchangeTracer.class));
} }
...@@ -74,7 +77,8 @@ public class TraceAutoConfigurationTests { ...@@ -74,7 +77,8 @@ public class TraceAutoConfigurationTests {
@Test @Test
public void usesUserProvidedTracer() { public void usesUserProvidedTracer() {
new WebApplicationContextRunner() new WebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class)) .withConfiguration(
AutoConfigurations.of(HttpTraceAutoConfiguration.class))
.withUserConfiguration(CustomTracerConfiguration.class).run((context) -> { .withUserConfiguration(CustomTracerConfiguration.class).run((context) -> {
assertThat(context).hasSingleBean(HttpExchangeTracer.class); assertThat(context).hasSingleBean(HttpExchangeTracer.class);
assertThat(context.getBean(HttpExchangeTracer.class)) assertThat(context.getBean(HttpExchangeTracer.class))
...@@ -85,7 +89,8 @@ public class TraceAutoConfigurationTests { ...@@ -85,7 +89,8 @@ public class TraceAutoConfigurationTests {
@Test @Test
public void configuresWebFilter() { public void configuresWebFilter() {
new ReactiveWebApplicationContextRunner() new ReactiveWebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class)) .withConfiguration(
AutoConfigurations.of(HttpTraceAutoConfiguration.class))
.run((context) -> assertThat(context) .run((context) -> assertThat(context)
.hasSingleBean(HttpTraceWebFilter.class)); .hasSingleBean(HttpTraceWebFilter.class));
} }
...@@ -93,7 +98,8 @@ public class TraceAutoConfigurationTests { ...@@ -93,7 +98,8 @@ public class TraceAutoConfigurationTests {
@Test @Test
public void usesUserProvidedWebFilter() { public void usesUserProvidedWebFilter() {
new ReactiveWebApplicationContextRunner() new ReactiveWebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class)) .withConfiguration(
AutoConfigurations.of(HttpTraceAutoConfiguration.class))
.withUserConfiguration(CustomWebFilterConfiguration.class) .withUserConfiguration(CustomWebFilterConfiguration.class)
.run((context) -> { .run((context) -> {
assertThat(context).hasSingleBean(HttpTraceWebFilter.class); assertThat(context).hasSingleBean(HttpTraceWebFilter.class);
...@@ -105,7 +111,8 @@ public class TraceAutoConfigurationTests { ...@@ -105,7 +111,8 @@ public class TraceAutoConfigurationTests {
@Test @Test
public void configuresServletFilter() { public void configuresServletFilter() {
new WebApplicationContextRunner() new WebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class)) .withConfiguration(
AutoConfigurations.of(HttpTraceAutoConfiguration.class))
.run((context) -> assertThat(context) .run((context) -> assertThat(context)
.hasSingleBean(HttpTraceFilter.class)); .hasSingleBean(HttpTraceFilter.class));
} }
...@@ -113,7 +120,8 @@ public class TraceAutoConfigurationTests { ...@@ -113,7 +120,8 @@ public class TraceAutoConfigurationTests {
@Test @Test
public void usesUserProvidedServletFilter() { public void usesUserProvidedServletFilter() {
new WebApplicationContextRunner() new WebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class)) .withConfiguration(
AutoConfigurations.of(HttpTraceAutoConfiguration.class))
.withUserConfiguration(CustomFilterConfiguration.class).run((context) -> { .withUserConfiguration(CustomFilterConfiguration.class).run((context) -> {
assertThat(context).hasSingleBean(HttpTraceFilter.class); assertThat(context).hasSingleBean(HttpTraceFilter.class);
assertThat(context.getBean(HttpTraceFilter.class)) assertThat(context.getBean(HttpTraceFilter.class))
...@@ -124,8 +132,9 @@ public class TraceAutoConfigurationTests { ...@@ -124,8 +132,9 @@ public class TraceAutoConfigurationTests {
@Test @Test
public void backsOffWhenDisabled() { public void backsOffWhenDisabled() {
new WebApplicationContextRunner() new WebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class)) .withConfiguration(
.withPropertyValues("management.trace.enabled=false") AutoConfigurations.of(HttpTraceAutoConfiguration.class))
.withPropertyValues("management.httptrace.enabled=false")
.run((context) -> assertThat(context) .run((context) -> assertThat(context)
.doesNotHaveBean(InMemoryHttpTraceRepository.class) .doesNotHaveBean(InMemoryHttpTraceRepository.class)
.doesNotHaveBean(HttpExchangeTracer.class) .doesNotHaveBean(HttpExchangeTracer.class)
...@@ -168,7 +177,7 @@ public class TraceAutoConfigurationTests { ...@@ -168,7 +177,7 @@ public class TraceAutoConfigurationTests {
static class CustomTracerConfiguration { static class CustomTracerConfiguration {
@Bean @Bean
public CustomHttpExchangeTracer customTracer(TraceProperties properties) { public CustomHttpExchangeTracer customTracer(HttpTraceProperties properties) {
return new CustomHttpExchangeTracer(properties.getInclude()); return new CustomHttpExchangeTracer(properties.getInclude());
} }
...@@ -188,7 +197,7 @@ public class TraceAutoConfigurationTests { ...@@ -188,7 +197,7 @@ public class TraceAutoConfigurationTests {
@Bean @Bean
public CustomHttpTraceWebFilter customWebFilter(HttpTraceRepository repository, public CustomHttpTraceWebFilter customWebFilter(HttpTraceRepository repository,
HttpExchangeTracer tracer, TraceProperties properties) { HttpExchangeTracer tracer, HttpTraceProperties properties) {
return new CustomHttpTraceWebFilter(repository, tracer, return new CustomHttpTraceWebFilter(repository, tracer,
properties.getInclude()); properties.getInclude());
} }
......
...@@ -25,15 +25,15 @@ import org.springframework.boot.test.context.runner.WebApplicationContextRunner; ...@@ -25,15 +25,15 @@ import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
/** /**
* Tests for {@link TraceEndpointAutoConfiguration}. * Tests for {@link HttpTraceEndpointAutoConfiguration}.
* *
* @author Phillip Webb * @author Phillip Webb
*/ */
public class TraceEndpointAutoConfigurationTests { public class HttpTraceEndpointAutoConfigurationTests {
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class, .withConfiguration(AutoConfigurations.of(HttpTraceAutoConfiguration.class,
TraceEndpointAutoConfiguration.class)); HttpTraceEndpointAutoConfiguration.class));
@Test @Test
public void runShouldHaveEndpointBean() { public void runShouldHaveEndpointBean() {
...@@ -43,14 +43,15 @@ public class TraceEndpointAutoConfigurationTests { ...@@ -43,14 +43,15 @@ public class TraceEndpointAutoConfigurationTests {
@Test @Test
public void runWhenEnabledPropertyIsFalseShouldNotHaveEndpointBean() { public void runWhenEnabledPropertyIsFalseShouldNotHaveEndpointBean() {
this.contextRunner.withPropertyValues("management.endpoint.trace.enabled:false") this.contextRunner
.withPropertyValues("management.endpoint.httptrace.enabled:false")
.run((context) -> assertThat(context) .run((context) -> assertThat(context)
.doesNotHaveBean(HttpTraceEndpoint.class)); .doesNotHaveBean(HttpTraceEndpoint.class));
} }
@Test @Test
public void endpointBacksOffWhenRepositoryIsNotAvailable() { public void endpointBacksOffWhenRepositoryIsNotAvailable() {
this.contextRunner.withPropertyValues("management.trace.enabled:false") this.contextRunner.withPropertyValues("management.httptrace.enabled:false")
.run((context) -> assertThat(context) .run((context) -> assertThat(context)
.doesNotHaveBean(HttpTraceEndpoint.class)); .doesNotHaveBean(HttpTraceEndpoint.class));
} }
......
...@@ -133,17 +133,18 @@ public class HttpExchangeTracer { ...@@ -133,17 +133,18 @@ public class HttpExchangeTracer {
@Override @Override
public Map<String, List<String>> getHeaders() { public Map<String, List<String>> getHeaders() {
return getHeadersIfIncluded(Include.REQUEST_HEADERS, return getHeadersIfIncluded(Include.REQUEST_HEADERS,
this.delegate::getHeaders, (name) -> { this.delegate::getHeaders, this::includedHeader);
}
private boolean includedHeader(String name) {
if (name.equalsIgnoreCase(HttpHeaders.COOKIE)) { if (name.equalsIgnoreCase(HttpHeaders.COOKIE)) {
return HttpExchangeTracer.this.includes return HttpExchangeTracer.this.includes.contains(Include.COOKIE_HEADERS);
.contains(Include.COOKIE_HEADERS);
} }
if (name.equalsIgnoreCase(HttpHeaders.AUTHORIZATION)) { if (name.equalsIgnoreCase(HttpHeaders.AUTHORIZATION)) {
return HttpExchangeTracer.this.includes return HttpExchangeTracer.this.includes
.contains(Include.AUTHORIZATION_HEADER); .contains(Include.AUTHORIZATION_HEADER);
} }
return true; return true;
});
} }
@Override @Override
...@@ -169,13 +170,14 @@ public class HttpExchangeTracer { ...@@ -169,13 +170,14 @@ public class HttpExchangeTracer {
@Override @Override
public Map<String, List<String>> getHeaders() { public Map<String, List<String>> getHeaders() {
return getHeadersIfIncluded(Include.RESPONSE_HEADERS, return getHeadersIfIncluded(Include.RESPONSE_HEADERS,
this.delegate::getHeaders, (name) -> { this.delegate::getHeaders, this::includedHeader);
}
private boolean includedHeader(String name) {
if (name.equalsIgnoreCase(HttpHeaders.SET_COOKIE)) { if (name.equalsIgnoreCase(HttpHeaders.SET_COOKIE)) {
return HttpExchangeTracer.this.includes return HttpExchangeTracer.this.includes.contains(Include.COOKIE_HEADERS);
.contains(Include.COOKIE_HEADERS);
} }
return true; return true;
});
} }
} }
......
...@@ -26,9 +26,10 @@ import org.springframework.util.Assert; ...@@ -26,9 +26,10 @@ import org.springframework.util.Assert;
* {@link Endpoint} to expose {@link HttpTrace} information. * {@link Endpoint} to expose {@link HttpTrace} information.
* *
* @author Dave Syer * @author Dave Syer
* @author Andy Wilkinson
* @since 2.0.0 * @since 2.0.0
*/ */
@Endpoint(id = "trace") @Endpoint(id = "httptrace")
public class HttpTraceEndpoint { public class HttpTraceEndpoint {
private final HttpTraceRepository repository; private final HttpTraceRepository repository;
...@@ -43,19 +44,19 @@ public class HttpTraceEndpoint { ...@@ -43,19 +44,19 @@ public class HttpTraceEndpoint {
} }
@ReadOperation @ReadOperation
public TraceDescriptor traces() { public HttpTraceDescriptor traces() {
return new TraceDescriptor(this.repository.findAll()); return new HttpTraceDescriptor(this.repository.findAll());
} }
/** /**
* A description of an application's {@link HttpTrace} entries. Primarily intended for * A description of an application's {@link HttpTrace} entries. Primarily intended for
* serialization to JSON. * serialization to JSON.
*/ */
public static final class TraceDescriptor { public static final class HttpTraceDescriptor {
private final List<HttpTrace> traces; private final List<HttpTrace> traces;
private TraceDescriptor(List<HttpTrace> traces) { private HttpTraceDescriptor(List<HttpTrace> traces) {
this.traces = traces; this.traces = traces;
} }
......
...@@ -1206,6 +1206,10 @@ content into your application. Rather, pick only the properties that you need. ...@@ -1206,6 +1206,10 @@ content into your application. Rather, pick only the properties that you need.
management.endpoint.heapdump.cache.time-to-live=0ms # Maximum time that a response can be cached. management.endpoint.heapdump.cache.time-to-live=0ms # Maximum time that a response can be cached.
management.endpoint.heapdump.enabled= # Whether to enable the heapdump endpoint. management.endpoint.heapdump.enabled= # Whether to enable the heapdump endpoint.
# HTTP TRACE ENDPOINT ({sc-spring-boot-actuator}/web/trace/HttpTraceEndpoint.{sc-ext}[HttpTraceEndpoint])
management.endpoint.httptrace.cache.time-to-live=0ms # Maximum time that a response can be cached.
management.endpoint.httptrace.enabled= # Whether to enable the HTTP trace endpoint.
# INFO ENDPOINT ({sc-spring-boot-actuator}/info/InfoEndpoint.{sc-ext}[InfoEndpoint]) # INFO ENDPOINT ({sc-spring-boot-actuator}/info/InfoEndpoint.{sc-ext}[InfoEndpoint])
info= # Arbitrary properties to add to the info endpoint. info= # Arbitrary properties to add to the info endpoint.
management.endpoint.info.cache.time-to-live=0ms # Maximum time that a response can be cached. management.endpoint.info.cache.time-to-live=0ms # Maximum time that a response can be cached.
...@@ -1250,10 +1254,6 @@ content into your application. Rather, pick only the properties that you need. ...@@ -1250,10 +1254,6 @@ content into your application. Rather, pick only the properties that you need.
management.endpoint.threaddump.cache.time-to-live=0ms # Maximum time that a response can be cached. management.endpoint.threaddump.cache.time-to-live=0ms # Maximum time that a response can be cached.
management.endpoint.threaddump.enabled= # Whether to enable the threaddump endpoint. management.endpoint.threaddump.enabled= # Whether to enable the threaddump endpoint.
# TRACE ENDPOINT ({sc-spring-boot-actuator}/web/trace/HttpTraceEndpoint.{sc-ext}[HttpTraceEndpoint])
management.endpoint.trace.cache.time-to-live=0ms # Maximum time that a response can be cached.
management.endpoint.trace.enabled= # Whether to enable the trace endpoint.
# JOLOKIA ENDPOINT ({sc-spring-boot-actuator-autoconfigure}/jolokia/JolokiaProperties.{sc-ext}[JolokiaProperties]) # JOLOKIA ENDPOINT ({sc-spring-boot-actuator-autoconfigure}/jolokia/JolokiaProperties.{sc-ext}[JolokiaProperties])
management.endpoint.jolokia.config.*= # Jolokia settings. See the Jolokia manual for details. management.endpoint.jolokia.config.*= # Jolokia settings. See the Jolokia manual for details.
management.endpoint.jolokia.enabled=true # Whether to enable Jolokia. management.endpoint.jolokia.enabled=true # Whether to enable Jolokia.
...@@ -1281,6 +1281,10 @@ content into your application. Rather, pick only the properties that you need. ...@@ -1281,6 +1281,10 @@ content into your application. Rather, pick only the properties that you need.
management.health.status.http-mapping= # Mapping of health statuses to HTTP status codes. By default, registered health statuses map to sensible defaults (for example, UP maps to 200). management.health.status.http-mapping= # Mapping of health statuses to HTTP status codes. By default, registered health statuses map to sensible defaults (for example, UP maps to 200).
management.health.status.order=DOWN, OUT_OF_SERVICE, UP, UNKNOWN # Comma-separated list of health statuses in order of severity. management.health.status.order=DOWN, OUT_OF_SERVICE, UP, UNKNOWN # Comma-separated list of health statuses in order of severity.
# HTTP TRACING ({sc-spring-boot-actuator-autoconfigure}/web/trace/HttpTraceProperties.{sc-ext}[HttpTraceProperties])
management.httptrace.enabled=true # Whether to enable HTTP request-response tracing.
management.httptrace.include=request-headers,response-headers,cookies,errors # Items to be included in the trace.
# INFO CONTRIBUTORS ({sc-spring-boot-actuator-autoconfigure}/info/InfoContributorProperties.{sc-ext}[InfoContributorProperties]) # INFO CONTRIBUTORS ({sc-spring-boot-actuator-autoconfigure}/info/InfoContributorProperties.{sc-ext}[InfoContributorProperties])
management.info.build.enabled=true # Whether to enable build info. management.info.build.enabled=true # Whether to enable build info.
management.info.defaults.enabled=true # Whether to enable default info contributors. management.info.defaults.enabled=true # Whether to enable default info contributors.
...@@ -1375,10 +1379,6 @@ content into your application. Rather, pick only the properties that you need. ...@@ -1375,10 +1379,6 @@ content into your application. Rather, pick only the properties that you need.
management.metrics.web.server.record-request-percentiles=false # Whether instrumented requests record percentiles histogram buckets by default. management.metrics.web.server.record-request-percentiles=false # Whether instrumented requests record percentiles histogram buckets by default.
management.metrics.web.server.requests-metric-name=http.server.requests # Name of the metric for received requests. management.metrics.web.server.requests-metric-name=http.server.requests # Name of the metric for received requests.
# TRACING ({sc-spring-boot-actuator-autoconfigure}/web/trace/TraceProperties.{sc-ext}[TraceProperties])
management.trace.enabled=true # Whether to enable HTTP request-response tracing.
management.trace.include=request-headers,response-headers,cookies,errors # Items to be included in the trace.
# ---------------------------------------- # ----------------------------------------
# DEVTOOLS PROPERTIES # DEVTOOLS PROPERTIES
......
...@@ -96,6 +96,11 @@ classes and the reasons why they did or did not match. ...@@ -96,6 +96,11 @@ classes and the reasons why they did or did not match.
|Shows application health information. |Shows application health information.
|Yes |Yes
|`httptrace`
|Displays HTTP trace information (by default, the last 100 HTTP request-response
exchanges).
|Yes
|`info` |`info`
|Displays arbitrary application info. |Displays arbitrary application info.
|Yes |Yes
...@@ -133,10 +138,6 @@ store. Not available when using Spring Session's support for reactive web applic ...@@ -133,10 +138,6 @@ store. Not available when using Spring Session's support for reactive web applic
|Performs a thread dump. |Performs a thread dump.
|Yes |Yes
|`trace`
|Displays HTTP trace information (by default, the last 100 HTTP requests).
|Yes
|=== |===
If your application is a web application (Spring MVC, Spring WebFlux, or Jersey), you can If your application is a web application (Spring MVC, Spring WebFlux, or Jersey), you can
...@@ -243,6 +244,10 @@ endpoints: ...@@ -243,6 +244,10 @@ endpoints:
|N/A |N/A
|No |No
|`httptrace`
|Yes
|No
|`info` |`info`
|Yes |Yes
|Yes |Yes
...@@ -291,10 +296,6 @@ endpoints: ...@@ -291,10 +296,6 @@ endpoints:
|Yes |Yes
|No |No
|`trace`
|Yes
|No
|=== |===
To change which endpoints are exposed, use the following technology-specific `expose` and To change which endpoints are exposed, use the following technology-specific `expose` and
...@@ -1309,22 +1310,22 @@ implementing `ApplicationEventPublisherAware`). ...@@ -1309,22 +1310,22 @@ implementing `ApplicationEventPublisherAware`).
[[production-ready-tracing]] [[production-ready-http-tracing]]
== Tracing == HTTP Tracing
Tracing is automatically enabled for all HTTP requests. You can view the `trace` endpoint Tracing is automatically enabled for all HTTP requests. You can view the `httptrace`
and obtain basic information about the last 100 requests. endpoint and obtain basic information about the last 100 request-response exchanges.
[[production-ready-custom-tracing]] [[production-ready-http-tracing-custom]]
=== Custom tracing === Custom HTTP tracing
To customize the items that are included in each trace, use the To customize the items that are included in each trace, use the
`management.trace.include` configuration property. `management.httptrace.include` configuration property.
By default, an `InMemoryTraceRepository` that stores the last 100 events is used. If you By default, an `InMemoryHttpTraceRepository` that stores traces for the last 100
need to expand the capacity, you can define your own instance of the request-response exchanges is used. If you need to expand the capacity, you can define
`InMemoryTraceRepository` bean. You can also create your own alternative your own instance of the `InMemoryHttpTraceRepository` bean. You can also create your own
`TraceRepository` implementation. alternative `HttpTraceRepository` implementation.
......
...@@ -18,4 +18,4 @@ spring.jmx.enabled=true ...@@ -18,4 +18,4 @@ spring.jmx.enabled=true
spring.jackson.serialization.write_dates_as_timestamps=false spring.jackson.serialization.write_dates_as_timestamps=false
management.trace.include=REQUEST_HEADERS,RESPONSE_HEADERS,PRINCIPAL,REMOTE_ADDRESS,SESSION_ID management.httptrace.include=REQUEST_HEADERS,RESPONSE_HEADERS,PRINCIPAL,REMOTE_ADDRESS,SESSION_ID
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment