mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-09-03 04:26:12 +08:00
Clean up access logging threads when Undertow is stopped
Closes gh-12742
This commit is contained in:
parent
e7b03f7ca3
commit
2bb7a430cf
@ -32,6 +32,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EventListener;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@ -46,6 +47,8 @@ import javax.net.ssl.TrustManagerFactory;
|
||||
import javax.net.ssl.X509ExtendedKeyManager;
|
||||
import javax.servlet.ServletContainerInitializer;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import io.undertow.Undertow;
|
||||
@ -64,6 +67,7 @@ import io.undertow.server.session.SessionManager;
|
||||
import io.undertow.servlet.Servlets;
|
||||
import io.undertow.servlet.api.DeploymentInfo;
|
||||
import io.undertow.servlet.api.DeploymentManager;
|
||||
import io.undertow.servlet.api.ListenerInfo;
|
||||
import io.undertow.servlet.api.MimeMapping;
|
||||
import io.undertow.servlet.api.ServletContainerInitializerInfo;
|
||||
import io.undertow.servlet.api.ServletStackTraces;
|
||||
@ -417,34 +421,41 @@ public class UndertowEmbeddedServletContainerFactory
|
||||
}
|
||||
|
||||
private void configureAccessLog(DeploymentInfo deploymentInfo) {
|
||||
deploymentInfo.addInitialHandlerChainWrapper(new HandlerWrapper() {
|
||||
|
||||
@Override
|
||||
public HttpHandler wrap(HttpHandler handler) {
|
||||
return createAccessLogHandler(handler);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private AccessLogHandler createAccessLogHandler(HttpHandler handler) {
|
||||
try {
|
||||
createAccessLogDirectoryIfNecessary();
|
||||
XnioWorker worker = createWorker();
|
||||
String prefix = (this.accessLogPrefix != null ? this.accessLogPrefix
|
||||
: "access_log.");
|
||||
AccessLogReceiver accessLogReceiver = new DefaultAccessLogReceiver(
|
||||
createWorker(), this.accessLogDirectory, prefix, this.accessLogSuffix,
|
||||
DefaultAccessLogReceiver accessLogReceiver = new DefaultAccessLogReceiver(
|
||||
worker, this.accessLogDirectory, prefix, this.accessLogSuffix,
|
||||
this.accessLogRotate);
|
||||
String formatString = (this.accessLogPattern != null ? this.accessLogPattern
|
||||
: "common");
|
||||
return new AccessLogHandler(handler, accessLogReceiver, formatString,
|
||||
Undertow.class.getClassLoader());
|
||||
EventListener listener = new AccessLogShutdownListener(worker,
|
||||
accessLogReceiver);
|
||||
deploymentInfo.addListener(new ListenerInfo(AccessLogShutdownListener.class,
|
||||
new ImmediateInstanceFactory<EventListener>(listener)));
|
||||
deploymentInfo.addInitialHandlerChainWrapper(new HandlerWrapper() {
|
||||
|
||||
@Override
|
||||
public HttpHandler wrap(HttpHandler handler) {
|
||||
return createAccessLogHandler(handler, accessLogReceiver);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalStateException("Failed to create AccessLogHandler", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private AccessLogHandler createAccessLogHandler(HttpHandler handler,
|
||||
AccessLogReceiver accessLogReceiver) {
|
||||
createAccessLogDirectoryIfNecessary();
|
||||
String formatString = (this.accessLogPattern != null) ? this.accessLogPattern
|
||||
: "common";
|
||||
return new AccessLogHandler(handler, accessLogReceiver, formatString,
|
||||
Undertow.class.getClassLoader());
|
||||
}
|
||||
|
||||
private void createAccessLogDirectoryIfNecessary() {
|
||||
Assert.state(this.accessLogDirectory != null, "Access log directory is not set");
|
||||
if (!this.accessLogDirectory.isDirectory() && !this.accessLogDirectory.mkdirs()) {
|
||||
@ -790,4 +801,33 @@ public class UndertowEmbeddedServletContainerFactory
|
||||
|
||||
}
|
||||
|
||||
private static class AccessLogShutdownListener implements ServletContextListener {
|
||||
|
||||
private final XnioWorker worker;
|
||||
|
||||
private final DefaultAccessLogReceiver accessLogReceiver;
|
||||
|
||||
AccessLogShutdownListener(XnioWorker worker,
|
||||
DefaultAccessLogReceiver accessLogReceiver) {
|
||||
this.worker = worker;
|
||||
this.accessLogReceiver = accessLogReceiver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
try {
|
||||
this.accessLogReceiver.close();
|
||||
this.worker.shutdown();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ import io.undertow.servlet.api.DeploymentInfo;
|
||||
import io.undertow.servlet.api.DeploymentManager;
|
||||
import io.undertow.servlet.api.ServletContainer;
|
||||
import org.apache.jasper.servlet.JspServlet;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.InOrder;
|
||||
|
||||
@ -73,6 +74,11 @@ public class UndertowEmbeddedServletContainerFactoryTests
|
||||
return new UndertowEmbeddedServletContainerFactory(0);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void errorPage404() throws Exception {
|
||||
AbstractEmbeddedServletContainerFactory factory = getFactory();
|
||||
|
Loading…
Reference in New Issue
Block a user