|
32 | 32 | import java.util.Arrays;
|
33 | 33 | import java.util.Collection;
|
34 | 34 | import java.util.Collections;
|
| 35 | +import java.util.EventListener; |
35 | 36 | import java.util.List;
|
36 | 37 | import java.util.Locale;
|
37 | 38 | import java.util.Map;
|
|
46 | 47 | import javax.net.ssl.X509ExtendedKeyManager;
|
47 | 48 | import javax.servlet.ServletContainerInitializer;
|
48 | 49 | import javax.servlet.ServletContext;
|
| 50 | +import javax.servlet.ServletContextEvent; |
| 51 | +import javax.servlet.ServletContextListener; |
49 | 52 | import javax.servlet.ServletException;
|
50 | 53 |
|
51 | 54 | import io.undertow.Undertow;
|
|
64 | 67 | import io.undertow.servlet.Servlets;
|
65 | 68 | import io.undertow.servlet.api.DeploymentInfo;
|
66 | 69 | import io.undertow.servlet.api.DeploymentManager;
|
| 70 | +import io.undertow.servlet.api.ListenerInfo; |
67 | 71 | import io.undertow.servlet.api.MimeMapping;
|
68 | 72 | import io.undertow.servlet.api.ServletContainerInitializerInfo;
|
69 | 73 | import io.undertow.servlet.api.ServletStackTraces;
|
@@ -417,34 +421,41 @@ private DeploymentManager createDeploymentManager(
|
417 | 421 | }
|
418 | 422 |
|
419 | 423 | private void configureAccessLog(DeploymentInfo deploymentInfo) {
|
420 |
| - deploymentInfo.addInitialHandlerChainWrapper(new HandlerWrapper() { |
421 |
| - |
422 |
| - @Override |
423 |
| - public HttpHandler wrap(HttpHandler handler) { |
424 |
| - return createAccessLogHandler(handler); |
425 |
| - } |
426 |
| - |
427 |
| - }); |
428 |
| - } |
429 |
| - |
430 |
| - private AccessLogHandler createAccessLogHandler(HttpHandler handler) { |
431 | 424 | try {
|
432 | 425 | createAccessLogDirectoryIfNecessary();
|
| 426 | + XnioWorker worker = createWorker(); |
433 | 427 | String prefix = (this.accessLogPrefix != null ? this.accessLogPrefix
|
434 | 428 | : "access_log.");
|
435 |
| - AccessLogReceiver accessLogReceiver = new DefaultAccessLogReceiver( |
436 |
| - createWorker(), this.accessLogDirectory, prefix, this.accessLogSuffix, |
| 429 | + DefaultAccessLogReceiver accessLogReceiver = new DefaultAccessLogReceiver( |
| 430 | + worker, this.accessLogDirectory, prefix, this.accessLogSuffix, |
437 | 431 | this.accessLogRotate);
|
438 |
| - String formatString = (this.accessLogPattern != null ? this.accessLogPattern |
439 |
| - : "common"); |
440 |
| - return new AccessLogHandler(handler, accessLogReceiver, formatString, |
441 |
| - Undertow.class.getClassLoader()); |
| 432 | + EventListener listener = new AccessLogShutdownListener(worker, |
| 433 | + accessLogReceiver); |
| 434 | + deploymentInfo.addListener(new ListenerInfo(AccessLogShutdownListener.class, |
| 435 | + new ImmediateInstanceFactory<EventListener>(listener))); |
| 436 | + deploymentInfo.addInitialHandlerChainWrapper(new HandlerWrapper() { |
| 437 | + |
| 438 | + @Override |
| 439 | + public HttpHandler wrap(HttpHandler handler) { |
| 440 | + return createAccessLogHandler(handler, accessLogReceiver); |
| 441 | + } |
| 442 | + |
| 443 | + }); |
442 | 444 | }
|
443 | 445 | catch (IOException ex) {
|
444 | 446 | throw new IllegalStateException("Failed to create AccessLogHandler", ex);
|
445 | 447 | }
|
446 | 448 | }
|
447 | 449 |
|
| 450 | + private AccessLogHandler createAccessLogHandler(HttpHandler handler, |
| 451 | + AccessLogReceiver accessLogReceiver) { |
| 452 | + createAccessLogDirectoryIfNecessary(); |
| 453 | + String formatString = (this.accessLogPattern != null) ? this.accessLogPattern |
| 454 | + : "common"; |
| 455 | + return new AccessLogHandler(handler, accessLogReceiver, formatString, |
| 456 | + Undertow.class.getClassLoader()); |
| 457 | + } |
| 458 | + |
448 | 459 | private void createAccessLogDirectoryIfNecessary() {
|
449 | 460 | Assert.state(this.accessLogDirectory != null, "Access log directory is not set");
|
450 | 461 | if (!this.accessLogDirectory.isDirectory() && !this.accessLogDirectory.mkdirs()) {
|
@@ -790,4 +801,33 @@ public String[] getServerAliases(String keyType, Principal[] issuers) {
|
790 | 801 |
|
791 | 802 | }
|
792 | 803 |
|
| 804 | + private static class AccessLogShutdownListener implements ServletContextListener { |
| 805 | + |
| 806 | + private final XnioWorker worker; |
| 807 | + |
| 808 | + private final DefaultAccessLogReceiver accessLogReceiver; |
| 809 | + |
| 810 | + AccessLogShutdownListener(XnioWorker worker, |
| 811 | + DefaultAccessLogReceiver accessLogReceiver) { |
| 812 | + this.worker = worker; |
| 813 | + this.accessLogReceiver = accessLogReceiver; |
| 814 | + } |
| 815 | + |
| 816 | + @Override |
| 817 | + public void contextInitialized(ServletContextEvent sce) { |
| 818 | + } |
| 819 | + |
| 820 | + @Override |
| 821 | + public void contextDestroyed(ServletContextEvent sce) { |
| 822 | + try { |
| 823 | + this.accessLogReceiver.close(); |
| 824 | + this.worker.shutdown(); |
| 825 | + } |
| 826 | + catch (IOException ex) { |
| 827 | + throw new IllegalStateException(ex); |
| 828 | + } |
| 829 | + } |
| 830 | + |
| 831 | + } |
| 832 | + |
793 | 833 | }
|
0 commit comments