You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ma...@apache.org on 2014/05/18 20:40:54 UTC

svn commit: r1595653 [3/11] - in /logging/log4j/log4j2/branches/experimental: ./ log4j-1.2-api/src/main/java/org/apache/log4j/ log4j-1.2-api/src/test/java/org/apache/log4j/ log4j-api/ log4j-api/src/main/java/org/apache/logging/log4j/ log4j-api/src/main...

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RandomAccessFileManager.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RandomAccessFileManager.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RandomAccessFileManager.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RandomAccessFileManager.java Sun May 18 18:40:48 2014
@@ -52,8 +52,6 @@ public class RandomAccessFileManager ext
         this.randomAccessFile = file;
         this.advertiseURI = advertiseURI;
         this.isEndOfBatch.set(Boolean.FALSE);
-
-        // TODO make buffer size configurable?
         this.buffer = ByteBuffer.allocate(bufferSize);
     }
 
@@ -136,6 +134,14 @@ public class RandomAccessFileManager ext
     public String getFileName() {
         return getName();
     }
+    
+    /**
+     * Returns the buffer capacity.
+     * @return the buffer size
+     */
+    public int getBufferSize() {
+        return buffer.capacity();
+    }
 
     /** {@code OutputStream} subclass that does not write anything. */
     static class DummyOutputStream extends OutputStream {

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java Sun May 18 18:40:48 2014
@@ -34,9 +34,9 @@ import org.apache.logging.log4j.core.con
 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.helpers.Booleans;
 import org.apache.logging.log4j.core.layout.PatternLayout;
 import org.apache.logging.log4j.core.net.Advertiser;
+import org.apache.logging.log4j.core.util.Booleans;
 
 /**
  * An appender that writes to files and can roll over at intervals.

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingRandomAccessFileAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingRandomAccessFileAppender.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingRandomAccessFileAppender.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingRandomAccessFileAppender.java Sun May 18 18:40:48 2014
@@ -25,8 +25,8 @@ import org.apache.logging.log4j.core.Fil
 import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy;
-import org.apache.logging.log4j.core.appender.rolling.RollingRandomAccessFileManager;
 import org.apache.logging.log4j.core.appender.rolling.RollingFileManager;
+import org.apache.logging.log4j.core.appender.rolling.RollingRandomAccessFileManager;
 import org.apache.logging.log4j.core.appender.rolling.RolloverStrategy;
 import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy;
 import org.apache.logging.log4j.core.config.Configuration;
@@ -35,9 +35,10 @@ import org.apache.logging.log4j.core.con
 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.helpers.Booleans;
 import org.apache.logging.log4j.core.layout.PatternLayout;
 import org.apache.logging.log4j.core.net.Advertiser;
+import org.apache.logging.log4j.core.util.Booleans;
+import org.apache.logging.log4j.core.util.Integers;
 
 /**
  * An appender that writes to random access files and can roll over at
@@ -54,11 +55,10 @@ public final class RollingRandomAccessFi
     private RollingRandomAccessFileAppender(final String name, final Layout<? extends Serializable> layout,
             final Filter filter, final RollingFileManager manager, final String fileName,
             final String filePattern, final boolean ignoreExceptions,
-            final boolean immediateFlush, final Advertiser advertiser) {
+            final boolean immediateFlush, final int bufferSize, final Advertiser advertiser) {
         super(name, layout, filter, ignoreExceptions, immediateFlush, manager);
         if (advertiser != null) {
-            final Map<String, String> configuration = new HashMap<String, String>(
-                    layout.getContentFormat());
+            final Map<String, String> configuration = new HashMap<String, String>(layout.getContentFormat());
             configuration.put("contentType", layout.getContentType());
             configuration.put("name", name);
             advertisement = advertiser.advertise(configuration);
@@ -113,6 +113,14 @@ public final class RollingRandomAccessFi
     public String getFilePattern() {
         return filePattern;
     }
+    
+    /**
+     * Returns the size of the file manager's buffer.
+     * @return the buffer size
+     */
+    public int getBufferSize() {
+        return ((RollingRandomAccessFileManager) getManager()).getBufferSize();
+    }
 
     /**
      * Create a RollingRandomAccessFileAppender.
@@ -126,6 +134,7 @@ public final class RollingRandomAccessFi
      * @param name The name of the Appender (required).
      * @param immediateFlush When true, events are immediately flushed. Defaults
      *            to "true".
+     * @param bufferSizeStr The buffer size, defaults to {@value RollingRandomAccessFileManager#DEFAULT_BUFFER_SIZE}.
      * @param policy The triggering policy. (required).
      * @param strategy The rollover strategy. Defaults to
      *            DefaultRolloverStrategy.
@@ -147,6 +156,7 @@ public final class RollingRandomAccessFi
             @PluginAttribute("append") final String append,
             @PluginAttribute("name") final String name,
             @PluginAttribute("immediateFlush") final String immediateFlush,
+            @PluginAttribute("bufferSize") final String bufferSizeStr,
             @PluginElement("Policy") final TriggeringPolicy policy,
             @PluginElement("Strategy") RolloverStrategy strategy,
             @PluginElement("Layout") Layout<? extends Serializable> layout,
@@ -160,6 +170,7 @@ public final class RollingRandomAccessFi
         final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true);
         final boolean isFlush = Booleans.parseBoolean(immediateFlush, true);
         final boolean isAdvertise = Boolean.parseBoolean(advertise);
+        final int bufferSize = Integers.parseInt(bufferSizeStr, RollingRandomAccessFileManager.DEFAULT_BUFFER_SIZE);
 
         if (name == null) {
             LOGGER.error("No name provided for FileAppender");
@@ -167,14 +178,12 @@ public final class RollingRandomAccessFi
         }
 
         if (fileName == null) {
-            LOGGER.error("No filename was provided for FileAppender with name "
-                    + name);
+            LOGGER.error("No filename was provided for FileAppender with name " + name);
             return null;
         }
 
         if (filePattern == null) {
-            LOGGER.error("No filename pattern provided for FileAppender with name "
-                    + name);
+            LOGGER.error("No filename pattern provided for FileAppender with name " + name);
             return null;
         }
 
@@ -192,15 +201,14 @@ public final class RollingRandomAccessFi
             layout = PatternLayout.createLayout(null, null, null, null, null, null, null, null);
         }
 
-
-        final RollingRandomAccessFileManager manager = RollingRandomAccessFileManager.getRollingRandomAccessFileManager(fileName, filePattern,
-            isAppend, isFlush, policy, strategy, advertiseURI, layout);
+        final RollingRandomAccessFileManager manager = RollingRandomAccessFileManager.getRollingRandomAccessFileManager(
+                fileName, filePattern, isAppend, isFlush, bufferSize, policy, strategy, advertiseURI, layout);
         if (manager == null) {
             return null;
         }
 
         return new RollingRandomAccessFileAppender(name, layout, filter, manager,
-                fileName, filePattern, ignoreExceptions, isFlush,
+                fileName, filePattern, ignoreExceptions, isFlush, bufferSize,
                 isAdvertise ? config.getAdvertiser() : null);
     }
 }

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SMTPAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SMTPAppender.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SMTPAppender.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SMTPAppender.java Sun May 18 18:40:48 2014
@@ -27,9 +27,9 @@ import org.apache.logging.log4j.core.con
 import org.apache.logging.log4j.core.config.plugins.PluginElement;
 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
 import org.apache.logging.log4j.core.filter.ThresholdFilter;
-import org.apache.logging.log4j.core.helpers.Booleans;
 import org.apache.logging.log4j.core.layout.HTMLLayout;
 import org.apache.logging.log4j.core.net.SMTPManager;
+import org.apache.logging.log4j.core.util.Booleans;
 
 /**
  * Send an e-mail when a specific logging event occurs, typically on errors or

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SocketAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SocketAppender.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SocketAppender.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SocketAppender.java Sun May 18 18:40:48 2014
@@ -28,13 +28,13 @@ import org.apache.logging.log4j.core.con
 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.helpers.Booleans;
 import org.apache.logging.log4j.core.layout.SerializedLayout;
 import org.apache.logging.log4j.core.net.AbstractSocketManager;
 import org.apache.logging.log4j.core.net.Advertiser;
 import org.apache.logging.log4j.core.net.DatagramSocketManager;
 import org.apache.logging.log4j.core.net.Protocol;
 import org.apache.logging.log4j.core.net.TCPSocketManager;
+import org.apache.logging.log4j.core.util.Booleans;
 import org.apache.logging.log4j.util.EnglishEnums;
 
 /**

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SyslogAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SyslogAppender.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SyslogAppender.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SyslogAppender.java Sun May 18 18:40:48 2014
@@ -26,13 +26,13 @@ import org.apache.logging.log4j.core.con
 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.helpers.Booleans;
 import org.apache.logging.log4j.core.layout.LoggerFields;
 import org.apache.logging.log4j.core.layout.RFC5424Layout;
 import org.apache.logging.log4j.core.layout.SyslogLayout;
 import org.apache.logging.log4j.core.net.AbstractSocketManager;
 import org.apache.logging.log4j.core.net.Advertiser;
 import org.apache.logging.log4j.core.net.Protocol;
+import org.apache.logging.log4j.core.util.Booleans;
 import org.apache.logging.log4j.util.EnglishEnums;
 
 /**

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/TLSSyslogAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/TLSSyslogAppender.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/TLSSyslogAppender.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/TLSSyslogAppender.java Sun May 18 18:40:48 2014
@@ -20,7 +20,6 @@ import org.apache.logging.log4j.core.Fil
 import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.plugins.*;
-import org.apache.logging.log4j.core.helpers.Booleans;
 import org.apache.logging.log4j.core.layout.LoggerFields;
 import org.apache.logging.log4j.core.layout.RFC5424Layout;
 import org.apache.logging.log4j.core.layout.SyslogLayout;
@@ -28,6 +27,7 @@ import org.apache.logging.log4j.core.net
 import org.apache.logging.log4j.core.net.Advertiser;
 import org.apache.logging.log4j.core.net.TLSSocketManager;
 import org.apache.logging.log4j.core.net.ssl.SSLConfiguration;
+import org.apache.logging.log4j.core.util.Booleans;
 
 import java.io.Serializable;
 

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/ColumnConfig.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/ColumnConfig.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/ColumnConfig.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/ColumnConfig.java Sun May 18 18:40:48 2014
@@ -22,10 +22,10 @@ import org.apache.logging.log4j.core.con
 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.PluginFactory;
-import org.apache.logging.log4j.core.helpers.Booleans;
-import org.apache.logging.log4j.core.helpers.Strings;
 import org.apache.logging.log4j.core.layout.PatternLayout;
+import org.apache.logging.log4j.core.util.Booleans;
 import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.Strings;
 
 /**
  * A configuration element used to configure which event properties are logged to which columns in the database table.

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/DataSourceConnectionSource.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/DataSourceConnectionSource.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/DataSourceConnectionSource.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/DataSourceConnectionSource.java Sun May 18 18:40:48 2014
@@ -27,8 +27,8 @@ import org.apache.logging.log4j.Logger;
 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.PluginFactory;
-import org.apache.logging.log4j.core.helpers.Strings;
 import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.Strings;
 
 /**
  * A {@link JDBCAppender} connection source that uses a {@link DataSource} to connect to the database.

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/FactoryMethodConnectionSource.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/FactoryMethodConnectionSource.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/FactoryMethodConnectionSource.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/FactoryMethodConnectionSource.java Sun May 18 18:40:48 2014
@@ -27,9 +27,9 @@ import org.apache.logging.log4j.Logger;
 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.PluginFactory;
-import org.apache.logging.log4j.core.helpers.Loader;
-import org.apache.logging.log4j.core.helpers.Strings;
+import org.apache.logging.log4j.core.util.Loader;
 import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.Strings;
 
 /**
  * A {@link JDBCAppender} connection source that uses a public static factory method to obtain a {@link Connection} or

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/JDBCAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/JDBCAppender.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/JDBCAppender.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/JDBCAppender.java Sun May 18 18:40:48 2014
@@ -23,7 +23,7 @@ import org.apache.logging.log4j.core.con
 import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginElement;
 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
-import org.apache.logging.log4j.core.helpers.Booleans;
+import org.apache.logging.log4j.core.util.Booleans;
 
 /**
  * This Appender writes logging events to a relational database using standard JDBC mechanisms. It takes a list of

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/JDBCDatabaseManager.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/JDBCDatabaseManager.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/JDBCDatabaseManager.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/JDBCDatabaseManager.java Sun May 18 18:40:48 2014
@@ -28,8 +28,8 @@ import org.apache.logging.log4j.core.Log
 import org.apache.logging.log4j.core.appender.AppenderLoggingException;
 import org.apache.logging.log4j.core.appender.ManagerFactory;
 import org.apache.logging.log4j.core.appender.db.AbstractDatabaseManager;
-import org.apache.logging.log4j.core.helpers.Closer;
 import org.apache.logging.log4j.core.layout.PatternLayout;
+import org.apache.logging.log4j.core.util.Closer;
 
 /**
  * An {@link AbstractDatabaseManager} implementation for relational databases accessed via JDBC.
@@ -90,7 +90,7 @@ public final class JDBCDatabaseManager e
             int i = 1;
             for (final Column column : this.columns) {
                 if (column.isEventTimestamp) {
-                    this.statement.setTimestamp(i++, new Timestamp(event.getMillis()));
+                    this.statement.setTimestamp(i++, new Timestamp(event.getTimeMillis()));
                 } else {
                     if (column.isClob) {
                         reader = new StringReader(column.layout.toSerializable(event));

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/AbstractLogEventWrapperEntity.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/AbstractLogEventWrapperEntity.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/AbstractLogEventWrapperEntity.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/AbstractLogEventWrapperEntity.java Sun May 18 18:40:48 2014
@@ -26,6 +26,7 @@ import javax.persistence.Transient;
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.Marker;
 import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.core.AbstractLogEvent;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.message.Message;
 
@@ -171,7 +172,7 @@ public abstract class AbstractLogEventWr
      * @param millis Ignored.
      */
     @SuppressWarnings("unused")
-    public void setMillis(final long millis) {
+    public void setTimeMillis(final long millis) {
         // this entity is write-only
     }
 
@@ -211,7 +212,7 @@ public abstract class AbstractLogEventWr
      * @param fqcn Ignored.
      */
     @SuppressWarnings("unused")
-    public void setFQCN(final String fqcn) {
+    public void setLoggerFQCN(final String fqcn) {
         // this entity is write-only
     }
 
@@ -253,82 +254,9 @@ public abstract class AbstractLogEventWr
      * A no-op log event class to prevent {@code NullPointerException}s. O/RMs tend to create instances of entities in
      * order to "play around" with them.
      */
-    private static class NullLogEvent implements LogEvent {
-        private static final long serialVersionUID = 1L;
-
-        @Override
-        public Level getLevel() {
-            return null;
-        }
-
-        @Override
-        public String getLoggerName() {
-            return null;
-        }
-
-        @Override
-        public StackTraceElement getSource() {
-            return null;
-        }
-
-        @Override
-        public Message getMessage() {
-            return null;
-        }
-
-        @Override
-        public Marker getMarker() {
-            return null;
-        }
-
-        @Override
-        public String getThreadName() {
-            return null;
-        }
-
-        @Override
-        public long getMillis() {
-            return 0;
-        }
-
-        @Override
-        public Throwable getThrown() {
-            return null;
-        }
+    private static class NullLogEvent extends AbstractLogEvent {
 
-        @Override
-        public Map<String, String> getContextMap() {
-            return null;
-        }
-
-        @Override
-        public ThreadContext.ContextStack getContextStack() {
-            return null;
-        }
-
-        @Override
-        public String getFQCN() {
-            return null;
-        }
-
-        @Override
-        public boolean isIncludeLocation() {
-            return false;
-        }
-
-        @Override
-        public void setIncludeLocation(final boolean locationRequired) {
-
-        }
-
-        @Override
-        public boolean isEndOfBatch() {
-            return false;
-        }
-
-        @Override
-        public void setEndOfBatch(final boolean endOfBatch) {
-
-        }
+        private static final long serialVersionUID = 1L;
+    	// Inherits everything
     }
 }

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/BasicLogEventEntity.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/BasicLogEventEntity.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/BasicLogEventEntity.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/BasicLogEventEntity.java Sun May 18 18:40:48 2014
@@ -17,9 +17,11 @@
 package org.apache.logging.log4j.core.appender.db.jpa;
 
 import java.util.Map;
+
 import javax.persistence.Basic;
 import javax.persistence.Convert;
 import javax.persistence.MappedSuperclass;
+import javax.persistence.Transient;
 
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.Marker;
@@ -32,6 +34,7 @@ import org.apache.logging.log4j.core.app
 import org.apache.logging.log4j.core.appender.db.jpa.converter.MessageAttributeConverter;
 import org.apache.logging.log4j.core.appender.db.jpa.converter.StackTraceElementAttributeConverter;
 import org.apache.logging.log4j.core.appender.db.jpa.converter.ThrowableAttributeConverter;
+import org.apache.logging.log4j.core.impl.ThrowableProxy;
 import org.apache.logging.log4j.message.Message;
 
 /**
@@ -162,8 +165,8 @@ public abstract class BasicLogEventEntit
      */
     @Override
     @Basic
-    public long getMillis() {
-        return this.getWrappedEvent().getMillis();
+    public long getTimeMillis() {
+        return this.getWrappedEvent().getTimeMillis();
     }
 
     /**
@@ -179,6 +182,18 @@ public abstract class BasicLogEventEntit
     }
 
     /**
+     * Gets the exception logged. Annotated with {@code @Convert(converter = ThrowableAttributeConverter.class)}.
+     *
+     * @return the exception logged.
+     * @see ThrowableAttributeConverter
+     */
+    @Override
+    @Transient
+    public ThrowableProxy getThrownProxy() {
+        return this.getWrappedEvent().getThrownProxy();
+    }
+
+    /**
      * Gets the context map. Annotated with {@code @Convert(converter = ContextMapAttributeConverter.class)}.
      *
      * @return the context map.
@@ -192,6 +207,18 @@ public abstract class BasicLogEventEntit
     }
 
     /**
+     * Gets the value at the given key in the context map.
+     * 
+     * @param key the key to query
+     * @return the value to which the specified key is mapped, or {@code null} if this map contains no mapping for the key or there is no
+     *         map.
+     */
+    @Override
+    public String getContextMap(String key) {
+        return this.getWrappedEvent().getContextMap(key);
+    }
+
+    /**
      * Gets the context stack. Annotated with {@code @Convert(converter = ContextStackAttributeConverter.class)}.
      *
      * @return the context stack.
@@ -211,7 +238,7 @@ public abstract class BasicLogEventEntit
      */
     @Override
     @Basic
-    public String getFQCN() {
-        return this.getWrappedEvent().getFQCN();
+    public String getLoggerFQCN() {
+        return this.getWrappedEvent().getLoggerFQCN();
     }
 }

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/JPAAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/JPAAppender.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/JPAAppender.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/JPAAppender.java Sun May 18 18:40:48 2014
@@ -26,9 +26,9 @@ import org.apache.logging.log4j.core.con
 import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginElement;
 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
-import org.apache.logging.log4j.core.helpers.Booleans;
-import org.apache.logging.log4j.core.helpers.Loader;
-import org.apache.logging.log4j.core.helpers.Strings;
+import org.apache.logging.log4j.core.util.Booleans;
+import org.apache.logging.log4j.core.util.Loader;
+import org.apache.logging.log4j.util.Strings;
 
 /**
  * This Appender writes logging events to a relational database using the Java Persistence API. It requires a

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextMapJsonAttributeConverter.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextMapJsonAttributeConverter.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextMapJsonAttributeConverter.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextMapJsonAttributeConverter.java Sun May 18 18:40:48 2014
@@ -23,7 +23,7 @@ import javax.persistence.AttributeConver
 import javax.persistence.Converter;
 import javax.persistence.PersistenceException;
 
-import org.apache.logging.log4j.core.helpers.Strings;
+import org.apache.logging.log4j.util.Strings;
 
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextStackJsonAttributeConverter.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextStackJsonAttributeConverter.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextStackJsonAttributeConverter.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextStackJsonAttributeConverter.java Sun May 18 18:40:48 2014
@@ -24,8 +24,8 @@ import javax.persistence.Converter;
 import javax.persistence.PersistenceException;
 
 import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.core.helpers.Strings;
 import org.apache.logging.log4j.spi.DefaultThreadContextStack;
+import org.apache.logging.log4j.util.Strings;
 
 import com.fasterxml.jackson.core.type.TypeReference;
 

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/LevelAttributeConverter.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/LevelAttributeConverter.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/LevelAttributeConverter.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/LevelAttributeConverter.java Sun May 18 18:40:48 2014
@@ -16,12 +16,12 @@
  */
 package org.apache.logging.log4j.core.appender.db.jpa.converter;
 
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.core.helpers.Strings;
-
 import javax.persistence.AttributeConverter;
 import javax.persistence.Converter;
 
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.util.Strings;
+
 /**
  * A JPA 2.1 attribute converter for {@link org.apache.logging.log4j.Level}s in {@link org.apache.logging.log4j.core.LogEvent}s. This
  * converter is capable of converting both to and from {@link String}s.

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/MarkerAttributeConverter.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/MarkerAttributeConverter.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/MarkerAttributeConverter.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/MarkerAttributeConverter.java Sun May 18 18:40:48 2014
@@ -21,7 +21,7 @@ import javax.persistence.Converter;
 
 import org.apache.logging.log4j.Marker;
 import org.apache.logging.log4j.MarkerManager;
-import org.apache.logging.log4j.core.helpers.Strings;
+import org.apache.logging.log4j.util.Strings;
 
 /**
  * A JPA 2.1 attribute converter for {@link Marker}s in {@link org.apache.logging.log4j.core.LogEvent}s. This
@@ -34,24 +34,7 @@ public class MarkerAttributeConverter im
         if (marker == null) {
             return null;
         }
-
-        final StringBuilder builder = new StringBuilder(marker.getName());
-        Marker parent = marker.getParent();
-        int levels = 0;
-        boolean hasParent = false;
-        while (parent != null) {
-            levels++;
-            hasParent = true;
-            builder.append("[ ").append(parent.getName());
-            parent = parent.getParent();
-        }
-        for (int i = 0; i < levels; i++) {
-            builder.append(" ]");
-        }
-        if (hasParent) {
-            builder.append(" ]");
-        }
-        return builder.toString();
+        return marker.toString();
     }
 
     @Override

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/MessageAttributeConverter.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/MessageAttributeConverter.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/MessageAttributeConverter.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/MessageAttributeConverter.java Sun May 18 18:40:48 2014
@@ -19,9 +19,9 @@ package org.apache.logging.log4j.core.ap
 import javax.persistence.AttributeConverter;
 import javax.persistence.Converter;
 
-import org.apache.logging.log4j.core.helpers.Strings;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.Strings;
 
 /**
  * A JPA 2.1 attribute converter for {@link Message}s in {@link org.apache.logging.log4j.core.LogEvent}s. This

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/StackTraceElementAttributeConverter.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/StackTraceElementAttributeConverter.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/StackTraceElementAttributeConverter.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/StackTraceElementAttributeConverter.java Sun May 18 18:40:48 2014
@@ -19,7 +19,7 @@ package org.apache.logging.log4j.core.ap
 import javax.persistence.AttributeConverter;
 import javax.persistence.Converter;
 
-import org.apache.logging.log4j.core.helpers.Strings;
+import org.apache.logging.log4j.util.Strings;
 
 /**
  * A JPA 2.1 attribute converter for {@link StackTraceElement}s in {@link org.apache.logging.log4j.core.LogEvent}s. This

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ThrowableAttributeConverter.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ThrowableAttributeConverter.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ThrowableAttributeConverter.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ThrowableAttributeConverter.java Sun May 18 18:40:48 2014
@@ -26,8 +26,8 @@ import java.util.ListIterator;
 import javax.persistence.AttributeConverter;
 import javax.persistence.Converter;
 
-import org.apache.logging.log4j.core.helpers.Loader;
-import org.apache.logging.log4j.core.helpers.Strings;
+import org.apache.logging.log4j.core.util.Loader;
+import org.apache.logging.log4j.util.Strings;
 
 /**
  * A JPA 2.1 attribute converter for {@link Throwable}s in {@link org.apache.logging.log4j.core.LogEvent}s. This

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/jms/JMSQueueAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/jms/JMSQueueAppender.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/jms/JMSQueueAppender.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/jms/JMSQueueAppender.java Sun May 18 18:40:48 2014
@@ -27,9 +27,9 @@ import org.apache.logging.log4j.core.con
 import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginElement;
 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
-import org.apache.logging.log4j.core.helpers.Booleans;
 import org.apache.logging.log4j.core.layout.SerializedLayout;
 import org.apache.logging.log4j.core.net.jms.JMSQueueManager;
+import org.apache.logging.log4j.core.util.Booleans;
 
 /**
  * Appender to write to a JMS Queue.

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/jms/JMSTopicAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/jms/JMSTopicAppender.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/jms/JMSTopicAppender.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/jms/JMSTopicAppender.java Sun May 18 18:40:48 2014
@@ -27,9 +27,9 @@ import org.apache.logging.log4j.core.con
 import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginElement;
 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
-import org.apache.logging.log4j.core.helpers.Booleans;
 import org.apache.logging.log4j.core.layout.SerializedLayout;
 import org.apache.logging.log4j.core.net.jms.JMSTopicManager;
+import org.apache.logging.log4j.core.util.Booleans;
 
 /**
  * Appender to write to a JMS Topic.

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rewrite/MapRewritePolicy.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rewrite/MapRewritePolicy.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rewrite/MapRewritePolicy.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rewrite/MapRewritePolicy.java Sun May 18 18:40:48 2014
@@ -25,8 +25,8 @@ import org.apache.logging.log4j.core.con
 import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginElement;
 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
-import org.apache.logging.log4j.core.helpers.KeyValuePair;
 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
+import org.apache.logging.log4j.core.util.KeyValuePair;
 import org.apache.logging.log4j.message.MapMessage;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.status.StatusLogger;
@@ -80,13 +80,13 @@ public final class MapRewritePolicy impl
         final MapMessage message = ((MapMessage) msg).newInstance(newMap);
         if (source instanceof Log4jLogEvent) {
             Log4jLogEvent event = (Log4jLogEvent) source;
-            return Log4jLogEvent.createEvent(event.getLoggerName(), event.getMarker(), event.getFQCN(),
+            return Log4jLogEvent.createEvent(event.getLoggerName(), event.getMarker(), event.getLoggerFQCN(),
                 event.getLevel(), message, event.getThrownProxy(), event.getContextMap(), event.getContextStack(),
-                event.getThreadName(), event.getSource(), event.getMillis());
+                event.getThreadName(), event.getSource(), event.getTimeMillis());
         }
-        return new Log4jLogEvent(source.getLoggerName(), source.getMarker(), source.getFQCN(), source.getLevel(),
+        return new Log4jLogEvent(source.getLoggerName(), source.getMarker(), source.getLoggerFQCN(), source.getLevel(),
             message, source.getThrown(), source.getContextMap(), source.getContextStack(), source.getThreadName(),
-            source.getSource(), source.getMillis());
+            source.getSource(), source.getTimeMillis());
     }
 
     /**

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rewrite/PropertiesRewritePolicy.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rewrite/PropertiesRewritePolicy.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rewrite/PropertiesRewritePolicy.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rewrite/PropertiesRewritePolicy.java Sun May 18 18:40:48 2014
@@ -70,9 +70,9 @@ public final class PropertiesRewritePoli
                 config.getStrSubstitutor().replace(prop.getValue()) : prop.getValue());
         }
 
-        return new Log4jLogEvent(source.getLoggerName(), source.getMarker(), source.getFQCN(), source.getLevel(),
+        return new Log4jLogEvent(source.getLoggerName(), source.getMarker(), source.getLoggerFQCN(), source.getLevel(),
             source.getMessage(), source.getThrown(), props, source.getContextStack(), source.getThreadName(),
-            source.getSource(), source.getMillis());
+            source.getSource(), source.getTimeMillis());
     }
 
     @Override

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rewrite/RewriteAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rewrite/RewriteAppender.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rewrite/RewriteAppender.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rewrite/RewriteAppender.java Sun May 18 18:40:48 2014
@@ -32,7 +32,7 @@ import org.apache.logging.log4j.core.con
 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.helpers.Booleans;
+import org.apache.logging.log4j.core.util.Booleans;
 
 /**
  * This Appender allows the logging event to be manipulated before it is processed by other Appenders.

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java Sun May 18 18:40:48 2014
@@ -31,8 +31,8 @@ import org.apache.logging.log4j.core.con
 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.PluginFactory;
-import org.apache.logging.log4j.core.helpers.Integers;
 import org.apache.logging.log4j.core.lookup.StrSubstitutor;
+import org.apache.logging.log4j.core.util.Integers;
 import org.apache.logging.log4j.status.StatusLogger;
 
 /**

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/OnStartupTriggeringPolicy.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/OnStartupTriggeringPolicy.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/OnStartupTriggeringPolicy.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/OnStartupTriggeringPolicy.java Sun May 18 18:40:48 2014
@@ -21,7 +21,7 @@ import java.lang.reflect.Method;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
-import org.apache.logging.log4j.core.helpers.Loader;
+import org.apache.logging.log4j.core.util.Loader;
 import org.apache.logging.log4j.status.StatusLogger;
 
 /**

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java Sun May 18 18:40:48 2014
@@ -197,6 +197,8 @@ public class PatternProcessor {
      * @param obj object to be evaluated in formatting, may not be null.
      */
     public final void formatFileName(final StrSubstitutor subst, final StringBuilder buf, final Object obj) {
+        // LOG4J2-628: we deliberately use System time, not the log4j.Clock time
+        // for creating the file name of rolled-over files. 
         final long time = prevFileTime == 0 ? System.currentTimeMillis() : prevFileTime;
         formatFileName(buf, new Date(time), obj);
         LogEvent event = new Log4jLogEvent(time);

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java Sun May 18 18:40:48 2014
@@ -33,7 +33,10 @@ import org.apache.logging.log4j.core.app
  * I/O.
  */
 public class RollingRandomAccessFileManager extends RollingFileManager {
-    static final int DEFAULT_BUFFER_SIZE = 256 * 1024;
+    /**
+     * The default buffer size
+     */
+    public static final int DEFAULT_BUFFER_SIZE = 256 * 1024;
 
     private static final RollingRandomAccessFileManagerFactory FACTORY = new RollingRandomAccessFileManagerFactory();
 
@@ -44,23 +47,22 @@ public class RollingRandomAccessFileMana
 
     public RollingRandomAccessFileManager(final RandomAccessFile raf, final String fileName,
             final String pattern, final OutputStream os, final boolean append,
-            final boolean immediateFlush, final long size, final long time,
+            final boolean immediateFlush, final int bufferSize, final long size, final long time,
             final TriggeringPolicy policy, final RolloverStrategy strategy,
             final String advertiseURI, final Layout<? extends Serializable> layout) {
         super(fileName, pattern, os, append, size, time, policy, strategy, advertiseURI, layout);
         this.isImmediateFlush = immediateFlush;
         this.randomAccessFile = raf;
         isEndOfBatch.set(Boolean.FALSE);
-
-        // TODO make buffer size configurable?
-        buffer = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE);
+        this.buffer = ByteBuffer.allocate(bufferSize);
     }
 
-    public static RollingRandomAccessFileManager getRollingRandomAccessFileManager(final String fileName, final String filePattern,
-            final boolean isAppend, final boolean immediateFlush, final TriggeringPolicy policy,
-            final RolloverStrategy strategy, final String advertiseURI, final Layout<? extends Serializable> layout) {
-        return (RollingRandomAccessFileManager) getManager(fileName, new FactoryData(filePattern, isAppend, immediateFlush,
-            policy, strategy, advertiseURI, layout), FACTORY);
+    public static RollingRandomAccessFileManager getRollingRandomAccessFileManager(final String fileName,
+            final String filePattern, final boolean isAppend, final boolean immediateFlush, final int bufferSize, 
+            final TriggeringPolicy policy, final RolloverStrategy strategy, final String advertiseURI, 
+            final Layout<? extends Serializable> layout) {
+        return (RollingRandomAccessFileManager) getManager(fileName, new FactoryData(filePattern, isAppend, 
+                immediateFlush, bufferSize, policy, strategy, advertiseURI, layout), FACTORY);
     }
 
     public Boolean isEndOfBatch() {
@@ -121,6 +123,14 @@ public class RollingRandomAccessFileMana
                     + ex);
         }
     }
+    
+    /**
+     * Returns the buffer capacity.
+     * @return the buffer size
+     */
+    public int getBufferSize() {
+        return buffer.capacity();
+    }
 
     /**
      * Factory to create a RollingRandomAccessFileManager.
@@ -160,7 +170,8 @@ public class RollingRandomAccessFileMana
                     raf.setLength(0);
                 }
                 return new RollingRandomAccessFileManager(raf, name, data.pattern, new DummyOutputStream(), data.append,
-                        data.immediateFlush, size, time, data.policy, data.strategy, data.advertiseURI, data.layout);
+                        data.immediateFlush, data.bufferSize, size, time, data.policy, data.strategy, data.advertiseURI,
+                        data.layout);
             } catch (final IOException ex) {
                 LOGGER.error("Cannot access RandomAccessFile {}) " + ex);
                 if (raf != null) {
@@ -193,6 +204,7 @@ public class RollingRandomAccessFileMana
         private final String pattern;
         private final boolean append;
         private final boolean immediateFlush;
+        private final int bufferSize;
         private final TriggeringPolicy policy;
         private final RolloverStrategy strategy;
         private final String advertiseURI;
@@ -204,13 +216,19 @@ public class RollingRandomAccessFileMana
          * @param pattern The pattern.
          * @param append The append flag.
          * @param immediateFlush
+         * @param bufferSize
+         * @param policy
+         * @param strategy
+         * @param advertiseURI
+         * @param layout
          */
         public FactoryData(final String pattern, final boolean append, final boolean immediateFlush,
-                           final TriggeringPolicy policy, final RolloverStrategy strategy, final String advertiseURI,
-                           final Layout<? extends Serializable> layout) {
+                final int bufferSize, final TriggeringPolicy policy, final RolloverStrategy strategy,
+                final String advertiseURI, final Layout<? extends Serializable> layout) {
             this.pattern = pattern;
             this.append = append;
             this.immediateFlush = immediateFlush;
+            this.bufferSize = bufferSize;
             this.policy = policy;
             this.strategy = strategy;
             this.advertiseURI = advertiseURI;

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/SizeBasedTriggeringPolicy.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/SizeBasedTriggeringPolicy.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/SizeBasedTriggeringPolicy.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/SizeBasedTriggeringPolicy.java Sun May 18 18:40:48 2014
@@ -133,7 +133,7 @@ public class SizeBasedTriggeringPolicy i
                 // Get units specified
                 final String units = matcher.group(3);
 
-                if (units.equalsIgnoreCase("")) {
+                if (units.isEmpty()) {
                     return value;
                 } else if (units.equalsIgnoreCase("K")) {
                     return value * KB;

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/TimeBasedTriggeringPolicy.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/TimeBasedTriggeringPolicy.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/TimeBasedTriggeringPolicy.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/TimeBasedTriggeringPolicy.java Sun May 18 18:40:48 2014
@@ -20,7 +20,7 @@ import org.apache.logging.log4j.core.Log
 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.PluginFactory;
-import org.apache.logging.log4j.core.helpers.Integers;
+import org.apache.logging.log4j.core.util.Integers;
 
 /**
  * Triggering Policy that causes a rollover based on time.
@@ -63,7 +63,7 @@ public final class TimeBasedTriggeringPo
         if (manager.getFileSize() == 0) {
             return false;
         }
-        final long now = event.getMillis();
+        final long now = event.getTimeMillis();
         if (now > nextRollover) {
             nextRollover = manager.getPatternProcessor().getNextTime(now, interval, modulate);
             return true;

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/routing/RoutingAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/routing/RoutingAppender.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/routing/RoutingAppender.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/routing/RoutingAppender.java Sun May 18 18:40:48 2014
@@ -33,7 +33,7 @@ import org.apache.logging.log4j.core.con
 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.helpers.Booleans;
+import org.apache.logging.log4j.core.util.Booleans;
 
 /**
  * This Appender "routes" between various Appenders, some of which can be references to

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java Sun May 18 18:40:48 2014
@@ -16,33 +16,35 @@
  */
 package org.apache.logging.log4j.core.async;
 
-import com.lmax.disruptor.BlockingWaitStrategy;
-import com.lmax.disruptor.ExceptionHandler;
-import com.lmax.disruptor.RingBuffer;
-import com.lmax.disruptor.SleepingWaitStrategy;
-import com.lmax.disruptor.WaitStrategy;
-import com.lmax.disruptor.YieldingWaitStrategy;
-import com.lmax.disruptor.dsl.Disruptor;
-import com.lmax.disruptor.dsl.ProducerType;
-import com.lmax.disruptor.util.Util;
 import java.util.Map;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.Marker;
 import org.apache.logging.log4j.ThreadContext;
 import org.apache.logging.log4j.core.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.config.Property;
-import org.apache.logging.log4j.core.helpers.Clock;
-import org.apache.logging.log4j.core.helpers.ClockFactory;
-import org.apache.logging.log4j.core.helpers.Loader;
 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
 import org.apache.logging.log4j.core.jmx.RingBufferAdmin;
+import org.apache.logging.log4j.core.util.Clock;
+import org.apache.logging.log4j.core.util.ClockFactory;
+import org.apache.logging.log4j.core.util.Loader;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.MessageFactory;
 import org.apache.logging.log4j.status.StatusLogger;
 
+import com.lmax.disruptor.BlockingWaitStrategy;
+import com.lmax.disruptor.ExceptionHandler;
+import com.lmax.disruptor.RingBuffer;
+import com.lmax.disruptor.SleepingWaitStrategy;
+import com.lmax.disruptor.WaitStrategy;
+import com.lmax.disruptor.YieldingWaitStrategy;
+import com.lmax.disruptor.dsl.Disruptor;
+import com.lmax.disruptor.dsl.ProducerType;
+import com.lmax.disruptor.util.Util;
+
 /**
  * AsyncLogger is a logger designed for high throughput and low latency logging.
  * It does not perform any I/O in the calling (application) thread, but instead
@@ -222,22 +224,30 @@ public class AsyncLogger extends Logger 
     }
 
     @Override
-    public void logMessage(final String fqcn, final Level level, final Marker marker, final Message message, final Throwable t) {
+    public void logMessage(final String fqcn, final Level level, final Marker marker, final Message message, final Throwable thrown) {
         Info info = threadlocalInfo.get();
         if (info == null) {
             info = new Info(new RingBufferLogEventTranslator(), Thread.currentThread().getName(), false);
             threadlocalInfo.set(info);
         }
+        
+        Disruptor<RingBufferLogEvent> temp = disruptor;
+        if (temp == null) { // LOG4J2-639
+            LOGGER.fatal("Ignoring log event after log4j was shut down");
+            return;
+        }
 
         // LOG4J2-471: prevent deadlock when RingBuffer is full and object
         // being logged calls Logger.log() from its toString() method
-        if (info.isAppenderThread && disruptor.getRingBuffer().remainingCapacity() == 0) {
+        if (info.isAppenderThread && temp.getRingBuffer().remainingCapacity() == 0) {
             // bypass RingBuffer and invoke Appender directly
-            config.loggerConfig.log(getName(), fqcn, marker, level, message, t);
+            config.loggerConfig.log(getName(), fqcn, marker, level, message, thrown);
             return;
         }
         final boolean includeLocation = config.loggerConfig.isIncludeLocation();
-        info.translator.setValues(this, getName(), marker, fqcn, level, message, t, //
+        info.translator.setValues(this, getName(), marker, fqcn, level, message, //
+                // don't construct ThrowableProxy until required
+                thrown, //
 
                 // config properties are taken care of in the EventHandler
                 // thread in the #actualAsyncLog method
@@ -262,7 +272,15 @@ public class AsyncLogger extends Logger 
                 // CachedClock: 10% faster than system clock, smaller gaps
                 clock.currentTimeMillis());
 
-        disruptor.publishEvent(info.translator);
+        // LOG4J2-639: catch NPE if disruptor field was set to null after our check above
+        try {
+            // Note: do NOT use the temp variable above!
+            // That could result in adding a log event to the disruptor after it was shut down,
+            // which could cause the publishEvent method to hang and never return.
+            disruptor.publishEvent(info.translator);
+        } catch (NullPointerException npe) {
+            LOGGER.fatal("Ignoring log event after log4j was shut down.");
+        }
     }
 
     private static StackTraceElement location(final String fqcnOfLogger) {
@@ -290,28 +308,30 @@ public class AsyncLogger extends Logger 
         if (temp == null) {
             return; // stop() has already been called
         }
-        temp.shutdown();
 
-        // Wait up to 10 seconds for the ringbuffer to drain,
-        // in case we received a burst of events right before the application was stopped.
-        final RingBuffer<RingBufferLogEvent> ringBuffer = temp.getRingBuffer();
-        for (int i = 0; i < MAX_DRAIN_ATTEMPTS_BEFORE_SHUTDOWN; i++) {
-            if (ringBuffer.hasAvailableCapacity(ringBuffer.getBufferSize())) {
-                break; // no more events queued, we can safely kill the processor thread
-            }
+        // Calling Disruptor.shutdown() will wait until all enqueued events are fully processed,
+        // but this waiting happens in a busy-spin. To avoid (postpone) wasting CPU,
+        // we sleep in short chunks, up to 10 seconds, waiting for the ringbuffer to drain.
+        for (int i = 0; hasBacklog(temp) && i < MAX_DRAIN_ATTEMPTS_BEFORE_SHUTDOWN; i++) {
             try {
-                // give ringbuffer some time to drain...
-                // noinspection BusyWait
-                Thread.sleep(SLEEP_MILLIS_BETWEEN_DRAIN_ATTEMPTS);
-            } catch (final InterruptedException e) {
-                // ignored
+                Thread.sleep(SLEEP_MILLIS_BETWEEN_DRAIN_ATTEMPTS); // give up the CPU for a while
+            } catch (final InterruptedException e) { // ignored
             }
         }
+        temp.shutdown(); // busy-spins until all events currently in the disruptor have been processed
         executor.shutdown(); // finally, kill the processor thread
         threadlocalInfo.remove(); // LOG4J2-323
     }
 
     /**
+     * Returns {@code true} if the specified disruptor still has unprocessed events.
+     */
+    private static boolean hasBacklog(Disruptor<?> disruptor) {
+        final RingBuffer<?> ringBuffer = disruptor.getRingBuffer();
+        return !ringBuffer.hasAvailableCapacity(ringBuffer.getBufferSize());
+    }
+
+    /**
      * Creates and returns a new {@code RingBufferAdmin} that instruments the
      * ringbuffer of the {@code AsyncLogger}.
      *

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfig.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfig.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfig.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfig.java Sun May 18 18:40:48 2014
@@ -32,8 +32,9 @@ import org.apache.logging.log4j.core.con
 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.helpers.Booleans;
 import org.apache.logging.log4j.core.jmx.RingBufferAdmin;
+import org.apache.logging.log4j.core.util.Booleans;
+import org.apache.logging.log4j.util.Strings;
 
 /**
  * Asynchronous Logger object that is created via configuration and can be
@@ -181,7 +182,7 @@ public class AsyncLoggerConfig extends L
                     levelName);
             level = Level.ERROR;
         }
-        final String name = loggerName.equals("root") ? "" : loggerName;
+        final String name = loggerName.equals("root") ? Strings.EMPTY : loggerName;
         final boolean additive = Booleans.parseBoolean(additivity, true);
 
         return new AsyncLoggerConfig(name, appenderRefs, filter, level,

Modified: logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigHelper.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigHelper.java?rev=1595653&r1=1595652&r2=1595653&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigHelper.java (original)
+++ logging/log4j/log4j2/branches/experimental/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigHelper.java Sun May 18 18:40:48 2014
@@ -58,14 +58,13 @@ import com.lmax.disruptor.util.Util;
  */
 class AsyncLoggerConfigHelper {
 
-    private static final int MAX_DRAIN_ATTEMPTS_BEFORE_SHUTDOWN = 20;
-    private static final int HALF_A_SECOND = 500;
+    private static final int MAX_DRAIN_ATTEMPTS_BEFORE_SHUTDOWN = 200;
+    private static final int SLEEP_MILLIS_BETWEEN_DRAIN_ATTEMPTS = 50;
     private static final int RINGBUFFER_MIN_SIZE = 128;
     private static final int RINGBUFFER_DEFAULT_SIZE = 256 * 1024;
     private static final Logger LOGGER = StatusLogger.getLogger();
 
-    private static ThreadFactory threadFactory = new DaemonThreadFactory(
-            "AsyncLoggerConfig-");
+    private static ThreadFactory threadFactory = new DaemonThreadFactory("AsyncLoggerConfig-");
     private static volatile Disruptor<Log4jEventWrapper> disruptor;
     private static ExecutorService executor;
 
@@ -256,7 +255,9 @@ class AsyncLoggerConfigHelper {
         }
         final Disruptor<Log4jEventWrapper> temp = disruptor;
         if (temp == null) {
-            LOGGER.trace("AsyncLoggerConfigHelper: disruptor already shut down: ref count is {}.", count);
+            LOGGER.trace("AsyncLoggerConfigHelper: disruptor already shut down: ref count is {}. (Resetting to zero.)",
+                    count);
+            count = 0; // ref count must not be negative or #claim() will not work correctly
             return; // disruptor was already shut down by another thread
         }
         LOGGER.trace("AsyncLoggerConfigHelper: shutting down disruptor: ref count is {}.", count);
@@ -264,32 +265,36 @@ class AsyncLoggerConfigHelper {
         // Must guarantee that publishing to the RingBuffer has stopped
         // before we call disruptor.shutdown()
         disruptor = null; // client code fails with NPE if log after stop = OK
-        temp.shutdown();
 
-        // wait up to 10 seconds for the ringbuffer to drain
-        final RingBuffer<Log4jEventWrapper> ringBuffer = temp.getRingBuffer();
-        for (int i = 0; i < MAX_DRAIN_ATTEMPTS_BEFORE_SHUTDOWN; i++) {
-            if (ringBuffer.hasAvailableCapacity(ringBuffer.getBufferSize())) {
-                break;
-            }
+        // Calling Disruptor.shutdown() will wait until all enqueued events are fully processed,
+        // but this waiting happens in a busy-spin. To avoid (postpone) wasting CPU,
+        // we sleep in short chunks, up to 10 seconds, waiting for the ringbuffer to drain.
+        for (int i = 0; hasBacklog(temp) && i < MAX_DRAIN_ATTEMPTS_BEFORE_SHUTDOWN; i++) {
             try {
-                // give ringbuffer some time to drain...
-                Thread.sleep(HALF_A_SECOND);
-            } catch (final InterruptedException e) {
-                // ignored
+                Thread.sleep(SLEEP_MILLIS_BETWEEN_DRAIN_ATTEMPTS); // give up the CPU for a while
+            } catch (final InterruptedException e) { // ignored
             }
         }
+        temp.shutdown(); // busy-spins until all events currently in the disruptor have been processed
         executor.shutdown(); // finally, kill the processor thread
         executor = null; // release reference to allow GC
     }
 
     /**
+     * Returns {@code true} if the specified disruptor still has unprocessed events.
+     */
+    private static boolean hasBacklog(Disruptor<?> disruptor) {
+        final RingBuffer<?> ringBuffer = disruptor.getRingBuffer();
+        return !ringBuffer.hasAvailableCapacity(ringBuffer.getBufferSize());
+    }
+
+    /**
      * Initialize the threadlocal that allows us to detect Logger.log() calls 
      * initiated from the appender thread, which may cause deadlock when the 
      * RingBuffer is full. (LOG4J2-471)
      */
     private static void initThreadLocalForExecutorThread() {
-        executor.submit(new Runnable(){
+        executor.submit(new Runnable() {
             @Override
             public void run() {
                 isAppenderThread.set(Boolean.TRUE);
@@ -311,16 +316,29 @@ class AsyncLoggerConfigHelper {
      *          calling thread needs to process the event itself
      */
     public boolean callAppendersFromAnotherThread(final LogEvent event) {
-        
+        Disruptor<Log4jEventWrapper> temp = disruptor;
+        if (temp == null) { // LOG4J2-639
+            LOGGER.fatal("Ignoring log event after log4j was shut down");
+            return true;
+        }
+
         // LOG4J2-471: prevent deadlock when RingBuffer is full and object
         // being logged calls Logger.log() from its toString() method
         if (isAppenderThread.get() == Boolean.TRUE //
-                && disruptor.getRingBuffer().remainingCapacity() == 0) {
-            
+                && temp.getRingBuffer().remainingCapacity() == 0) {
+
             // bypass RingBuffer and invoke Appender directly
             return false;
         }
-        disruptor.getRingBuffer().publishEvent(translator, event, asyncLoggerConfig);
+        // LOG4J2-639: catch NPE if disruptor field was set to null after our check above
+        try {
+            // Note: do NOT use the temp variable above!
+            // That could result in adding a log event to the disruptor after it was shut down,
+            // which could cause the publishEvent method to hang and never return.
+            disruptor.getRingBuffer().publishEvent(translator, event, asyncLoggerConfig);
+        } catch (NullPointerException npe) {
+            LOGGER.fatal("Ignoring log event after log4j was shut down.");
+        }
         return true;
     }