diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java
index 0f09c85204..7e63016ac6 100644
--- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java
+++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java
@@ -546,6 +546,18 @@ public class ServerProperties {
*/
private boolean enabled = false;
+ /**
+ * Whether logging of the request will only be enabled if
+ * "ServletRequest.getAttribute(conditionIf)" does not yield null.
+ */
+ private String conditionIf;
+
+ /**
+ * Whether logging of the request will only be enabled if
+ * "ServletRequest.getAttribute(conditionUnless)" yield null.
+ */
+ private String conditionUnless;
+
/**
* Format pattern for access logs.
*/
@@ -567,6 +579,24 @@ public class ServerProperties {
*/
private String suffix = ".log";
+ /**
+ * Character set used by the log file. Default to the system default character
+ * set.
+ */
+ private String encoding;
+
+ /**
+ * Locale used to format timestamps in log entries and in log file name
+ * suffix. Default to the default locale of the Java process.
+ */
+ private String locale;
+
+ /**
+ * Whether to check for log file existence so it can be recreated it if an
+ * external process has renamed it.
+ */
+ private boolean checkExists = false;
+
/**
* Whether to enable access log rotation.
*/
@@ -588,6 +618,11 @@ public class ServerProperties {
*/
private String fileDateFormat = ".yyyy-MM-dd";
+ /**
+ * Whether to use IPv6 canonical representation format as defined by RFC 5952.
+ */
+ private boolean ipv6Canonical = false;
+
/**
* Set request attributes for the IP address, Hostname, protocol, and port
* used for the request.
@@ -599,42 +634,6 @@ public class ServerProperties {
*/
private boolean buffered = true;
- /**
- * Check for log file existence so it can be recreated it if an external
- * process/agent has renamed it.
- */
- private boolean checkExists = false;
-
- /**
- * If the value returned from ServletRequest.getAttribute(conditionIf) yields
- * a null value, logging of the request will be skipped.
- */
- private String conditionIf;
-
- /**
- * If the value returned from ServletRequest.getAttribute(conditionUnless)
- * yields a non-null value, the logging of the request will be skipped.
- */
- private String conditionUnless;
-
- /**
- * Character set used by the log file. If it is null, the system
- * default character set will be used. An empty string will be treated as
- * null when this property is assigned.
- */
- private String encoding;
-
- /**
- * Use IPv6 canonical representation format as defined by RFC 5952 in output.
- */
- private boolean ipv6Canonical = false;
-
- /**
- * Set the locale used to format timestamps in log entries and in log file
- * name suffix.
- */
- private String locale = Locale.getDefault().toString();
-
public boolean isEnabled() {
return this.enabled;
}
@@ -643,6 +642,22 @@ public class ServerProperties {
this.enabled = enabled;
}
+ public String getConditionIf() {
+ return this.conditionIf;
+ }
+
+ public void setConditionIf(String conditionIf) {
+ this.conditionIf = conditionIf;
+ }
+
+ public String getConditionUnless() {
+ return this.conditionUnless;
+ }
+
+ public void setConditionUnless(String conditionUnless) {
+ this.conditionUnless = conditionUnless;
+ }
+
public String getPattern() {
return this.pattern;
}
@@ -675,6 +690,30 @@ public class ServerProperties {
this.suffix = suffix;
}
+ public String getEncoding() {
+ return this.encoding;
+ }
+
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ public String getLocale() {
+ return this.locale;
+ }
+
+ public void setLocale(String locale) {
+ this.locale = locale;
+ }
+
+ public boolean isCheckExists() {
+ return this.checkExists;
+ }
+
+ public void setCheckExists(boolean checkExists) {
+ this.checkExists = checkExists;
+ }
+
public boolean isRotate() {
return this.rotate;
}
@@ -707,6 +746,14 @@ public class ServerProperties {
this.fileDateFormat = fileDateFormat;
}
+ public boolean isIpv6Canonical() {
+ return this.ipv6Canonical;
+ }
+
+ public void setIpv6Canonical(boolean ipv6Canonical) {
+ this.ipv6Canonical = ipv6Canonical;
+ }
+
public boolean isRequestAttributesEnabled() {
return this.requestAttributesEnabled;
}
@@ -723,54 +770,6 @@ public class ServerProperties {
this.buffered = buffered;
}
- public boolean isCheckExists() {
- return this.checkExists;
- }
-
- public void setCheckExists(boolean checkExists) {
- this.checkExists = checkExists;
- }
-
- public String getConditionIf() {
- return this.conditionIf;
- }
-
- public void setConditionIf(String conditionIf) {
- this.conditionIf = conditionIf;
- }
-
- public String getConditionUnless() {
- return this.conditionUnless;
- }
-
- public void setConditionUnless(String conditionUnless) {
- this.conditionUnless = conditionUnless;
- }
-
- public String getEncoding() {
- return this.encoding;
- }
-
- public void setEncoding(String encoding) {
- this.encoding = encoding;
- }
-
- public boolean isIpv6Canonical() {
- return this.ipv6Canonical;
- }
-
- public void setIpv6Canonical(boolean ipv6Canonical) {
- this.ipv6Canonical = ipv6Canonical;
- }
-
- public String getLocale() {
- return this.locale;
- }
-
- public void setLocale(String locale) {
- this.locale = locale;
- }
-
}
/**
diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java
index e674a8d22c..76cba0c862 100644
--- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java
+++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java
@@ -30,6 +30,7 @@ import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.ErrorProperties.IncludeStacktrace;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat;
+import org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat.Accesslog;
import org.springframework.boot.cloud.CloudPlatform;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.boot.web.embedded.tomcat.ConfigurableTomcatWebServerFactory;
@@ -247,23 +248,25 @@ public class TomcatWebServerFactoryCustomizer implements
private void customizeAccessLog(ConfigurableTomcatWebServerFactory factory) {
ServerProperties.Tomcat tomcatProperties = this.serverProperties.getTomcat();
AccessLogValve valve = new AccessLogValve();
- valve.setPattern(tomcatProperties.getAccesslog().getPattern());
- valve.setDirectory(tomcatProperties.getAccesslog().getDirectory());
- valve.setPrefix(tomcatProperties.getAccesslog().getPrefix());
- valve.setSuffix(tomcatProperties.getAccesslog().getSuffix());
- valve.setRenameOnRotate(tomcatProperties.getAccesslog().isRenameOnRotate());
- valve.setMaxDays(tomcatProperties.getAccesslog().getMaxDays());
- valve.setFileDateFormat(tomcatProperties.getAccesslog().getFileDateFormat());
- valve.setRequestAttributesEnabled(
- tomcatProperties.getAccesslog().isRequestAttributesEnabled());
- valve.setRotatable(tomcatProperties.getAccesslog().isRotate());
- valve.setBuffered(tomcatProperties.getAccesslog().isBuffered());
- valve.setCheckExists(tomcatProperties.getAccesslog().isCheckExists());
- valve.setConditionIf(tomcatProperties.getAccesslog().getConditionIf());
- valve.setConditionUnless(tomcatProperties.getAccesslog().getConditionUnless());
- valve.setEncoding(tomcatProperties.getAccesslog().getEncoding());
- valve.setIpv6Canonical(tomcatProperties.getAccesslog().isIpv6Canonical());
- valve.setLocale(tomcatProperties.getAccesslog().getLocale());
+ PropertyMapper map = PropertyMapper.get();
+ Accesslog accessLogConfig = tomcatProperties.getAccesslog();
+ map.from(accessLogConfig.getConditionIf()).to(valve::setConditionIf);
+ map.from(accessLogConfig.getConditionUnless()).to(valve::setConditionUnless);
+ map.from(accessLogConfig.getPattern()).to(valve::setPattern);
+ map.from(accessLogConfig.getDirectory()).to(valve::setDirectory);
+ map.from(accessLogConfig.getPrefix()).to(valve::setPrefix);
+ map.from(accessLogConfig.getSuffix()).to(valve::setSuffix);
+ map.from(accessLogConfig.getEncoding()).whenHasText().to(valve::setEncoding);
+ map.from(accessLogConfig.getLocale()).whenHasText().to(valve::setLocale);
+ map.from(accessLogConfig.isCheckExists()).to(valve::setCheckExists);
+ map.from(accessLogConfig.isRotate()).to(valve::setRotatable);
+ map.from(accessLogConfig.isRenameOnRotate()).to(valve::setRenameOnRotate);
+ map.from(accessLogConfig.getMaxDays()).to(valve::setMaxDays);
+ map.from(accessLogConfig.getFileDateFormat()).to(valve::setFileDateFormat);
+ map.from(accessLogConfig.isIpv6Canonical()).to(valve::setIpv6Canonical);
+ map.from(accessLogConfig.isRequestAttributesEnabled())
+ .to(valve::setRequestAttributesEnabled);
+ map.from(accessLogConfig.isBuffered()).to(valve::setBuffered);
factory.addEngineValves(valve);
}
diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java
index 397244ac80..df2eaf5ec0 100644
--- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java
+++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java
@@ -42,6 +42,7 @@ import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.Request;
import org.junit.Test;
+import org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat.Accesslog;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
@@ -112,36 +113,37 @@ public class ServerPropertiesTests {
@Test
public void testTomcatBinding() {
Map map = new HashMap<>();
- map.put("server.tomcat.accesslog.pattern", "%h %t '%r' %s %b");
- map.put("server.tomcat.accesslog.prefix", "foo");
- map.put("server.tomcat.accesslog.rotate", "false");
- map.put("server.tomcat.accesslog.rename-on-rotate", "true");
- map.put("server.tomcat.accesslog.request-attributes-enabled", "true");
- map.put("server.tomcat.accesslog.suffix", "-bar.log");
- map.put("server.tomcat.accesslog.checkExists", "true");
map.put("server.tomcat.accesslog.conditionIf", "foo");
map.put("server.tomcat.accesslog.conditionUnless", "bar");
+ map.put("server.tomcat.accesslog.pattern", "%h %t '%r' %s %b");
+ map.put("server.tomcat.accesslog.prefix", "foo");
+ map.put("server.tomcat.accesslog.suffix", "-bar.log");
map.put("server.tomcat.accesslog.encoding", "UTF-8");
- map.put("server.tomcat.accesslog.ipv6Canonical", "true");
map.put("server.tomcat.accesslog.locale", "en-AU");
+ map.put("server.tomcat.accesslog.checkExists", "true");
+ map.put("server.tomcat.accesslog.rotate", "false");
+ map.put("server.tomcat.accesslog.rename-on-rotate", "true");
+ map.put("server.tomcat.accesslog.ipv6Canonical", "true");
+ map.put("server.tomcat.accesslog.request-attributes-enabled", "true");
map.put("server.tomcat.protocol-header", "X-Forwarded-Protocol");
map.put("server.tomcat.remote-ip-header", "Remote-Ip");
map.put("server.tomcat.internal-proxies", "10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
map.put("server.tomcat.background-processor-delay", "10");
bind(map);
ServerProperties.Tomcat tomcat = this.properties.getTomcat();
- assertThat(tomcat.getAccesslog().getPattern()).isEqualTo("%h %t '%r' %s %b");
- assertThat(tomcat.getAccesslog().getPrefix()).isEqualTo("foo");
- assertThat(tomcat.getAccesslog().isRotate()).isFalse();
- assertThat(tomcat.getAccesslog().isRenameOnRotate()).isTrue();
- assertThat(tomcat.getAccesslog().isRequestAttributesEnabled()).isTrue();
- assertThat(tomcat.getAccesslog().getSuffix()).isEqualTo("-bar.log");
- assertThat(tomcat.getAccesslog().isCheckExists()).isEqualTo(true);
- assertThat(tomcat.getAccesslog().getConditionIf()).isEqualTo("foo");
- assertThat(tomcat.getAccesslog().getConditionUnless()).isEqualTo("bar");
- assertThat(tomcat.getAccesslog().getEncoding()).isEqualTo("UTF-8");
- assertThat(tomcat.getAccesslog().isIpv6Canonical()).isTrue();
- assertThat(tomcat.getAccesslog().getLocale()).isEqualTo("en-AU");
+ Accesslog accesslog = tomcat.getAccesslog();
+ assertThat(accesslog.getConditionIf()).isEqualTo("foo");
+ assertThat(accesslog.getConditionUnless()).isEqualTo("bar");
+ assertThat(accesslog.getPattern()).isEqualTo("%h %t '%r' %s %b");
+ assertThat(accesslog.getPrefix()).isEqualTo("foo");
+ assertThat(accesslog.getSuffix()).isEqualTo("-bar.log");
+ assertThat(accesslog.getEncoding()).isEqualTo("UTF-8");
+ assertThat(accesslog.getLocale()).isEqualTo("en-AU");
+ assertThat(accesslog.isCheckExists()).isEqualTo(true);
+ assertThat(accesslog.isRotate()).isFalse();
+ assertThat(accesslog.isRenameOnRotate()).isTrue();
+ assertThat(accesslog.isIpv6Canonical()).isTrue();
+ assertThat(accesslog.isRequestAttributesEnabled()).isTrue();
assertThat(tomcat.getRemoteIpHeader()).isEqualTo("Remote-Ip");
assertThat(tomcat.getProtocolHeader()).isEqualTo("X-Forwarded-Protocol");
assertThat(tomcat.getInternalProxies())
diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java
index 032e700743..12ee998d54 100644
--- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java
+++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java
@@ -326,32 +326,6 @@ public class TomcatWebServerFactoryCustomizerTests {
this.serverProperties.getTomcat().getAccesslog().getMaxDays());
}
- @Test
- public void accessLogMaxDaysCanBeRedefined() {
- bind("server.tomcat.accesslog.enabled=true",
- "server.tomcat.accesslog.max-days=20");
- TomcatServletWebServerFactory factory = customizeAndGetFactory();
- assertThat(((AccessLogValve) factory.getEngineValves().iterator().next())
- .getMaxDays()).isEqualTo(20);
- }
-
- @Test
- public void accessLogCheckExistsDefault() {
- bind("server.tomcat.accesslog.enabled=true");
- TomcatServletWebServerFactory factory = customizeAndGetFactory();
- assertThat(((AccessLogValve) factory.getEngineValves().iterator().next())
- .isCheckExists()).isFalse();
- }
-
- @Test
- public void accessLogCheckExistsSpecified() {
- bind("server.tomcat.accesslog.enabled=true",
- "server.tomcat.accesslog.checkExists=true");
- TomcatServletWebServerFactory factory = customizeAndGetFactory();
- assertThat(((AccessLogValve) factory.getEngineValves().iterator().next())
- .isCheckExists()).isTrue();
- }
-
@Test
public void accessLogConditionCanBeSpecified() {
bind("server.tomcat.accesslog.enabled=true",
@@ -385,23 +359,6 @@ public class TomcatWebServerFactoryCustomizerTests {
.getEncoding()).isEqualTo("UTF-8");
}
- @Test
- public void accessLogDoesNotUseIpv6CanonicalFormatByDefault() {
- bind("server.tomcat.accesslog.enabled=true");
- TomcatServletWebServerFactory factory = customizeAndGetFactory();
- assertThat(((AccessLogValve) factory.getEngineValves().iterator().next())
- .getIpv6Canonical()).isFalse();
- }
-
- @Test
- public void accessLogwithIpv6CanonicalSet() {
- bind("server.tomcat.accesslog.enabled=true",
- "server.tomcat.accesslog.ipv6Canonical=true");
- TomcatServletWebServerFactory factory = customizeAndGetFactory();
- assertThat(((AccessLogValve) factory.getEngineValves().iterator().next())
- .getIpv6Canonical()).isTrue();
- }
-
@Test
public void accessLogWithDefaultLocale() {
bind("server.tomcat.accesslog.enabled=true");
@@ -421,6 +378,49 @@ public class TomcatWebServerFactoryCustomizerTests {
.getLocale()).isEqualTo(locale);
}
+ @Test
+ public void accessLogCheckExistsDefault() {
+ bind("server.tomcat.accesslog.enabled=true");
+ TomcatServletWebServerFactory factory = customizeAndGetFactory();
+ assertThat(((AccessLogValve) factory.getEngineValves().iterator().next())
+ .isCheckExists()).isFalse();
+ }
+
+ @Test
+ public void accessLogCheckExistsSpecified() {
+ bind("server.tomcat.accesslog.enabled=true",
+ "server.tomcat.accesslog.check-exists=true");
+ TomcatServletWebServerFactory factory = customizeAndGetFactory();
+ assertThat(((AccessLogValve) factory.getEngineValves().iterator().next())
+ .isCheckExists()).isTrue();
+ }
+
+ @Test
+ public void accessLogMaxDaysCanBeRedefined() {
+ bind("server.tomcat.accesslog.enabled=true",
+ "server.tomcat.accesslog.max-days=20");
+ TomcatServletWebServerFactory factory = customizeAndGetFactory();
+ assertThat(((AccessLogValve) factory.getEngineValves().iterator().next())
+ .getMaxDays()).isEqualTo(20);
+ }
+
+ @Test
+ public void accessLogDoesNotUseIpv6CanonicalFormatByDefault() {
+ bind("server.tomcat.accesslog.enabled=true");
+ TomcatServletWebServerFactory factory = customizeAndGetFactory();
+ assertThat(((AccessLogValve) factory.getEngineValves().iterator().next())
+ .getIpv6Canonical()).isFalse();
+ }
+
+ @Test
+ public void accessLogwithIpv6CanonicalSet() {
+ bind("server.tomcat.accesslog.enabled=true",
+ "server.tomcat.accesslog.ipv6-canonical=true");
+ TomcatServletWebServerFactory factory = customizeAndGetFactory();
+ assertThat(((AccessLogValve) factory.getEngineValves().iterator().next())
+ .getIpv6Canonical()).isTrue();
+ }
+
private void bind(String... inlinedProperties) {
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment,
inlinedProperties);