diff --git a/spring-boot-actuator/pom.xml b/spring-boot-actuator/pom.xml
index 8863c7c4df..84bc130139 100644
--- a/spring-boot-actuator/pom.xml
+++ b/spring-boot-actuator/pom.xml
@@ -307,6 +307,22 @@
json-path
test
+
+ io.undertow
+ undertow-core
+ test
+
+
+ io.undertow
+ undertow-servlet
+ test
+
+
+ org.jboss.spec.javax.servlet
+ jboss-servlet-api_3.1_spec
+
+
+
org.aspectj
aspectjrt
diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcChildContextConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcChildContextConfiguration.java
index a61a32dceb..b4a8ef2998 100644
--- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcChildContextConfiguration.java
+++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcChildContextConfiguration.java
@@ -24,6 +24,9 @@ import javax.servlet.Filter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.catalina.Valve;
+import org.apache.catalina.valves.AccessLogValve;
+
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.HierarchicalBeanFactory;
@@ -43,6 +46,9 @@ import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
+import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
+import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
+import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory;
import org.springframework.boot.web.servlet.ErrorPage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -106,6 +112,17 @@ public class EndpointWebMvcChildContextConfiguration {
return new ServerCustomization();
}
+ @Bean
+ public UndertowAccessLogCustomizer undertowAccessLogCustomizer() {
+ return new UndertowAccessLogCustomizer();
+ }
+
+ @Bean
+ @ConditionalOnClass(name = "org.apache.catalina.valves.AccessLogValve")
+ public TomcatAccessLogCustomizer tomcatAccessLogCustomizer() {
+ return new TomcatAccessLogCustomizer();
+ }
+
/*
* The error controller is present but not mapped as an endpoint in this context
* because of the DispatcherServlet having had its HandlerMapping explicitly disabled.
@@ -321,4 +338,79 @@ public class EndpointWebMvcChildContextConfiguration {
}
+ static abstract class AccessLogCustomizer
+ implements EmbeddedServletContainerCustomizer, Ordered {
+
+ private final Class factoryClass;
+
+ AccessLogCustomizer(Class factoryClass) {
+ this.factoryClass = factoryClass;
+ }
+
+ protected String customizePrefix(String prefix) {
+ return "management_" + prefix;
+ }
+
+ @Override
+ public int getOrder() {
+ return 1;
+ }
+
+ @Override
+ public void customize(ConfigurableEmbeddedServletContainer container) {
+ if (this.factoryClass.isInstance(container)) {
+ customize(this.factoryClass.cast(container));
+ }
+ }
+
+ abstract void customize(T container);
+ }
+
+ static class TomcatAccessLogCustomizer
+ extends AccessLogCustomizer {
+
+ TomcatAccessLogCustomizer() {
+ super(TomcatEmbeddedServletContainerFactory.class);
+ }
+
+ @Override
+ public int getOrder() {
+ return 1;
+ }
+
+ @Override
+ public void customize(TomcatEmbeddedServletContainerFactory container) {
+ AccessLogValve accessLogValve = findAccessLogValve(container);
+ if (accessLogValve == null) {
+ return;
+ }
+ accessLogValve.setPrefix(customizePrefix(accessLogValve.getPrefix()));
+ }
+
+ private AccessLogValve findAccessLogValve(
+ TomcatEmbeddedServletContainerFactory container) {
+ for (Valve engineValve : container.getEngineValves()) {
+ if (engineValve instanceof AccessLogValve) {
+ return (AccessLogValve) engineValve;
+ }
+ }
+ return null;
+ }
+
+ }
+
+ static class UndertowAccessLogCustomizer
+ extends AccessLogCustomizer {
+
+ UndertowAccessLogCustomizer() {
+ super(UndertowEmbeddedServletContainerFactory.class);
+ }
+
+ @Override
+ public void customize(UndertowEmbeddedServletContainerFactory container) {
+ container.setAccessLogPrefix(customizePrefix(container.getAccessLogPrefix()));
+ }
+
+ }
+
}
diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java
index 4ce12702fc..09a10ca285 100644
--- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java
+++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java
@@ -29,6 +29,8 @@ import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.catalina.Valve;
+import org.apache.catalina.valves.AccessLogValve;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
@@ -67,6 +69,7 @@ import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
import org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
+import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory;
import org.springframework.boot.context.event.ApplicationFailedEvent;
import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.boot.testutil.Matched;
@@ -429,7 +432,8 @@ public class EndpointWebMvcAutoConfigurationTests {
this.applicationContext.register(RootConfig.class, BaseConfiguration.class,
ServerPortConfig.class, EndpointWebMvcAutoConfiguration.class);
this.applicationContext.refresh();
- // /health, /metrics, /env, /actuator, /heapdump (/shutdown is disabled by default)
+ // /health, /metrics, /env, /actuator, /heapdump (/shutdown is disabled by
+ // default)
assertThat(this.applicationContext.getBeansOfType(MvcEndpoint.class)).hasSize(5);
}
@@ -562,6 +566,54 @@ public class EndpointWebMvcAutoConfigurationTests {
assertThat(managementServerProperties.getSsl().isEnabled()).isFalse();
}
+ @Test
+ public void tomcatManagementAccessLogUsesCustomPrefix() throws Exception {
+ this.applicationContext.register(TomcatContainerConfig.class, RootConfig.class,
+ EndpointConfig.class, DifferentPortConfig.class, BaseConfiguration.class,
+ EndpointWebMvcAutoConfiguration.class, ErrorMvcAutoConfiguration.class);
+ EnvironmentTestUtils.addEnvironment(this.applicationContext,
+ "server.tomcat.accesslog.enabled: true");
+ this.applicationContext.refresh();
+ ApplicationContext managementContext = this.applicationContext
+ .getBean(ManagementContextResolver.class).getApplicationContext();
+ EmbeddedServletContainerFactory servletContainerFactory = managementContext
+ .getBean(EmbeddedServletContainerFactory.class);
+ assertThat(servletContainerFactory)
+ .isInstanceOf(TomcatEmbeddedServletContainerFactory.class);
+ AccessLogValve accessLogValve = findAccessLogValve(
+ ((TomcatEmbeddedServletContainerFactory) servletContainerFactory));
+ assertThat(accessLogValve).isNotNull();
+ assertThat(accessLogValve.getPrefix()).isEqualTo("management_access_log");
+ }
+
+ @Test
+ public void undertowManagementAccessLogUsesCustomPrefix() throws Exception {
+ this.applicationContext.register(UndertowContainerConfig.class, RootConfig.class,
+ EndpointConfig.class, DifferentPortConfig.class, BaseConfiguration.class,
+ EndpointWebMvcAutoConfiguration.class, ErrorMvcAutoConfiguration.class);
+ EnvironmentTestUtils.addEnvironment(this.applicationContext,
+ "server.undertow.accesslog.enabled: true");
+ this.applicationContext.refresh();
+ ApplicationContext managementContext = this.applicationContext
+ .getBean(ManagementContextResolver.class).getApplicationContext();
+ EmbeddedServletContainerFactory servletContainerFactory = managementContext
+ .getBean(EmbeddedServletContainerFactory.class);
+ assertThat(servletContainerFactory)
+ .isInstanceOf(UndertowEmbeddedServletContainerFactory.class);
+ assertThat(((UndertowEmbeddedServletContainerFactory) servletContainerFactory)
+ .getAccessLogPrefix()).isEqualTo("management_access_log.");
+ }
+
+ private AccessLogValve findAccessLogValve(
+ TomcatEmbeddedServletContainerFactory container) {
+ for (Valve engineValve : container.getEngineValves()) {
+ if (engineValve instanceof AccessLogValve) {
+ return (AccessLogValve) engineValve;
+ }
+ }
+ return null;
+ }
+
private void endpointDisabled(String name, Class extends MvcEndpoint> type) {
this.applicationContext.register(RootConfig.class, BaseConfiguration.class,
ServerPortConfig.class, EndpointWebMvcAutoConfiguration.class);
@@ -734,6 +786,26 @@ public class EndpointWebMvcAutoConfigurationTests {
}
+ @Configuration
+ public static class TomcatContainerConfig {
+
+ @Bean
+ public TomcatEmbeddedServletContainerFactory embeddedServletContainerFactory() {
+ return new TomcatEmbeddedServletContainerFactory();
+ }
+
+ }
+
+ @Configuration
+ public static class UndertowContainerConfig {
+
+ @Bean
+ public UndertowEmbeddedServletContainerFactory embeddedServletContainerFactory() {
+ return new UndertowEmbeddedServletContainerFactory();
+ }
+
+ }
+
@Configuration
@Import(ServerPortConfig.class)
public static class DifferentPortConfig {
diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java
index e868383866..fd06f59390 100644
--- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java
+++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java
@@ -568,6 +568,10 @@ public class UndertowEmbeddedServletContainerFactory
this.accessLogPattern = accessLogPattern;
}
+ public String getAccessLogPrefix() {
+ return this.accessLogPrefix;
+ }
+
public void setAccessLogPrefix(String accessLogPrefix) {
this.accessLogPrefix = accessLogPrefix;
}