Repository: logging-log4j2 Updated Branches: refs/heads/LOG4J2-1349-gcfree-threadcontext 37d47a62a -> 3832ad9b3
Create branch for [LOG4J2-1539]. Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/3f92f7cc Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/3f92f7cc Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/3f92f7cc Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext Commit: 3f92f7cc11f4f7f9a36784f4bdc5380ebbb27c5c Parents: 7eba2e9 Author: Gary Gregory <ggreg...@apache.org> Authored: Mon Aug 22 16:50:01 2016 -0700 Committer: Gary Gregory <ggreg...@apache.org> Committed: Mon Aug 22 16:50:01 2016 -0700 ---------------------------------------------------------------------- .../logging/log4j/core/AbstractLifeCycle.java | 8 ++ .../apache/logging/log4j/core/LifeCycle.java | 13 +++ .../logging/log4j/core/LoggerContext.java | 111 ++++++++++++++++++- .../log4j/core/appender/AbstractManager.java | 6 + .../core/appender/mom/kafka/KafkaManager.java | 17 ++- .../appender/rolling/RollingFileManager.java | 12 +- .../core/config/ConfigurationScheduler.java | 8 +- .../core/config/ConfiguratonFileWatcher.java | 10 +- .../logging/log4j/core/config/Configurator.java | 36 +++++- .../apache/logging/log4j/core/jmx/Server.java | 2 +- .../log4j/core/net/server/JmsServer.java | 7 ++ .../util/DefaultShutdownCallbackRegistry.java | 7 ++ .../log4j/core/util/Log4jThreadFactory.java | 11 ++ .../RandomRollingAppenderOnStartupTest.java | 2 +- .../rolling/RollingAppenderCronTest.java | 2 +- .../RollingAppenderCustomDeleteActionTest.java | 2 +- ...lingAppenderDeleteAccumulatedCount1Test.java | 2 +- ...lingAppenderDeleteAccumulatedCount2Test.java | 2 +- ...ollingAppenderDeleteAccumulatedSizeTest.java | 2 +- .../RollingAppenderDeleteMaxDepthTest.java | 2 +- .../RollingAppenderDeleteNestedTest.java | 2 +- .../RollingAppenderDeleteScriptFri13thTest.java | 2 +- .../RollingAppenderDeleteScriptTest.java | 2 +- ...ollingAppenderNoUnconditionalDeleteTest.java | 2 +- .../rolling/RollingAppenderOnStartupTest.java | 2 +- .../rolling/RollingAppenderSizeTest.java | 2 +- .../rolling/RollingAppenderTimeAndSizeTest.java | 4 +- .../rolling/RollingAppenderTimeTest.java | 2 +- ...RandomAccessFileManagerHeaderFooterTest.java | 3 +- .../logging/log4j/junit/LoggerContextRule.java | 25 ++++- 30 files changed, 260 insertions(+), 48 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/main/java/org/apache/logging/log4j/core/AbstractLifeCycle.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/AbstractLifeCycle.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/AbstractLifeCycle.java index a5a0c77..069362d 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/AbstractLifeCycle.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/AbstractLifeCycle.java @@ -16,6 +16,8 @@ */ package org.apache.logging.log4j.core; +import java.util.concurrent.TimeUnit; + import org.apache.logging.log4j.status.StatusLogger; /** @@ -121,4 +123,10 @@ public class AbstractLifeCycle implements LifeCycle { this.state = LifeCycle.State.STOPPED; } + @Override + public boolean stop(long timeout, TimeUnit timeUnit) { + this.state = LifeCycle.State.STOPPED; + return true; + } + } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/main/java/org/apache/logging/log4j/core/LifeCycle.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/LifeCycle.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/LifeCycle.java index 33a61a2..9311487 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/LifeCycle.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/LifeCycle.java @@ -17,6 +17,8 @@ package org.apache.logging.log4j.core; +import java.util.concurrent.TimeUnit; + /** * All proper Java frameworks implement some sort of object life cycle. In Log4j, the main interface for handling * the life cycle context of an object is this one. An object first starts in the {@link State#INITIALIZED} state @@ -60,7 +62,18 @@ public interface LifeCycle { void stop(); + /** + * Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current + * thread is interrupted, whichever happens first. + * + * @param timeout the maximum time to wait + * @param timeUnit the time unit of the timeout argument + * @return + */ + boolean stop(long timeout, TimeUnit timeUnit); + boolean isStarted(); boolean isStopped(); + } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java index cfb4945..d1bc137 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java @@ -26,6 +26,11 @@ import java.util.Collection; import java.util.Objects; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -40,6 +45,7 @@ import org.apache.logging.log4j.core.config.Reconfigurable; import org.apache.logging.log4j.core.impl.Log4jLogEvent; import org.apache.logging.log4j.core.jmx.Server; import org.apache.logging.log4j.core.util.Cancellable; +import org.apache.logging.log4j.core.util.Log4jThreadFactory; import org.apache.logging.log4j.core.util.NetUtils; import org.apache.logging.log4j.core.util.ShutdownCallbackRegistry; import org.apache.logging.log4j.message.MessageFactory; @@ -72,6 +78,8 @@ public class LoggerContext extends AbstractLifeCycle * reference is updated. */ private volatile Configuration configuration = new DefaultConfiguration(); + private ExecutorService executorService; + private ExecutorService executorServiceDeamons; private Object externalContext; private String contextName; private volatile URI configLocation; @@ -294,11 +302,18 @@ public class LoggerContext extends AbstractLifeCycle @Override public void stop() { + stop(0, null); + } + + @Override + public boolean stop(long timeout, TimeUnit timeUnit) { LOGGER.debug("Stopping LoggerContext[name={}, {}]...", getName(), this); configLock.lock(); + final boolean shutdownEs; + final boolean shutdownEsd; try { if (this.isStopped()) { - return; + return true; } this.setStopping(); @@ -317,11 +332,54 @@ public class LoggerContext extends AbstractLifeCycle prev.stop(); externalContext = null; LogManager.getFactory().removeContext(this); + shutdownEs = shutdown(executorService, timeout, timeUnit); + // Do not wait for daemon threads + shutdownEsd = shutdown(executorServiceDeamons, 0, null); this.setStopped(); } finally { configLock.unlock(); } LOGGER.debug("Stopped LoggerContext[name={}, {}]...", getName(), this); + return shutdownEs && shutdownEsd; + } + + /** + * Shuts down the given pool. + * + * @param pool + * the pool to shutdown. + * @param timeout + * the maximum time to wait + * @param unit + * the time unit of the timeout argument + * @return {@code true} if the given executor terminated and {@code false} if the timeout elapsed before termination. + */ + private boolean shutdown(ExecutorService pool, long timeout, TimeUnit timeUnit) { + pool.shutdown(); // Disable new tasks from being submitted + if (timeout > 0 && timeUnit == null) { + throw new IllegalArgumentException( + String.format("Logger context '%s' can't shutdown %s when timeout = %,d and timeUnit = %s.", + getName(), pool, timeout, timeUnit)); + } + if (timeout > 0) { + try { + // Wait a while for existing tasks to terminate + if (!pool.awaitTermination(timeout, timeUnit)) { + pool.shutdownNow(); // Cancel currently executing tasks + // Wait a while for tasks to respond to being cancelled + if (!pool.awaitTermination(timeout, timeUnit)) { + LOGGER.error("LoggerContext '{}' pool {} did not terminate after {} {}", getName(), pool, timeout, timeUnit); + } + return false; + } + } catch (InterruptedException ie) { + // (Re-)Cancel if current thread also interrupted + pool.shutdownNow(); + // Preserve interrupt status + Thread.currentThread().interrupt(); + } + } + return true; } /** @@ -490,6 +548,9 @@ public class LoggerContext extends AbstractLifeCycle try { final Configuration prev = this.configuration; config.addListener(this); + executorService = Executors.newCachedThreadPool(Log4jThreadFactory.createThreadFactory(contextName)); + executorServiceDeamons = Executors.newCachedThreadPool(Log4jThreadFactory.createDaemonThreadFactory(contextName)); + final ConcurrentMap<String, String> map = config.getComponent(Configuration.CONTEXT_PROPERTIES); try { // LOG4J2-719 network access may throw android.os.NetworkOnMainThreadException @@ -630,4 +691,52 @@ public class LoggerContext extends AbstractLifeCycle return new Logger(ctx, name, messageFactory); } + /** + * Gets the executor service to submit normal tasks. + * + * @return the ExecutorService to submit normal tasks. + */ + public ExecutorService getExecutorService() { + return executorService; + } + + /** + * Gets the executor service to submit daemon tasks. + * + * @return the ExecutorService to submit normal daemon tasks. + */ + public ExecutorService getExecutorServiceDeamons() { + return executorServiceDeamons; + } + + /** + * Submits a Runnable task for normal execution and returns a Future representing that task. The Future's + * {@code get} method will return {@code null} upon <em>successful</em> completion. + * + * @param task the task to submit + * @return a Future representing pending completion of the task + * @throws RejectedExecutionException if the task cannot be + * scheduled for execution + * @throws NullPointerException if the task is null + */ + public Future<?> submit(Runnable task) { + return executorService.submit(task); + } + + /** + * Submits a Runnable task for daemon execution and returns a Future representing that task. The Future's + * {@code get} method will return {@code null} upon <em>successful</em> completion. + * + * @param task + * the task to submit + * @return a Future representing pending completion of the task + * @throws RejectedExecutionException + * if the task cannot be scheduled for execution + * @throws NullPointerException + * if the task is null + */ + public Future<?> submitDaemon(Runnable task) { + return executorServiceDeamons.submit(task); + } + } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractManager.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractManager.java index 4c78e7f..dbe1bc4 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractManager.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractManager.java @@ -23,6 +23,7 @@ import java.util.concurrent.locks.ReentrantLock; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.message.Message; import org.apache.logging.log4j.status.StatusLogger; @@ -116,6 +117,11 @@ public abstract class AbstractManager { return count; } + public LoggerContext getLoggerContext() { + // TODO Can and should a manager tracks it's logger context? + return LoggerContext.getContext(false); + } + /** * Called to signify that this Manager is no longer required by an Appender. */ http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/kafka/KafkaManager.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/kafka/KafkaManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/kafka/KafkaManager.java index d535e02..21224e3 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/kafka/KafkaManager.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/kafka/KafkaManager.java @@ -26,7 +26,6 @@ import org.apache.kafka.clients.producer.Producer; import org.apache.kafka.clients.producer.ProducerRecord; import org.apache.logging.log4j.core.appender.AbstractManager; import org.apache.logging.log4j.core.config.Property; -import org.apache.logging.log4j.core.util.Log4jThread; public class KafkaManager extends AbstractManager { @@ -38,7 +37,7 @@ public class KafkaManager extends AbstractManager { static KafkaProducerFactory producerFactory = new DefaultKafkaProducerFactory(); private final Properties config = new Properties(); - private Producer<byte[], byte[]> producer = null; + private Producer<byte[], byte[]> producer; private final int timeoutMillis; private final String topic; @@ -59,17 +58,17 @@ public class KafkaManager extends AbstractManager { public void releaseSub() { if (producer != null) { // This thread is a workaround for this Kafka issue: https://issues.apache.org/jira/browse/KAFKA-1660 - final Thread closeThread = new Log4jThread(new Runnable() { + final Runnable task = new Runnable() { @Override public void run() { - producer.close(); + if (producer != null) { + producer.close(); + } } - }, "KafkaManager-CloseThread"); - closeThread.setDaemon(true); // avoid blocking JVM shutdown - closeThread.start(); + }; try { - closeThread.join(timeoutMillis); - } catch (final InterruptedException ignore) { + getLoggerContext().submitDaemon(task).get(timeoutMillis, TimeUnit.MILLISECONDS); + } catch (InterruptedException | ExecutionException | TimeoutException e) { // ignore } } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java index 3c6739f..3fcf864 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java @@ -17,24 +17,23 @@ package org.apache.logging.log4j.core.appender.rolling; import java.io.File; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.Serializable; import java.nio.ByteBuffer; +import java.util.concurrent.Future; import java.util.concurrent.Semaphore; import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; import org.apache.logging.log4j.core.Layout; import org.apache.logging.log4j.core.LogEvent; +import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.core.appender.FileManager; import org.apache.logging.log4j.core.appender.ManagerFactory; import org.apache.logging.log4j.core.appender.rolling.action.AbstractAction; import org.apache.logging.log4j.core.appender.rolling.action.Action; -import org.apache.logging.log4j.core.util.Clock; import org.apache.logging.log4j.core.util.Constants; -import org.apache.logging.log4j.core.util.Log4jThread; /** * The Rolling File Manager. @@ -236,7 +235,7 @@ public class RollingFileManager extends FileManager { } boolean success = false; - Thread thread = null; + Future<?> future = null; try { final RolloverDescription descriptor = strategy.rollover(this); @@ -254,14 +253,13 @@ public class RollingFileManager extends FileManager { if (success && descriptor.getAsynchronous() != null) { LOGGER.debug("RollingFileManager executing async {}", descriptor.getAsynchronous()); - thread = new Log4jThread(new AsyncAction(descriptor.getAsynchronous(), this)); - thread.start(); + future = LoggerContext.getContext(false).submit(new AsyncAction(descriptor.getAsynchronous(), this)); } return true; } return false; } finally { - if (thread == null || !thread.isAlive()) { + if (future == null || future.isDone() || future.isCancelled()) { semaphore.release(); } } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationScheduler.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationScheduler.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationScheduler.java index 744ed24..4987082 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationScheduler.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationScheduler.java @@ -39,17 +39,16 @@ public class ConfigurationScheduler extends AbstractLifeCycle { private int scheduledItems = 0; - @Override public void start() { super.start(); if (scheduledItems > 0) { - LOGGER.debug("Starting {} Log4j2Scheduled threads", scheduledItems); + LOGGER.debug("Starting {} Log4j2 Scheduled threads", scheduledItems); if (scheduledItems > 5) { scheduledItems = 5; } executorService = new ScheduledThreadPoolExecutor(scheduledItems, - Log4jThreadFactory.createDaemonThreadFactory("Log4j2Scheduled")); + Log4jThreadFactory.createDaemonThreadFactory("Scheduled")); } else { LOGGER.debug("No scheduled items"); } @@ -58,7 +57,7 @@ public class ConfigurationScheduler extends AbstractLifeCycle { @Override public void stop() { if (executorService != null) { - LOGGER.debug("Stopping Log4j2Scheduled threads."); + LOGGER.debug("Stopping Log4j2 Scheduled threads."); executorService.shutdown(); } super.stop(); @@ -86,6 +85,7 @@ public class ConfigurationScheduler extends AbstractLifeCycle { /** * Creates and executes a ScheduledFuture that becomes enabled after the given delay. + * @param <V> The result type returned by this Future * @param callable the function to execute. * @param delay the time from now to delay execution. * @param unit the time unit of the delay parameter. http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfiguratonFileWatcher.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfiguratonFileWatcher.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfiguratonFileWatcher.java index ceb6b57..cadb5e1 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfiguratonFileWatcher.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfiguratonFileWatcher.java @@ -16,12 +16,12 @@ */ package org.apache.logging.log4j.core.config; -import org.apache.logging.log4j.core.util.FileWatcher; -import org.apache.logging.log4j.core.util.Log4jThread; - import java.io.File; import java.util.List; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.util.FileWatcher; + /** * Watcher for configuration files. Causes a reconfiguration when a file changes. */ @@ -43,9 +43,7 @@ public class ConfiguratonFileWatcher implements FileWatcher { @Override public void fileModified(final File file) { for (final ConfigurationListener listener : listeners) { - final Thread thread = new Log4jThread(new ReconfigurationWorker(listener, reconfigurable)); - thread.setDaemon(true); - thread.start(); + LoggerContext.getContext(false).submitDaemon(new ReconfigurationWorker(listener, reconfigurable)); } } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configurator.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configurator.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configurator.java index e8286c1..3da469d 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configurator.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configurator.java @@ -20,6 +20,7 @@ import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.concurrent.TimeUnit; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; @@ -328,8 +329,15 @@ public final class Configurator { } /** - * Shuts down the given logging context. - * @param ctx the logging context to shut down, may be null. + * Shuts down the given logger context. This request does not wait for Log4j tasks to complete. + * <p> + * Log4j starts threads to perform certain actions like file rollovers; calling this method will not wait until the + * rollover thread is done. When this method returns, these tasks' status are undefined, the tasks may be done or + * not. + * </p> + * + * @param ctx + * the logger context to shut down, may be null. */ public static void shutdown(final LoggerContext ctx) { if (ctx != null) { @@ -337,6 +345,30 @@ public final class Configurator { } } + /** + * Blocks until all Log4j tasks have completed execution after a shutdown request, or the timeout occurs, or the + * current thread is interrupted, whichever happens first. + * <p> + * Log4j can start threads to perform certain actions like file rollovers, calling this method with a timeout will + * block until the rollover thread is done. + * </p> + * + * @param ctx + * the logger context to shut down, may be null. + * @param timeout + * the maximum time to wait + * @param timeUnit + * the time unit of the timeout argument + * @return {@code true} if the logger context terminated and {@code false} if the timeout elapsed before + * termination. + */ + public static boolean shutdown(final LoggerContext ctx, final long timeout, final TimeUnit timeUnit) { + if (ctx != null) { + return ctx.stop(timeout, timeUnit); + } + return true; + } + private Configurator() { // empty } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/Server.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/Server.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/Server.java index 10f343a..2c51758 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/Server.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/Server.java @@ -59,7 +59,7 @@ public final class Server { public static final String DOMAIN = "org.apache.logging.log4j2"; private static final String PROPERTY_DISABLE_JMX = "log4j2.disable.jmx"; private static final String PROPERTY_ASYNC_NOTIF = "log4j2.jmx.notify.async"; - private static final String THREAD_NAME_PREFIX = "log4j2.jmx.notif"; + private static final String THREAD_NAME_PREFIX = "jmx.notif"; private static final StatusLogger LOGGER = StatusLogger.getLogger(); static final Executor executor = isJmxDisabled() ? null : createExecutor(); http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/JmsServer.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/JmsServer.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/JmsServer.java index 752fc13..74a3834 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/JmsServer.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/JmsServer.java @@ -107,6 +107,13 @@ public class JmsServer extends LogEventListener implements MessageListener, Life jmsManager.release(); } + @Override + public boolean stop(long timeout, TimeUnit timeUnit) { + stop(); + return true; + } + + @Override public boolean isStarted() { return state.get() == State.STARTED; } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/main/java/org/apache/logging/log4j/core/util/DefaultShutdownCallbackRegistry.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/DefaultShutdownCallbackRegistry.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/DefaultShutdownCallbackRegistry.java index 45ae6f5..1aab6c7 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/DefaultShutdownCallbackRegistry.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/DefaultShutdownCallbackRegistry.java @@ -24,6 +24,7 @@ import java.util.Collection; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import org.apache.logging.log4j.Logger; @@ -163,6 +164,12 @@ public class DefaultShutdownCallbackRegistry implements ShutdownCallbackRegistry } } + @Override + public boolean stop(long timeout, TimeUnit timeUnit) { + stop(); + return true; + } + private void removeShutdownHook() { final Thread shutdownThread = shutdownHookRef.get(); if (shutdownThread != null) { http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Log4jThreadFactory.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Log4jThreadFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Log4jThreadFactory.java index 333ca0a..2f974e4 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Log4jThreadFactory.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Log4jThreadFactory.java @@ -40,6 +40,17 @@ public class Log4jThreadFactory implements ThreadFactory { return new Log4jThreadFactory(threadNamePrefix, true, Thread.NORM_PRIORITY); } + /** + * Creates a new thread factory. + * + * @param threadNamePrefix + * The thread name prefix. + * @return a new daemon thread factory. + */ + public static Log4jThreadFactory createThreadFactory(final String threadNamePrefix) { + return new Log4jThreadFactory(threadNamePrefix, false, Thread.NORM_PRIORITY); + } + private static final AtomicInteger FACTORY_NUMBER = new AtomicInteger(1); private static final AtomicInteger THREAD_NUMBER = new AtomicInteger(1); private final boolean daemon; http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RandomRollingAppenderOnStartupTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RandomRollingAppenderOnStartupTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RandomRollingAppenderOnStartupTest.java index 2c6fdd3..c24fa50 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RandomRollingAppenderOnStartupTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RandomRollingAppenderOnStartupTest.java @@ -57,7 +57,7 @@ public class RandomRollingAppenderOnStartupTest { public LoggerContextRule loggerContextRule; public RandomRollingAppenderOnStartupTest(final String configFile) { - this.loggerContextRule = new LoggerContextRule(configFile); + this.loggerContextRule = LoggerContextRule.createShutdownTimeoutLoggerContextRule(configFile); } @Before http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronTest.java index 6de7d7d..d04de19 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronTest.java @@ -49,7 +49,7 @@ public class RollingAppenderCronTest { private static final String DIR = "target/rolling-cron"; private static final String FILE = "target/rolling-cron/rollingtest.log"; - private final LoggerContextRule loggerContextRule = new LoggerContextRule(CONFIG); + private final LoggerContextRule loggerContextRule = LoggerContextRule.createShutdownTimeoutLoggerContextRule(CONFIG); @Rule public RuleChain chain = loggerContextRule.withCleanFoldersRule(DIR); http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCustomDeleteActionTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCustomDeleteActionTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCustomDeleteActionTest.java index 2e48ef8..3b30bd8 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCustomDeleteActionTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCustomDeleteActionTest.java @@ -37,7 +37,7 @@ public class RollingAppenderCustomDeleteActionTest { private static final String CONFIG = "log4j-rolling-with-custom-delete.xml"; private static final String DIR = "target/rolling-with-delete/test"; - private final LoggerContextRule loggerContextRule = new LoggerContextRule(CONFIG); + private final LoggerContextRule loggerContextRule = LoggerContextRule.createShutdownTimeoutLoggerContextRule(CONFIG); @Rule public RuleChain chain = loggerContextRule.withCleanFoldersRule(DIR); http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount1Test.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount1Test.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount1Test.java index e2e59e6..23dcffa 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount1Test.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount1Test.java @@ -47,7 +47,7 @@ public class RollingAppenderDeleteAccumulatedCount1Test { private static final String CONFIG = "log4j-rolling-with-custom-delete-accum-count1.xml"; private static final String DIR = "target/rolling-with-delete-accum-count1/test"; - private final LoggerContextRule loggerContextRule = new LoggerContextRule(CONFIG); + private final LoggerContextRule loggerContextRule = LoggerContextRule.createShutdownTimeoutLoggerContextRule(CONFIG); @Rule public RuleChain chain = loggerContextRule.withCleanFoldersRule(DIR); http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount2Test.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount2Test.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount2Test.java index e03c53a..f636275 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount2Test.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount2Test.java @@ -47,7 +47,7 @@ public class RollingAppenderDeleteAccumulatedCount2Test { private static final String CONFIG = "log4j-rolling-with-custom-delete-accum-count2.xml"; private static final String DIR = "target/rolling-with-delete-accum-count2/test"; - private final LoggerContextRule loggerContextRule = new LoggerContextRule(CONFIG); + private final LoggerContextRule loggerContextRule = LoggerContextRule.createShutdownTimeoutLoggerContextRule(CONFIG); @Rule public RuleChain chain = loggerContextRule.withCleanFoldersRule(DIR); http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedSizeTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedSizeTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedSizeTest.java index f6bfee3..f580b79 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedSizeTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedSizeTest.java @@ -37,7 +37,7 @@ public class RollingAppenderDeleteAccumulatedSizeTest { private static final String CONFIG = "log4j-rolling-with-custom-delete-accum-size.xml"; private static final String DIR = "target/rolling-with-delete-accum-size/test"; - private final LoggerContextRule loggerContextRule = new LoggerContextRule(CONFIG); + private final LoggerContextRule loggerContextRule = LoggerContextRule.createShutdownTimeoutLoggerContextRule(CONFIG); @Rule public RuleChain chain = loggerContextRule.withCleanFoldersRule(DIR); http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteMaxDepthTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteMaxDepthTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteMaxDepthTest.java index bef09c4..740f9ec 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteMaxDepthTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteMaxDepthTest.java @@ -44,7 +44,7 @@ public class RollingAppenderDeleteMaxDepthTest { private static final String CONFIG = "log4j-rolling-with-custom-delete-maxdepth.xml"; private static final String DIR = "target/rolling-with-delete-depth/test"; - private final LoggerContextRule loggerContextRule = new LoggerContextRule(CONFIG); + private final LoggerContextRule loggerContextRule = LoggerContextRule.createShutdownTimeoutLoggerContextRule(CONFIG); @Rule public RuleChain chain = loggerContextRule.withCleanFoldersRule(DIR); http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteNestedTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteNestedTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteNestedTest.java index 081a52e..7d335f0 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteNestedTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteNestedTest.java @@ -46,7 +46,7 @@ public class RollingAppenderDeleteNestedTest { private static final String CONFIG = "log4j-rolling-with-custom-delete-nested.xml"; private static final String DIR = "target/rolling-with-delete-nested/test"; - private final LoggerContextRule loggerContextRule = new LoggerContextRule(CONFIG); + private final LoggerContextRule loggerContextRule = LoggerContextRule.createShutdownTimeoutLoggerContextRule(CONFIG); @Rule public RuleChain chain = loggerContextRule.withCleanFoldersRule(DIR); http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptFri13thTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptFri13thTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptFri13thTest.java index a7dcb48..38dca95 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptFri13thTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptFri13thTest.java @@ -36,7 +36,7 @@ public class RollingAppenderDeleteScriptFri13thTest { private static final String CONFIG = "log4j-rolling-with-custom-delete-script-fri13th.xml"; private static final String DIR = "target/rolling-with-delete-script-fri13th/test"; - private final LoggerContextRule loggerContextRule = new LoggerContextRule(CONFIG); + private final LoggerContextRule loggerContextRule = LoggerContextRule.createShutdownTimeoutLoggerContextRule(CONFIG); @Rule public RuleChain chain = loggerContextRule.withCleanFoldersRule(DIR); http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptTest.java index f1c3888..91da1a7 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptTest.java @@ -34,7 +34,7 @@ public class RollingAppenderDeleteScriptTest { private static final String CONFIG = "log4j-rolling-with-custom-delete-script.xml"; private static final String DIR = "target/rolling-with-delete-script/test"; - private final LoggerContextRule loggerContextRule = new LoggerContextRule(CONFIG); + private final LoggerContextRule loggerContextRule = LoggerContextRule.createShutdownTimeoutLoggerContextRule(CONFIG); @Rule public RuleChain chain = loggerContextRule.withCleanFoldersRule(DIR); http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderNoUnconditionalDeleteTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderNoUnconditionalDeleteTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderNoUnconditionalDeleteTest.java index d7834f5..0d34be6 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderNoUnconditionalDeleteTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderNoUnconditionalDeleteTest.java @@ -58,7 +58,7 @@ public class RollingAppenderNoUnconditionalDeleteTest { public RollingAppenderNoUnconditionalDeleteTest(final String configFile, final String dir) { this.directory = new File(dir); - this.loggerContextRule = new LoggerContextRule(configFile); + this.loggerContextRule = LoggerContextRule.createShutdownTimeoutLoggerContextRule(configFile); deleteDir(); deleteDirParent(); } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderOnStartupTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderOnStartupTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderOnStartupTest.java index bc74585..aed2d19 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderOnStartupTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderOnStartupTest.java @@ -57,7 +57,7 @@ public class RollingAppenderOnStartupTest { public LoggerContextRule loggerContextRule; public RollingAppenderOnStartupTest(final String configFile) { - this.loggerContextRule = new LoggerContextRule(configFile); + this.loggerContextRule = LoggerContextRule.createShutdownTimeoutLoggerContextRule(configFile); } @Before http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeTest.java index d354b41..6e73ab3 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeTest.java @@ -94,7 +94,7 @@ public class RollingAppenderSizeTest { public RollingAppenderSizeTest(final String configFile, final String fileExtension, final boolean createOnDemand) { this.fileExtension = fileExtension; this.createOnDemand = createOnDemand; - this.loggerContextRule = new LoggerContextRule(configFile); + this.loggerContextRule = LoggerContextRule.createShutdownTimeoutLoggerContextRule(configFile); this.chain = loggerContextRule.withCleanFoldersRule(DIR); } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTimeAndSizeTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTimeAndSizeTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTimeAndSizeTest.java index bec238e..ad0ea64 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTimeAndSizeTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTimeAndSizeTest.java @@ -38,9 +38,11 @@ import org.junit.rules.RuleChain; */ public class RollingAppenderTimeAndSizeTest { + private static final String CONFIG = "log4j-rolling3.xml"; + private static final String DIR = "target/rolling3/test"; - public static LoggerContextRule loggerContextRule = new LoggerContextRule("log4j-rolling3.xml"); + public static LoggerContextRule loggerContextRule = LoggerContextRule.createShutdownTimeoutLoggerContextRule(CONFIG); @Rule public RuleChain chain = loggerContextRule.withCleanFoldersRule(DIR); http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTimeTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTimeTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTimeTest.java index aa99595..089908d 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTimeTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTimeTest.java @@ -40,7 +40,7 @@ public class RollingAppenderTimeTest { private static final String CONFIG = "log4j-rolling2.xml"; private static final String DIR = "target/rolling2"; - private final LoggerContextRule loggerContextRule = new LoggerContextRule(CONFIG); + private final LoggerContextRule loggerContextRule = LoggerContextRule.createShutdownTimeoutLoggerContextRule(CONFIG); @Rule public RuleChain chain = loggerContextRule.withCleanFoldersRule(DIR); http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerHeaderFooterTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerHeaderFooterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerHeaderFooterTest.java index af668d8..6734d6b 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerHeaderFooterTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerHeaderFooterTest.java @@ -39,10 +39,11 @@ import org.junit.rules.RuleChain; */ public class RollingRandomAccessFileManagerHeaderFooterTest { + private static final String CONFIG = "RollingRandomAccessFileAppenderHeaderFooterTest.xml"; private static final String DIR = "target/RollingRandomAccessFileAppenderHeaderFooterTest/"; private static final String LOGFILE = "target/RollingRandomAccessFileAppenderHeaderFooterTest.log"; - public LoggerContextRule loggerContextRule = new LoggerContextRule("RollingRandomAccessFileAppenderHeaderFooterTest.xml"); + public LoggerContextRule loggerContextRule = LoggerContextRule.createShutdownTimeoutLoggerContextRule(CONFIG); @Rule public RuleChain chain = loggerContextRule.withCleanFoldersRule(DIR); http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3f92f7cc/log4j-core/src/test/java/org/apache/logging/log4j/junit/LoggerContextRule.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/junit/LoggerContextRule.java b/log4j-core/src/test/java/org/apache/logging/log4j/junit/LoggerContextRule.java index 697e119..c3aaef9 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/junit/LoggerContextRule.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/junit/LoggerContextRule.java @@ -18,6 +18,8 @@ package org.apache.logging.log4j.junit; import static org.junit.Assert.assertNotNull; +import java.util.concurrent.TimeUnit; + import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.Appender; import org.apache.logging.log4j.core.Logger; @@ -41,12 +43,18 @@ import org.junit.runners.model.Statement; */ public class LoggerContextRule implements TestRule { + public static LoggerContextRule createShutdownTimeoutLoggerContextRule(String config) { + return new LoggerContextRule(config, 10, TimeUnit.SECONDS); + } + private static final String SYS_PROP_KEY_CLASS_NAME = "org.apache.logging.log4j.junit.LoggerContextRule#ClassName"; private static final String SYS_PROP_KEY_DISPLAY_NAME = "org.apache.logging.log4j.junit.LoggerContextRule#DisplayName"; private final String configLocation; private LoggerContext context; private Class<? extends ContextSelector> contextSelectorClass; private String testClassName; + private long shutdownTimeout; + private TimeUnit shutdownTimeUnit; /** * Constructs a new LoggerContextRule for a given configuration file. @@ -65,11 +73,21 @@ public class LoggerContextRule implements TestRule { * path to configuration file * @param contextSelectorClass * custom ContextSelector class to use instead of default - * @since 2.5 */ public LoggerContextRule(final String configLocation, final Class<? extends ContextSelector> contextSelectorClass) { + this(configLocation, contextSelectorClass, 0, null); + } + + public LoggerContextRule(final String configLocation, final Class<? extends ContextSelector> contextSelectorClass, + final long shutdownTimeout, final TimeUnit shutdownTimeUnit) { this.configLocation = configLocation; this.contextSelectorClass = contextSelectorClass; + this.shutdownTimeout = shutdownTimeout; + this.shutdownTimeUnit = shutdownTimeUnit; + } + + public LoggerContextRule(String config, int shutdownTimeout, TimeUnit shutdownTimeUnit) { + this(config, null, shutdownTimeout, shutdownTimeUnit); } @Override @@ -94,7 +112,10 @@ public class LoggerContextRule implements TestRule { try { base.evaluate(); } finally { - Configurator.shutdown(context); + if (!Configurator.shutdown(context, shutdownTimeout, shutdownTimeUnit)) { + StatusLogger.getLogger().error("Logger context {} did not shutdown completely after {} {}.", + context.getName(), shutdownTimeout, shutdownTimeUnit); + } context = null; contextSelectorClass = null; StatusLogger.getLogger().reset();