Ensure that access log is flushed periodically

Previously, Tomcat’s background processing was only enabled on the
context but access logging was configured on the engine. This means that
the access log valve’s background processing method was never called
and, therefore, that it wasn’t flushed periodically.

This commit moves the enablement of background processing up to the
engine, thereby ensuring that the access log is flushed periodically.
Background processing cascades down the container hierarchy so, after
this change, background processing will still be performed on the
context as well.

Closes gh-6646
This commit is contained in:
Andy Wilkinson
2016-08-22 22:36:28 +01:00
parent a16aa767dc
commit e465368f54
3 changed files with 39 additions and 15 deletions

View File

@@ -777,7 +777,7 @@ public class ServerProperties
if (getBasedir() != null) {
factory.setBaseDirectory(getBasedir());
}
customizeBackgroundProcessorDelay(factory);
factory.setBackgroundProcessorDelay(Tomcat.this.backgroundProcessorDelay);
customizeRemoteIpValve(serverProperties, factory);
if (this.maxThreads > 0) {
customizeMaxThreads(factory);
@@ -819,19 +819,6 @@ public class ServerProperties
}
}
private void customizeBackgroundProcessorDelay(
TomcatEmbeddedServletContainerFactory factory) {
factory.addContextCustomizers(new TomcatContextCustomizer() {
@Override
public void customize(Context context) {
context.setBackgroundProcessorDelay(
Tomcat.this.backgroundProcessorDelay);
}
});
}
private void customizeRemoteIpValve(ServerProperties properties,
TomcatEmbeddedServletContainerFactory factory) {
String protocolHeader = getProtocolHeader();

View File

@@ -43,6 +43,7 @@ import org.springframework.boot.bind.RelaxedDataBinder;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory;
import org.springframework.boot.web.servlet.ServletContextInitializer;
@@ -140,6 +141,7 @@ public class ServerPropertiesTests {
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");
bindProperties(map);
ServerProperties.Tomcat tomcat = this.properties.getTomcat();
assertThat(tomcat.getAccesslog().getPattern()).isEqualTo("%h %t '%r' %s %b");
@@ -150,6 +152,7 @@ public class ServerPropertiesTests {
assertThat(tomcat.getProtocolHeader()).isEqualTo("X-Forwarded-Protocol");
assertThat(tomcat.getInternalProxies())
.isEqualTo("10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
assertThat(tomcat.getBackgroundProcessorDelay()).isEqualTo(10);
}
@Test
@@ -352,6 +355,29 @@ public class ServerPropertiesTests {
testRemoteIpValveConfigured();
}
@Test
public void defaultTomcatBackgroundProcessorDelay() throws Exception {
TomcatEmbeddedServletContainerFactory container = new TomcatEmbeddedServletContainerFactory();
this.properties.customize(container);
assertThat(
((TomcatEmbeddedServletContainer) container.getEmbeddedServletContainer())
.getTomcat().getEngine().getBackgroundProcessorDelay())
.isEqualTo(30);
}
@Test
public void customTomcatBackgroundProcessorDelay() throws Exception {
Map<String, String> map = new HashMap<String, String>();
map.put("server.tomcat.background-processor-delay", "5");
bindProperties(map);
TomcatEmbeddedServletContainerFactory container = new TomcatEmbeddedServletContainerFactory();
this.properties.customize(container);
assertThat(
((TomcatEmbeddedServletContainer) container.getEmbeddedServletContainer())
.getTomcat().getEngine().getBackgroundProcessorDelay())
.isEqualTo(5);
}
@Test
public void setUseForwardHeadersTomcat() throws Exception {
// Since 1.3.0 no need to explicitly set header names if use-forward-header=true

View File

@@ -129,6 +129,8 @@ public class TomcatEmbeddedServletContainerFactory
private Charset uriEncoding = DEFAULT_CHARSET;
private int backgroundProcessorDelay;
/**
* Create a new {@link TomcatEmbeddedServletContainerFactory} instance.
*/
@@ -176,7 +178,7 @@ public class TomcatEmbeddedServletContainerFactory
}
private void configureEngine(Engine engine) {
engine.setBackgroundProcessorDelay(-1);
engine.setBackgroundProcessorDelay(this.backgroundProcessorDelay);
for (Valve valve : this.engineValves) {
engine.getPipeline().addValve(valve);
}
@@ -765,6 +767,15 @@ public class TomcatEmbeddedServletContainerFactory
return this.uriEncoding;
}
/**
* Sets the background processor delay in seconds.
* @param delay the delay in seconds
* @since 1.4.1
*/
public void setBackgroundProcessorDelay(int delay) {
this.backgroundProcessorDelay = delay;
}
/**
* {@link LifecycleListener} that stores an empty merged web.xml. This is critical for
* Jasper on Tomcat 7 to prevent warnings about missing web.xml files and to enable