Improve logging behaviour when shutdown occurs via a shutdownhook. If present, use...
authormarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Wed, 17 Feb 2010 13:51:37 +0000 (13:51 +0000)
committermarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Wed, 17 Feb 2010 13:51:37 +0000 (13:51 +0000)
git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@910974 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/catalina/startup/Catalina.java
java/org/apache/juli/ClassLoaderLogManager.java

index a7c722a..4fd6849 100644 (file)
@@ -28,11 +28,13 @@ import java.net.Socket;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
+import java.util.logging.LogManager;
 
 import org.apache.catalina.Container;
 import org.apache.catalina.Lifecycle;
 import org.apache.catalina.LifecycleException;
 import org.apache.catalina.core.StandardServer;
+import org.apache.juli.ClassLoaderLogManager;
 import org.apache.tomcat.util.digester.Digester;
 import org.apache.tomcat.util.digester.Rule;
 import org.xml.sax.Attributes;
@@ -572,6 +574,15 @@ public class Catalina extends Embedded {
                     shutdownHook = new CatalinaShutdownHook();
                 }
                 Runtime.getRuntime().addShutdownHook(shutdownHook);
+                
+                // If JULI is being used, disable JULI's shutdown hook since
+                // shutdown hooks run in parallel and log messages may be lost
+                // if JULI's hook completes before the CatalinaShutdownHook()
+                LogManager logManager = LogManager.getLogManager();
+                if (logManager instanceof ClassLoaderLogManager) {
+                    ((ClassLoaderLogManager) logManager).setUseShutdownHook(
+                            false);
+                }
             }
         } catch (Throwable t) {
             // This will fail on JDK 1.2. Ignoring, as Tomcat can run
@@ -652,6 +663,13 @@ public class Catalina extends Embedded {
                 Catalina.this.stop();
             }
             
+            // If JULI is used, shut JULI down *after* the server shuts down
+            // so log messages aren't lost
+            LogManager logManager = LogManager.getLogManager();
+            if (logManager instanceof ClassLoaderLogManager) {
+                ((ClassLoaderLogManager) logManager).shutdown();
+            }
+
         }
 
     }
index 96ddf17..ac6f14a 100644 (file)
@@ -50,25 +50,8 @@ public class ClassLoaderLogManager extends LogManager {
         
         @Override
         public void run() {
-            // The JVM us being shutdown. Make sure all loggers for all class
-            // loaders are shutdown
-            for (ClassLoaderLogInfo clLogInfo : classLoaderLoggers.values()) {
-                for (Logger logger : clLogInfo.loggers.values()) {
-                    resetLogger(logger);
-                }
-            }
-        }
-            
-        private void resetLogger(Logger logger) {
-            
-            Handler[] handlers = logger.getHandlers();
-            for (Handler handler : handlers) {
-                logger.removeHandler(handler);
-                try {
-                    handler.close();
-                } catch (Exception e) {
-                    // Ignore
-                }
+            if (useShutdownHook) {
+                shutdown();
             }
         }
 
@@ -105,7 +88,29 @@ public class ClassLoaderLogManager extends LogManager {
      */
     protected ThreadLocal<String> prefix = new ThreadLocal<String>();
 
+
+    /**
+     * Determines if the shutdown hook is used to perform any necessary
+     * clean-up such as flushing buffered handlers on JVM shutdown. Defaults to
+     * <code>true</code> but may be set to false if another component ensures
+     * that 
+     */
+    protected boolean useShutdownHook = true;
+
     
+    // ------------------------------------------------------------- Properties
+
+
+    public boolean isUseShutdownHook() {
+        return useShutdownHook;
+    }
+
+
+    public void setUseShutdownHook(boolean useShutdownHook) {
+        this.useShutdownHook = useShutdownHook;
+    }
+
+
     // --------------------------------------------------------- Public Methods
 
 
@@ -294,7 +299,35 @@ public class ClassLoaderLogManager extends LogManager {
         readConfiguration(is, Thread.currentThread().getContextClassLoader());
     
     }
+
+
+    /**
+     * Shuts down the logging system.
+     */
+    public void shutdown() {
+        // The JVM us being shutdown. Make sure all loggers for all class
+        // loaders are shutdown
+        for (ClassLoaderLogInfo clLogInfo : classLoaderLoggers.values()) {
+            for (Logger logger : clLogInfo.loggers.values()) {
+                resetLogger(logger);
+            }
+        }
+    }
+
+    // -------------------------------------------------------- Private Methods
+    private void resetLogger(Logger logger) {
         
+        Handler[] handlers = logger.getHandlers();
+        for (Handler handler : handlers) {
+            logger.removeHandler(handler);
+            try {
+                handler.close();
+            } catch (Exception e) {
+                // Ignore
+            }
+        }
+    }
+
     // ------------------------------------------------------ Protected Methods