Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 28bd5f5

Browse files
committed
Merge pull request spring-projects#16039 from amcghie
* pr/16039: Polish "Complete support for customizing Tomcat's access log" Complete support for customizing Tomcat's access log
2 parents 6615e11 + 076e327 commit 28bd5f5

File tree

4 files changed

+215
-18
lines changed

4 files changed

+215
-18
lines changed

‎spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java‎

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
* @author Olivier Lamy
5757
* @author Chentao Qu
5858
* @author Artsiom Yudovin
59+
* @author Andrew McGhie
5960
*/
6061
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
6162
public class ServerProperties {
@@ -545,6 +546,18 @@ public static class Accesslog {
545546
*/
546547
private boolean enabled = false;
547548

549+
/**
550+
* Whether logging of the request will only be enabled if
551+
* "ServletRequest.getAttribute(conditionIf)" does not yield null.
552+
*/
553+
private String conditionIf;
554+
555+
/**
556+
* Whether logging of the request will only be enabled if
557+
* "ServletRequest.getAttribute(conditionUnless)" yield null.
558+
*/
559+
private String conditionUnless;
560+
548561
/**
549562
* Format pattern for access logs.
550563
*/
@@ -566,6 +579,24 @@ public static class Accesslog {
566579
*/
567580
private String suffix = ".log";
568581

582+
/**
583+
* Character set used by the log file. Default to the system default character
584+
* set.
585+
*/
586+
private String encoding;
587+
588+
/**
589+
* Locale used to format timestamps in log entries and in log file name
590+
* suffix. Default to the default locale of the Java process.
591+
*/
592+
private String locale;
593+
594+
/**
595+
* Whether to check for log file existence so it can be recreated it if an
596+
* external process has renamed it.
597+
*/
598+
private boolean checkExists = false;
599+
569600
/**
570601
* Whether to enable access log rotation.
571602
*/
@@ -587,6 +618,11 @@ public static class Accesslog {
587618
*/
588619
private String fileDateFormat = ".yyyy-MM-dd";
589620

621+
/**
622+
* Whether to use IPv6 canonical representation format as defined by RFC 5952.
623+
*/
624+
private boolean ipv6Canonical = false;
625+
590626
/**
591627
* Set request attributes for the IP address, Hostname, protocol, and port
592628
* used for the request.
@@ -606,6 +642,22 @@ public void setEnabled(boolean enabled) {
606642
this.enabled = enabled;
607643
}
608644

645+
public String getConditionIf() {
646+
return this.conditionIf;
647+
}
648+
649+
public void setConditionIf(String conditionIf) {
650+
this.conditionIf = conditionIf;
651+
}
652+
653+
public String getConditionUnless() {
654+
return this.conditionUnless;
655+
}
656+
657+
public void setConditionUnless(String conditionUnless) {
658+
this.conditionUnless = conditionUnless;
659+
}
660+
609661
public String getPattern() {
610662
return this.pattern;
611663
}
@@ -638,6 +690,30 @@ public void setSuffix(String suffix) {
638690
this.suffix = suffix;
639691
}
640692

693+
public String getEncoding() {
694+
return this.encoding;
695+
}
696+
697+
public void setEncoding(String encoding) {
698+
this.encoding = encoding;
699+
}
700+
701+
public String getLocale() {
702+
return this.locale;
703+
}
704+
705+
public void setLocale(String locale) {
706+
this.locale = locale;
707+
}
708+
709+
public boolean isCheckExists() {
710+
return this.checkExists;
711+
}
712+
713+
public void setCheckExists(boolean checkExists) {
714+
this.checkExists = checkExists;
715+
}
716+
641717
public boolean isRotate() {
642718
return this.rotate;
643719
}
@@ -670,6 +746,14 @@ public void setFileDateFormat(String fileDateFormat) {
670746
this.fileDateFormat = fileDateFormat;
671747
}
672748

749+
public boolean isIpv6Canonical() {
750+
return this.ipv6Canonical;
751+
}
752+
753+
public void setIpv6Canonical(boolean ipv6Canonical) {
754+
this.ipv6Canonical = ipv6Canonical;
755+
}
756+
673757
public boolean isRequestAttributesEnabled() {
674758
return this.requestAttributesEnabled;
675759
}

‎spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java‎

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.springframework.boot.autoconfigure.web.ErrorProperties.IncludeStacktrace;
3131
import org.springframework.boot.autoconfigure.web.ServerProperties;
3232
import org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat;
33+
import org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat.Accesslog;
3334
import org.springframework.boot.cloud.CloudPlatform;
3435
import org.springframework.boot.context.properties.PropertyMapper;
3536
import org.springframework.boot.web.embedded.tomcat.ConfigurableTomcatWebServerFactory;
@@ -49,6 +50,7 @@
4950
* @author Phillip Webb
5051
* @author Artsiom Yudovin
5152
* @author Chentao Qu
53+
* @author Andrew McGhie
5254
* @since 2.0.0
5355
*/
5456
public class TomcatWebServerFactoryCustomizer implements
@@ -246,17 +248,25 @@ private void customizeMaxHttpPostSize(ConfigurableTomcatWebServerFactory factory
246248
private void customizeAccessLog(ConfigurableTomcatWebServerFactory factory) {
247249
ServerProperties.Tomcat tomcatProperties = this.serverProperties.getTomcat();
248250
AccessLogValve valve = new AccessLogValve();
249-
valve.setPattern(tomcatProperties.getAccesslog().getPattern());
250-
valve.setDirectory(tomcatProperties.getAccesslog().getDirectory());
251-
valve.setPrefix(tomcatProperties.getAccesslog().getPrefix());
252-
valve.setSuffix(tomcatProperties.getAccesslog().getSuffix());
253-
valve.setRenameOnRotate(tomcatProperties.getAccesslog().isRenameOnRotate());
254-
valve.setMaxDays(tomcatProperties.getAccesslog().getMaxDays());
255-
valve.setFileDateFormat(tomcatProperties.getAccesslog().getFileDateFormat());
256-
valve.setRequestAttributesEnabled(
257-
tomcatProperties.getAccesslog().isRequestAttributesEnabled());
258-
valve.setRotatable(tomcatProperties.getAccesslog().isRotate());
259-
valve.setBuffered(tomcatProperties.getAccesslog().isBuffered());
251+
PropertyMapper map = PropertyMapper.get();
252+
Accesslog accessLogConfig = tomcatProperties.getAccesslog();
253+
map.from(accessLogConfig.getConditionIf()).to(valve::setConditionIf);
254+
map.from(accessLogConfig.getConditionUnless()).to(valve::setConditionUnless);
255+
map.from(accessLogConfig.getPattern()).to(valve::setPattern);
256+
map.from(accessLogConfig.getDirectory()).to(valve::setDirectory);
257+
map.from(accessLogConfig.getPrefix()).to(valve::setPrefix);
258+
map.from(accessLogConfig.getSuffix()).to(valve::setSuffix);
259+
map.from(accessLogConfig.getEncoding()).whenHasText().to(valve::setEncoding);
260+
map.from(accessLogConfig.getLocale()).whenHasText().to(valve::setLocale);
261+
map.from(accessLogConfig.isCheckExists()).to(valve::setCheckExists);
262+
map.from(accessLogConfig.isRotate()).to(valve::setRotatable);
263+
map.from(accessLogConfig.isRenameOnRotate()).to(valve::setRenameOnRotate);
264+
map.from(accessLogConfig.getMaxDays()).to(valve::setMaxDays);
265+
map.from(accessLogConfig.getFileDateFormat()).to(valve::setFileDateFormat);
266+
map.from(accessLogConfig.isIpv6Canonical()).to(valve::setIpv6Canonical);
267+
map.from(accessLogConfig.isRequestAttributesEnabled())
268+
.to(valve::setRequestAttributesEnabled);
269+
map.from(accessLogConfig.isBuffered()).to(valve::setBuffered);
260270
factory.addEngineValves(valve);
261271
}
262272

‎spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java‎

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.eclipse.jetty.server.Request;
4343
import org.junit.Test;
4444

45+
import org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat.Accesslog;
4546
import org.springframework.boot.context.properties.bind.Bindable;
4647
import org.springframework.boot.context.properties.bind.Binder;
4748
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
@@ -72,6 +73,7 @@
7273
* @author Eddú Meléndez
7374
* @author Quinten De Swaef
7475
* @author Venil Noronha
76+
* @author Andrew McGhie
7577
*/
7678
public class ServerPropertiesTests {
7779

@@ -111,24 +113,37 @@ public void testConnectionTimeout() {
111113
@Test
112114
public void testTomcatBinding() {
113115
Map<String, String> map = new HashMap<>();
116+
map.put("server.tomcat.accesslog.conditionIf", "foo");
117+
map.put("server.tomcat.accesslog.conditionUnless", "bar");
114118
map.put("server.tomcat.accesslog.pattern", "%h %t '%r' %s %b");
115119
map.put("server.tomcat.accesslog.prefix", "foo");
120+
map.put("server.tomcat.accesslog.suffix", "-bar.log");
121+
map.put("server.tomcat.accesslog.encoding", "UTF-8");
122+
map.put("server.tomcat.accesslog.locale", "en-AU");
123+
map.put("server.tomcat.accesslog.checkExists", "true");
116124
map.put("server.tomcat.accesslog.rotate", "false");
117125
map.put("server.tomcat.accesslog.rename-on-rotate", "true");
126+
map.put("server.tomcat.accesslog.ipv6Canonical", "true");
118127
map.put("server.tomcat.accesslog.request-attributes-enabled", "true");
119-
map.put("server.tomcat.accesslog.suffix", "-bar.log");
120128
map.put("server.tomcat.protocol-header", "X-Forwarded-Protocol");
121129
map.put("server.tomcat.remote-ip-header", "Remote-Ip");
122130
map.put("server.tomcat.internal-proxies", "10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
123131
map.put("server.tomcat.background-processor-delay", "10");
124132
bind(map);
125133
ServerProperties.Tomcat tomcat = this.properties.getTomcat();
126-
assertThat(tomcat.getAccesslog().getPattern()).isEqualTo("%h %t '%r' %s %b");
127-
assertThat(tomcat.getAccesslog().getPrefix()).isEqualTo("foo");
128-
assertThat(tomcat.getAccesslog().isRotate()).isFalse();
129-
assertThat(tomcat.getAccesslog().isRenameOnRotate()).isTrue();
130-
assertThat(tomcat.getAccesslog().isRequestAttributesEnabled()).isTrue();
131-
assertThat(tomcat.getAccesslog().getSuffix()).isEqualTo("-bar.log");
134+
Accesslog accesslog = tomcat.getAccesslog();
135+
assertThat(accesslog.getConditionIf()).isEqualTo("foo");
136+
assertThat(accesslog.getConditionUnless()).isEqualTo("bar");
137+
assertThat(accesslog.getPattern()).isEqualTo("%h %t '%r' %s %b");
138+
assertThat(accesslog.getPrefix()).isEqualTo("foo");
139+
assertThat(accesslog.getSuffix()).isEqualTo("-bar.log");
140+
assertThat(accesslog.getEncoding()).isEqualTo("UTF-8");
141+
assertThat(accesslog.getLocale()).isEqualTo("en-AU");
142+
assertThat(accesslog.isCheckExists()).isEqualTo(true);
143+
assertThat(accesslog.isRotate()).isFalse();
144+
assertThat(accesslog.isRenameOnRotate()).isTrue();
145+
assertThat(accesslog.isIpv6Canonical()).isTrue();
146+
assertThat(accesslog.isRequestAttributesEnabled()).isTrue();
132147
assertThat(tomcat.getRemoteIpHeader()).isEqualTo("Remote-Ip");
133148
assertThat(tomcat.getProtocolHeader()).isEqualTo("X-Forwarded-Protocol");
134149
assertThat(tomcat.getInternalProxies())

‎spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java‎

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.boot.autoconfigure.web.embedded;
1818

19+
import java.util.Locale;
1920
import java.util.function.Consumer;
2021

2122
import org.apache.catalina.Context;
@@ -49,6 +50,7 @@
4950
* @author Rob Tompkins
5051
* @author Artsiom Yudovin
5152
* @author Stephane Nicoll
53+
* @author Andrew McGhie
5254
*/
5355
public class TomcatWebServerFactoryCustomizerTests {
5456

@@ -324,6 +326,75 @@ public void accessLogMaxDaysDefault() {
324326
this.serverProperties.getTomcat().getAccesslog().getMaxDays());
325327
}
326328

329+
@Test
330+
public void accessLogConditionCanBeSpecified() {
331+
bind("server.tomcat.accesslog.enabled=true",
332+
"server.tomcat.accesslog.conditionIf=foo",
333+
"server.tomcat.accesslog.conditionUnless=bar");
334+
TomcatServletWebServerFactory factory = customizeAndGetFactory();
335+
assertThat(((AccessLogValve) factory.getEngineValves().iterator().next())
336+
.getConditionIf()).isEqualTo("foo");
337+
assertThat(((AccessLogValve) factory.getEngineValves().iterator().next())
338+
.getConditionUnless()).isEqualTo("bar");
339+
assertThat(((AccessLogValve) factory.getEngineValves().iterator().next())
340+
.getCondition()).describedAs(
341+
"value of condition should equal conditionUnless - provided for backwards compatibility")
342+
.isEqualTo("bar");
343+
}
344+
345+
@Test
346+
public void accessLogEncodingIsNullWhenNotSpecified() {
347+
bind("server.tomcat.accesslog.enabled=true");
348+
TomcatServletWebServerFactory factory = customizeAndGetFactory();
349+
assertThat(((AccessLogValve) factory.getEngineValves().iterator().next())
350+
.getEncoding()).isNull();
351+
}
352+
353+
@Test
354+
public void accessLogEncodingCanBeSpecified() {
355+
bind("server.tomcat.accesslog.enabled=true",
356+
"server.tomcat.accesslog.encoding=UTF-8");
357+
TomcatServletWebServerFactory factory = customizeAndGetFactory();
358+
assertThat(((AccessLogValve) factory.getEngineValves().iterator().next())
359+
.getEncoding()).isEqualTo("UTF-8");
360+
}
361+
362+
@Test
363+
public void accessLogWithDefaultLocale() {
364+
bind("server.tomcat.accesslog.enabled=true");
365+
TomcatServletWebServerFactory factory = customizeAndGetFactory();
366+
assertThat(((AccessLogValve) factory.getEngineValves().iterator().next())
367+
.getLocale()).isEqualTo(Locale.getDefault().toString());
368+
}
369+
370+
@Test
371+
public void accessLogLocaleCanBeSpecified() {
372+
String locale = "en_AU".equals(Locale.getDefault().toString()) ? "en_US"
373+
: "en_AU";
374+
bind("server.tomcat.accesslog.enabled=true",
375+
"server.tomcat.accesslog.locale=" + locale);
376+
TomcatServletWebServerFactory factory = customizeAndGetFactory();
377+
assertThat(((AccessLogValve) factory.getEngineValves().iterator().next())
378+
.getLocale()).isEqualTo(locale);
379+
}
380+
381+
@Test
382+
public void accessLogCheckExistsDefault() {
383+
bind("server.tomcat.accesslog.enabled=true");
384+
TomcatServletWebServerFactory factory = customizeAndGetFactory();
385+
assertThat(((AccessLogValve) factory.getEngineValves().iterator().next())
386+
.isCheckExists()).isFalse();
387+
}
388+
389+
@Test
390+
public void accessLogCheckExistsSpecified() {
391+
bind("server.tomcat.accesslog.enabled=true",
392+
"server.tomcat.accesslog.check-exists=true");
393+
TomcatServletWebServerFactory factory = customizeAndGetFactory();
394+
assertThat(((AccessLogValve) factory.getEngineValves().iterator().next())
395+
.isCheckExists()).isTrue();
396+
}
397+
327398
@Test
328399
public void accessLogMaxDaysCanBeRedefined() {
329400
bind("server.tomcat.accesslog.enabled=true",
@@ -333,6 +404,23 @@ public void accessLogMaxDaysCanBeRedefined() {
333404
.getMaxDays()).isEqualTo(20);
334405
}
335406

407+
@Test
408+
public void accessLogDoesNotUseIpv6CanonicalFormatByDefault() {
409+
bind("server.tomcat.accesslog.enabled=true");
410+
TomcatServletWebServerFactory factory = customizeAndGetFactory();
411+
assertThat(((AccessLogValve) factory.getEngineValves().iterator().next())
412+
.getIpv6Canonical()).isFalse();
413+
}
414+
415+
@Test
416+
public void accessLogwithIpv6CanonicalSet() {
417+
bind("server.tomcat.accesslog.enabled=true",
418+
"server.tomcat.accesslog.ipv6-canonical=true");
419+
TomcatServletWebServerFactory factory = customizeAndGetFactory();
420+
assertThat(((AccessLogValve) factory.getEngineValves().iterator().next())
421+
.getIpv6Canonical()).isTrue();
422+
}
423+
336424
private void bind(String... inlinedProperties) {
337425
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment,
338426
inlinedProperties);

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /