You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by gg...@apache.org on 2016/08/26 19:00:56 UTC

[1/5] logging-log4j2 git commit: Create branch for [LOG4J2-1539].

Repository: logging-log4j2
Updated Branches:
  refs/heads/master 2cfc94b9e -> b1acc7f7b


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/master
Commit: 3f92f7cc11f4f7f9a36784f4bdc5380ebbb27c5c
Parents: 7eba2e9
Author: Gary Gregory <gg...@apache.org>
Authored: Mon Aug 22 16:50:01 2016 -0700
Committer: Gary Gregory <gg...@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();


[3/5] logging-log4j2 git commit: Merge remote-tracking branch 'origin/master' into LOG4J2-1539

Posted by gg...@apache.org.
Merge remote-tracking branch 'origin/master' into 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/a4ef9a1d
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/a4ef9a1d
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/a4ef9a1d

Branch: refs/heads/master
Commit: a4ef9a1de092e8f4748716e62dff0d6972c1bcb1
Parents: d18e9c9 29e7bfd
Author: Gary Gregory <gg...@apache.org>
Authored: Thu Aug 25 14:43:20 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Thu Aug 25 14:43:20 2016 -0700

----------------------------------------------------------------------
 .../config/Log4j1ConfigurationFactory.java      |    9 +-
 .../log4j/config/Log4j1ConfigurationParser.java |  210 ++--
 .../apache/log4j/BasicConfigurationFactory.java |   13 +-
 .../config/Log4j1ConfigurationFactoryTest.java  |   29 +-
 ...g4j-console-EnhancedPatternLayout.properties |    1 -
 .../log4j-console-HtmlLayout.properties         |    1 -
 .../log4j-console-PatternLayout.properties      |    1 -
 .../log4j-console-SimpleLayout.properties       |    1 -
 .../log4j-console-TTCCLayout.properties         |    1 -
 .../log4j-console-XmlLayout.properties          |    1 -
 .../log4j-file-SimpleLayout.properties          |   17 +
 .../logging/log4j/core/LoggerContext.java       |    2 +-
 .../core/config/AbstractConfiguration.java      |   15 +-
 .../log4j/core/config/Configuration.java        |    8 +
 .../log4j/core/config/ConfigurationFactory.java | 1113 +++++++++---------
 .../core/config/ConfigurationScheduler.java     |    2 +-
 .../log4j/core/config/DefaultConfiguration.java |    2 +-
 .../log4j/core/config/NullConfiguration.java    |    2 +-
 .../builder/api/ConfigurationBuilder.java       |    8 +
 .../config/builder/impl/BuiltConfiguration.java |    5 +-
 .../impl/DefaultConfigurationBuilder.java       |   29 +-
 .../composite/CompositeConfiguration.java       |    4 +-
 .../core/config/json/JsonConfiguration.java     |   14 +-
 .../config/json/JsonConfigurationFactory.java   |    5 +-
 .../core/config/plugins/util/ResolverUtil.java  |   11 +-
 .../properties/PropertiesConfiguration.java     |    8 +-
 .../PropertiesConfigurationBuilder.java         |   16 +-
 .../PropertiesConfigurationFactory.java         |   10 +-
 .../log4j/core/config/xml/XmlConfiguration.java |    7 +-
 .../config/xml/XmlConfigurationFactory.java     |    5 +-
 .../core/config/yaml/YamlConfiguration.java     |    7 +-
 .../config/yaml/YamlConfigurationFactory.java   |    5 +-
 .../log4j/core/impl/Log4jContextFactory.java    |    6 +-
 .../log4j/core/jmx/LoggerContextAdmin.java      |    4 +-
 .../apache/logging/log4j/core/jmx/Server.java   |    4 +
 .../core/net/server/AbstractSocketServer.java   |    7 +-
 .../log4j/core/BasicConfigurationFactory.java   |    6 +-
 .../RollingAppenderCronOnceADayTest.java        |  128 ++
 .../log4j/core/config/ConfigurationTest.java    |    6 +
 .../builder/CustomConfigurationFactory.java     |   11 +-
 .../plugins/util/PluginManagerPackagesTest.java |    2 +-
 .../util/ResolverUtilCustomProtocolTest.java    |  208 ++++
 .../config/plugins/util/ResolverUtilTest.java   |  146 ++-
 .../junit/URLStreamHandlerFactoryRule.java      |   96 ++
 .../resources/log4j-rolling-cron-once-a-day.xml |   47 +
 .../src/test/resources/log4j-rolling-cron.xml   |    2 +-
 .../src/test/resources/log4j-rolling-cron2.xml  |    2 +-
 .../configuration/CustomConfiguration.java      |   13 +-
 .../CustomConfigurationFactory.java             |   12 +-
 src/changes/changes.xml                         |    8 +-
 50 files changed, 1464 insertions(+), 806 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/a4ef9a1d/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/a4ef9a1d/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationScheduler.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/a4ef9a1d/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/Server.java
----------------------------------------------------------------------


[2/5] logging-log4j2 git commit: Merge remote-tracking branch 'origin/master' into LOG4J2-1539

Posted by gg...@apache.org.
Merge remote-tracking branch 'origin/master' into 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/d18e9c95
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/d18e9c95
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/d18e9c95

Branch: refs/heads/master
Commit: d18e9c951723fe1908f4a9d3c8078ddb18d0ef03
Parents: 3f92f7c 30ea283
Author: Gary Gregory <gg...@apache.org>
Authored: Tue Aug 23 21:13:34 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Tue Aug 23 21:13:34 2016 -0700

----------------------------------------------------------------------
 .../logging/log4j/core/LoggerContext.java       | 26 ++++++++-----
 .../log4j/core/appender/FileAppender.java       |  4 +-
 .../core/appender/RollingFileAppender.java      |  4 +-
 .../core/config/AbstractConfiguration.java      | 27 ++++++-------
 .../log4j/core/config/AppenderControl.java      |  3 +-
 .../logging/log4j/core/config/LoggerConfig.java | 36 +-----------------
 .../config/plugins/PluginBuilderFactory.java    |  1 +
 .../config/plugins/PluginConfiguration.java     |  1 +
 .../core/config/plugins/PluginFactory.java      |  2 +-
 .../log4j/core/config/plugins/PluginNode.java   |  1 +
 .../core/config/plugins/util/PluginBuilder.java |  2 -
 .../config/plugins/util/PluginRegistry.java     |  1 -
 .../core/config/plugins/util/ResolverUtil.java  |  8 +++-
 .../log4j/core/config/xml/XmlConfiguration.java | 40 ++++++++++----------
 .../apache/logging/log4j/core/jmx/Server.java   |  8 +++-
 .../log4j/core/script/ScriptManager.java        |  1 -
 .../apache/logging/log4j/core/util/Assert.java  | 38 -------------------
 .../logging/log4j/core/util/Constants.java      | 11 ------
 .../core/appender/OutputStreamAppenderTest.java |  2 +-
 .../rolling/RollingFileAppenderAccessTest.java  |  2 +-
 .../config/plugins/util/ResolverUtilTest.java   | 20 ++++++++++
 .../org/apache/logging/log4j/web/WebLookup.java |  8 ----
 src/changes/changes.xml                         | 30 +++++++++++++++
 23 files changed, 126 insertions(+), 150 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d18e9c95/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d18e9c95/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/Server.java
----------------------------------------------------------------------


[4/5] logging-log4j2 git commit: Merge remote-tracking branch 'origin/master' into LOG4J2-1539

Posted by gg...@apache.org.
Merge remote-tracking branch 'origin/master' into LOG4J2-1539

Conflicts:
	log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/01f59e46
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/01f59e46
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/01f59e46

Branch: refs/heads/master
Commit: 01f59e4640b78f251813d712cc011686907de557
Parents: a4ef9a1 2cfc94b
Author: Gary Gregory <gg...@apache.org>
Authored: Fri Aug 26 10:05:21 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Fri Aug 26 10:05:21 2016 -0700

----------------------------------------------------------------------
 .../config/Log4j1ConfigurationFactory.java      |  2 +-
 .../apache/log4j/BasicConfigurationFactory.java |  4 +-
 .../log4j/core/appender/AbstractManager.java    | 15 ++++--
 .../core/appender/ConfigurationFactoryData.java | 50 ++++++++++++++++++++
 .../log4j/core/appender/ConsoleAppender.java    |  4 --
 .../log4j/core/appender/FileAppender.java       | 12 ++---
 .../log4j/core/appender/FileManager.java        | 30 +++++++-----
 .../core/appender/OutputStreamManager.java      | 12 ++---
 .../core/appender/RandomAccessFileAppender.java |  2 +-
 .../core/appender/RandomAccessFileManager.java  | 27 ++++++-----
 .../core/appender/RollingFileAppender.java      | 16 +++----
 .../RollingRandomAccessFileAppender.java        |  2 +-
 .../log4j/core/appender/WriterManager.java      |  2 +-
 .../appender/db/AbstractDatabaseManager.java    |  2 +-
 .../log4j/core/appender/mom/JmsManager.java     |  2 +-
 .../core/appender/mom/jeromq/JeroMqManager.java |  2 +-
 .../core/appender/mom/kafka/KafkaManager.java   |  2 +-
 .../appender/rolling/RollingFileManager.java    | 32 +++++++------
 .../rolling/RollingRandomAccessFileManager.java | 32 ++++++++-----
 .../log4j/core/config/ConfigurationFactory.java |  4 +-
 .../composite/CompositeConfiguration.java       |  2 +-
 .../config/xml/XmlConfigurationFactory.java     |  1 +
 .../config/yaml/YamlConfigurationFactory.java   |  2 +-
 .../logging/log4j/core/net/JndiManager.java     |  2 +-
 .../logging/log4j/core/net/SmtpManager.java     |  2 +-
 .../log4j/core/BasicConfigurationFactory.java   |  4 +-
 .../appender/RandomAccessFileManagerTest.java   | 18 +++----
 .../rolling/OnStartupTriggeringPolicyTest.java  |  2 +-
 .../RollingRandomAccessFileManagerTest.java     | 24 +++++-----
 .../builder/CustomConfigurationFactory.java     |  6 +--
 .../flume/appender/AbstractFlumeManager.java    |  2 +-
 .../CustomConfigurationFactory.java             |  4 +-
 src/changes/changes.xml                         |  3 ++
 src/site/xdoc/manual/customconfig.xml           | 10 ++--
 src/site/xdoc/manual/extending.xml              |  8 ++--
 35 files changed, 214 insertions(+), 130 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/01f59e46/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/kafka/KafkaManager.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/01f59e46/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
----------------------------------------------------------------------
diff --cc log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
index 3fcf864,b741b4e..3f8ba2a
--- 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
@@@ -33,7 -33,9 +34,8 @@@ import org.apache.logging.log4j.core.ap
  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.config.Configuration;
  import org.apache.logging.log4j.core.util.Constants;
 -import org.apache.logging.log4j.core.util.Log4jThread;
  
  /**
   * The Rolling File Manager.


[5/5] logging-log4j2 git commit: [LOG4J2-1540] The Core AbstractManager should track its LoggerContext. Update Kafka support.

Posted by gg...@apache.org.
[LOG4J2-1540] The Core AbstractManager should track its LoggerContext.
Update Kafka support.

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/b1acc7f7
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/b1acc7f7
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/b1acc7f7

Branch: refs/heads/master
Commit: b1acc7f7b15daa5c6ad686a9e26413a204bee3fc
Parents: 01f59e4
Author: Gary Gregory <gg...@apache.org>
Authored: Fri Aug 26 10:09:01 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Fri Aug 26 10:09:01 2016 -0700

----------------------------------------------------------------------
 .../logging/log4j/core/appender/mom/kafka/KafkaAppender.java  | 7 +++++--
 .../logging/log4j/core/appender/mom/kafka/KafkaManager.java   | 5 +++--
 2 files changed, 8 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b1acc7f7/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/kafka/KafkaAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/kafka/KafkaAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/kafka/KafkaAppender.java
index 8619f3d..81879e7 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/kafka/KafkaAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/kafka/KafkaAppender.java
@@ -26,10 +26,12 @@ import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.appender.AbstractAppender;
 import org.apache.logging.log4j.core.appender.AppenderLoggingException;
+import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.Node;
 import org.apache.logging.log4j.core.config.Property;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
 import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
 import org.apache.logging.log4j.core.config.plugins.PluginElement;
 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
 import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
@@ -49,8 +51,9 @@ public final class KafkaAppender extends AbstractAppender {
             @Required(message = "No name provided for KafkaAppender") @PluginAttribute("name") final String name,
             @PluginAttribute(value = "ignoreExceptions", defaultBoolean = true) final boolean ignoreExceptions,
             @Required(message = "No topic provided for KafkaAppender") @PluginAttribute("topic") final String topic,
-            @PluginElement("Properties") final Property[] properties) {
-        final KafkaManager kafkaManager = new KafkaManager(name, topic, properties);
+            @PluginElement("Properties") final Property[] properties,
+            @PluginConfiguration final Configuration configuration) {
+        final KafkaManager kafkaManager = new KafkaManager(configuration.getLoggerContext(), name, topic, properties);
         return new KafkaAppender(name, layout, filter, ignoreExceptions, kafkaManager);
     }
 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b1acc7f7/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 d138c93..35aafb7 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
@@ -24,6 +24,7 @@ import java.util.concurrent.TimeoutException;
 
 import org.apache.kafka.clients.producer.Producer;
 import org.apache.kafka.clients.producer.ProducerRecord;
+import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.appender.AbstractManager;
 import org.apache.logging.log4j.core.config.Property;
 
@@ -42,8 +43,8 @@ public class KafkaManager extends AbstractManager {
 
     private final String topic;
 
-    public KafkaManager(final String name, final String topic, final Property[] properties) {
-        super(null, name);
+    public KafkaManager(LoggerContext loggerContext, final String name, final String topic, final Property[] properties) {
+        super(loggerContext, name);
         this.topic = topic;
         config.setProperty("key.serializer", "org.apache.kafka.common.serialization.ByteArraySerializer");
         config.setProperty("value.serializer", "org.apache.kafka.common.serialization.ByteArraySerializer");