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;
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
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();
+ }
+
}
}
@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();
}
}
*/
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
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